OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/quic/quic_connection.h" | 5 #include "net/quic/quic_connection.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "net/quic/congestion_control/receive_algorithm_interface.h" | 10 #include "net/quic/congestion_control/receive_algorithm_interface.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 } | 147 } |
148 | 148 |
149 virtual bool Decrypt(StringPiece nonce, | 149 virtual bool Decrypt(StringPiece nonce, |
150 StringPiece associated_data, | 150 StringPiece associated_data, |
151 StringPiece ciphertext, | 151 StringPiece ciphertext, |
152 unsigned char* output, | 152 unsigned char* output, |
153 size_t* output_length) OVERRIDE { | 153 size_t* output_length) OVERRIDE { |
154 if (ciphertext.size() < kTagSize) { | 154 if (ciphertext.size() < kTagSize) { |
155 return false; | 155 return false; |
156 } | 156 } |
157 if (!CheckTag(ciphertext)) { | 157 if (!CheckTag(ciphertext, GetTag(ciphertext))) { |
158 return false; | 158 return false; |
159 } | 159 } |
160 *output_length = ciphertext.size() - kTagSize; | 160 *output_length = ciphertext.size() - kTagSize; |
161 memcpy(output, ciphertext.data(), *output_length); | 161 memcpy(output, ciphertext.data(), *output_length); |
162 return true; | 162 return true; |
163 } | 163 } |
164 | 164 |
165 virtual QuicData* DecryptPacket(QuicPacketSequenceNumber sequence_number, | 165 virtual QuicData* DecryptPacket(QuicPacketSequenceNumber sequence_number, |
166 StringPiece associated_data, | 166 StringPiece associated_data, |
167 StringPiece ciphertext) OVERRIDE { | 167 StringPiece ciphertext) OVERRIDE { |
168 if (ciphertext.size() < kTagSize) { | 168 if (ciphertext.size() < kTagSize) { |
169 return NULL; | 169 return NULL; |
170 } | 170 } |
171 if (!CheckTag(ciphertext)) { | 171 if (!CheckTag(ciphertext, GetTag(ciphertext))) { |
172 return NULL; | 172 return NULL; |
173 } | 173 } |
174 const size_t len = ciphertext.size() - kTagSize; | 174 const size_t len = ciphertext.size() - kTagSize; |
175 uint8* buf = new uint8[len]; | 175 uint8* buf = new uint8[len]; |
176 memcpy(buf, ciphertext.data(), len); | 176 memcpy(buf, ciphertext.data(), len); |
177 return new QuicData(reinterpret_cast<char*>(buf), len, | 177 return new QuicData(reinterpret_cast<char*>(buf), len, |
178 true /* owns buffer */); | 178 true /* owns buffer */); |
179 } | 179 } |
180 | 180 |
181 virtual StringPiece GetKey() const OVERRIDE { return StringPiece(); } | 181 virtual StringPiece GetKey() const OVERRIDE { return StringPiece(); } |
182 virtual StringPiece GetNoncePrefix() const OVERRIDE { return StringPiece(); } | 182 virtual StringPiece GetNoncePrefix() const OVERRIDE { return StringPiece(); } |
183 | 183 |
| 184 protected: |
| 185 virtual uint8 GetTag(StringPiece ciphertext) { |
| 186 return ciphertext.data()[ciphertext.size()-1]; |
| 187 } |
| 188 |
184 private: | 189 private: |
185 enum { | 190 enum { |
186 kTagSize = 12, | 191 kTagSize = 12, |
187 }; | 192 }; |
188 | 193 |
189 bool CheckTag(StringPiece ciphertext) { | 194 bool CheckTag(StringPiece ciphertext, uint8 tag) { |
190 uint8 tag = ciphertext.data()[ciphertext.size()-1]; | |
191 for (size_t i = ciphertext.size() - kTagSize; i < ciphertext.size(); i++) { | 195 for (size_t i = ciphertext.size() - kTagSize; i < ciphertext.size(); i++) { |
192 if (ciphertext.data()[i] != tag) { | 196 if (ciphertext.data()[i] != tag) { |
193 return false; | 197 return false; |
194 } | 198 } |
195 } | 199 } |
196 | 200 |
197 return true; | 201 return true; |
198 } | 202 } |
199 }; | 203 }; |
200 | 204 |
| 205 // StringTaggingDecrypter ensures that the final kTagSize bytes of the message |
| 206 // match the expected value. |
| 207 class StrictTaggingDecrypter : public TaggingDecrypter { |
| 208 public: |
| 209 explicit StrictTaggingDecrypter(uint8 tag) : tag_(tag) {} |
| 210 virtual ~StrictTaggingDecrypter() {} |
| 211 |
| 212 // TaggingQuicDecrypter |
| 213 virtual uint8 GetTag(StringPiece ciphertext) OVERRIDE { |
| 214 return tag_; |
| 215 } |
| 216 |
| 217 private: |
| 218 const uint8 tag_; |
| 219 }; |
| 220 |
201 class TestConnectionHelper : public QuicConnectionHelperInterface { | 221 class TestConnectionHelper : public QuicConnectionHelperInterface { |
202 public: | 222 public: |
203 TestConnectionHelper(MockClock* clock, MockRandom* random_generator) | 223 TestConnectionHelper(MockClock* clock, MockRandom* random_generator) |
204 : clock_(clock), | 224 : clock_(clock), |
205 random_generator_(random_generator), | 225 random_generator_(random_generator), |
206 retransmission_alarm_(QuicTime::Zero()), | 226 retransmission_alarm_(QuicTime::Zero()), |
207 send_alarm_(QuicTime::Zero().Subtract( | 227 send_alarm_(QuicTime::Zero().Subtract( |
208 QuicTime::Delta::FromMilliseconds(1))), | 228 QuicTime::Delta::FromMilliseconds(1))), |
209 timeout_alarm_(QuicTime::Zero()), | 229 timeout_alarm_(QuicTime::Zero()), |
210 blocked_(false), | 230 blocked_(false), |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
482 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).Times(2).WillRepeatedly( | 502 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).Times(2).WillRepeatedly( |
483 Return(accept_packet_)); | 503 Return(accept_packet_)); |
484 } else { | 504 } else { |
485 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).WillOnce( | 505 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).WillOnce( |
486 Return(accept_packet_)); | 506 Return(accept_packet_)); |
487 } | 507 } |
488 return ProcessDataPacket(number, 1, !kEntropyFlag); | 508 return ProcessDataPacket(number, 1, !kEntropyFlag); |
489 } | 509 } |
490 | 510 |
491 size_t ProcessDataPacket(QuicPacketSequenceNumber number, | 511 size_t ProcessDataPacket(QuicPacketSequenceNumber number, |
492 QuicFecGroupNumber fec_group, | 512 QuicFecGroupNumber fec_group, |
493 bool entropy_flag) { | 513 bool entropy_flag) { |
| 514 return ProcessDataPacketAtLevel(number, fec_group, entropy_flag, |
| 515 ENCRYPTION_NONE); |
| 516 } |
| 517 |
| 518 size_t ProcessDataPacketAtLevel(QuicPacketSequenceNumber number, |
| 519 QuicFecGroupNumber fec_group, |
| 520 bool entropy_flag, |
| 521 EncryptionLevel level) { |
494 scoped_ptr<QuicPacket> packet(ConstructDataPacket(number, fec_group, | 522 scoped_ptr<QuicPacket> packet(ConstructDataPacket(number, fec_group, |
495 entropy_flag)); | 523 entropy_flag)); |
496 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket( | 524 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket( |
497 ENCRYPTION_NONE, number, *packet)); | 525 level, number, *packet)); |
498 connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted); | 526 connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted); |
499 return encrypted->length(); | 527 return encrypted->length(); |
500 } | 528 } |
501 | 529 |
502 void ProcessClosePacket(QuicPacketSequenceNumber number, | 530 void ProcessClosePacket(QuicPacketSequenceNumber number, |
503 QuicFecGroupNumber fec_group) { | 531 QuicFecGroupNumber fec_group) { |
504 EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true)); | 532 EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true)); |
505 scoped_ptr<QuicPacket> packet(ConstructClosePacket(number, fec_group)); | 533 scoped_ptr<QuicPacket> packet(ConstructClosePacket(number, fec_group)); |
506 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket( | 534 scoped_ptr<QuicEncryptedPacket> encrypted(framer_.EncryptPacket( |
507 ENCRYPTION_NONE, number, *packet)); | 535 ENCRYPTION_NONE, number, *packet)); |
(...skipping 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); | 1493 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); |
1466 | 1494 |
1467 SendStreamDataToPeer(2, "bar", 0, !kFin, NULL); | 1495 SendStreamDataToPeer(2, "bar", 0, !kFin, NULL); |
1468 | 1496 |
1469 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(1); | 1497 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(1); |
1470 EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(1); | 1498 EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(1); |
1471 | 1499 |
1472 connection_.RetransmitUnackedPackets(QuicConnection::INITIAL_ENCRYPTION_ONLY); | 1500 connection_.RetransmitUnackedPackets(QuicConnection::INITIAL_ENCRYPTION_ONLY); |
1473 } | 1501 } |
1474 | 1502 |
| 1503 TEST_F(QuicConnectionTest, BufferNonDecryptablePackets) { |
| 1504 use_tagging_decrypter(); |
| 1505 |
| 1506 const uint8 tag = 0x07; |
| 1507 framer_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag)); |
| 1508 |
| 1509 // Process an encrypted packet which can not yet be decrypted |
| 1510 // which should result in the packet being buffered. |
| 1511 ProcessDataPacketAtLevel(1, false, kEntropyFlag, ENCRYPTION_INITIAL); |
| 1512 |
| 1513 // Transition to the new encryption state and process another |
| 1514 // encrypted packet which should result in the original packet being |
| 1515 // processed. |
| 1516 connection_.SetDecrypter(new StrictTaggingDecrypter(tag)); |
| 1517 connection_.SetDefaultEncryptionLevel(ENCRYPTION_INITIAL); |
| 1518 connection_.SetEncrypter(ENCRYPTION_INITIAL, new TaggingEncrypter(tag)); |
| 1519 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).Times(2).WillRepeatedly( |
| 1520 Return(true)); |
| 1521 ProcessDataPacketAtLevel(2, false, kEntropyFlag, ENCRYPTION_INITIAL); |
| 1522 |
| 1523 // Finally, process a third packet and note that we do not |
| 1524 // reprocess the buffered packet. |
| 1525 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).WillOnce(Return(true)); |
| 1526 ProcessDataPacketAtLevel(3, false, kEntropyFlag, ENCRYPTION_INITIAL); |
| 1527 } |
| 1528 |
1475 TEST_F(QuicConnectionTest, TestRetransmitOrder) { | 1529 TEST_F(QuicConnectionTest, TestRetransmitOrder) { |
1476 QuicByteCount first_packet_size; | 1530 QuicByteCount first_packet_size; |
1477 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).WillOnce( | 1531 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).WillOnce( |
1478 SaveArg<2>(&first_packet_size)); | 1532 SaveArg<2>(&first_packet_size)); |
1479 EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(2); | 1533 EXPECT_CALL(*send_algorithm_, AbandoningPacket(_, _)).Times(2); |
1480 | 1534 |
1481 connection_.SendStreamData(1, "first_packet", 0, !kFin); | 1535 connection_.SendStreamData(1, "first_packet", 0, !kFin); |
1482 QuicByteCount second_packet_size; | 1536 QuicByteCount second_packet_size; |
1483 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).WillOnce( | 1537 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).WillOnce( |
1484 SaveArg<2>(&second_packet_size)); | 1538 SaveArg<2>(&second_packet_size)); |
(...skipping 698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2183 EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true)); | 2237 EXPECT_CALL(visitor_, OnCanWrite()).Times(1).WillOnce(Return(true)); |
2184 EXPECT_CALL(visitor_, ConnectionClose(QUIC_PEER_GOING_AWAY, true)); | 2238 EXPECT_CALL(visitor_, ConnectionClose(QUIC_PEER_GOING_AWAY, true)); |
2185 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).Times(0); | 2239 EXPECT_CALL(visitor_, OnPacket(_, _, _, _)).Times(0); |
2186 | 2240 |
2187 connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted); | 2241 connection_.ProcessUdpPacket(IPEndPoint(), IPEndPoint(), *encrypted); |
2188 } | 2242 } |
2189 | 2243 |
2190 } // namespace | 2244 } // namespace |
2191 } // namespace test | 2245 } // namespace test |
2192 } // namespace net | 2246 } // namespace net |
OLD | NEW |