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_packet_creator.h" | 5 #include "net/quic/quic_packet_creator.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "net/quic/crypto/quic_random.h" | 8 #include "net/quic/crypto/quic_random.h" |
9 #include "net/quic/quic_ack_notifier.h" | 9 #include "net/quic/quic_ack_notifier.h" |
10 #include "net/quic/quic_fec_group.h" | 10 #include "net/quic/quic_fec_group.h" |
11 #include "net/quic/quic_utils.h" | 11 #include "net/quic/quic_utils.h" |
12 | 12 |
13 using base::StringPiece; | 13 using base::StringPiece; |
14 using std::make_pair; | 14 using std::make_pair; |
15 using std::max; | 15 using std::max; |
16 using std::min; | 16 using std::min; |
17 using std::pair; | 17 using std::pair; |
18 using std::vector; | 18 using std::vector; |
19 | 19 |
20 // If true, then QUIC handshake packets will be padded to the maximium packet | 20 // If true, then QUIC handshake packets will be padded to the maximium packet |
21 // size. | 21 // size. |
22 bool FLAGS_pad_quic_handshake_packets = true; | 22 bool FLAGS_pad_quic_handshake_packets = true; |
23 | 23 |
24 namespace net { | 24 namespace net { |
25 | 25 |
| 26 // A QuicRandom wrapper that gets a bucket of entropy and distributes it |
| 27 // bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this |
| 28 // class if single bit randomness is needed elsewhere. |
| 29 class QuicRandomBoolSource { |
| 30 public: |
| 31 // random: Source of entropy. Not owned. |
| 32 explicit QuicRandomBoolSource(QuicRandom* random) |
| 33 : random_(random), |
| 34 bit_bucket_(0), |
| 35 bit_mask_(0) {} |
| 36 |
| 37 ~QuicRandomBoolSource() {} |
| 38 |
| 39 // Returns the next random bit from the bucket. |
| 40 bool RandBool() { |
| 41 if (bit_mask_ == 0) { |
| 42 bit_bucket_ = random_->RandUint64(); |
| 43 bit_mask_ = 1; |
| 44 } |
| 45 bool result = ((bit_bucket_ & bit_mask_) != 0); |
| 46 bit_mask_ <<= 1; |
| 47 return result; |
| 48 } |
| 49 |
| 50 private: |
| 51 // Source of entropy. |
| 52 QuicRandom* random_; |
| 53 // Stored random bits. |
| 54 uint64 bit_bucket_; |
| 55 // The next available bit has "1" in the mask. Zero means empty bucket. |
| 56 uint64 bit_mask_; |
| 57 |
| 58 DISALLOW_COPY_AND_ASSIGN(QuicRandomBoolSource); |
| 59 }; |
| 60 |
26 QuicPacketCreator::QuicPacketCreator(QuicGuid guid, | 61 QuicPacketCreator::QuicPacketCreator(QuicGuid guid, |
27 QuicFramer* framer, | 62 QuicFramer* framer, |
28 QuicRandom* random_generator, | 63 QuicRandom* random_generator, |
29 bool is_server) | 64 bool is_server) |
30 : guid_(guid), | 65 : guid_(guid), |
31 framer_(framer), | 66 framer_(framer), |
32 random_generator_(random_generator), | 67 random_bool_source_(new QuicRandomBoolSource(random_generator)), |
33 sequence_number_(0), | 68 sequence_number_(0), |
34 fec_group_number_(0), | 69 fec_group_number_(0), |
35 is_server_(is_server), | 70 is_server_(is_server), |
36 send_version_in_packet_(!is_server), | 71 send_version_in_packet_(!is_server), |
37 sequence_number_length_(options_.send_sequence_number_length), | 72 sequence_number_length_(options_.send_sequence_number_length), |
38 packet_size_(0) { | 73 packet_size_(0) { |
39 framer_->set_fec_builder(this); | 74 framer_->set_fec_builder(this); |
40 } | 75 } |
41 | 76 |
42 QuicPacketCreator::~QuicPacketCreator() { | 77 QuicPacketCreator::~QuicPacketCreator() { |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 bool fec_entropy_flag, | 400 bool fec_entropy_flag, |
366 QuicPacketHeader* header) { | 401 QuicPacketHeader* header) { |
367 header->public_header.guid = guid_; | 402 header->public_header.guid = guid_; |
368 header->public_header.reset_flag = false; | 403 header->public_header.reset_flag = false; |
369 header->public_header.version_flag = send_version_in_packet_; | 404 header->public_header.version_flag = send_version_in_packet_; |
370 header->fec_flag = fec_flag; | 405 header->fec_flag = fec_flag; |
371 header->packet_sequence_number = ++sequence_number_; | 406 header->packet_sequence_number = ++sequence_number_; |
372 header->public_header.sequence_number_length = sequence_number_length_; | 407 header->public_header.sequence_number_length = sequence_number_length_; |
373 | 408 |
374 bool entropy_flag; | 409 bool entropy_flag; |
375 if (header->packet_sequence_number == 1) { | 410 if (fec_flag) { |
376 DCHECK(!fec_flag); | |
377 // TODO(satyamshekhar): No entropy in the first message. | |
378 // For crypto tests to pass. Fix this by using deterministic QuicRandom. | |
379 entropy_flag = 0; | |
380 } else if (fec_flag) { | |
381 // FEC packets don't have an entropy of their own. Entropy flag for FEC | 411 // FEC packets don't have an entropy of their own. Entropy flag for FEC |
382 // packets is the XOR of entropy of previous packets. | 412 // packets is the XOR of entropy of previous packets. |
383 entropy_flag = fec_entropy_flag; | 413 entropy_flag = fec_entropy_flag; |
384 } else { | 414 } else { |
385 entropy_flag = random_generator_->RandBool(); | 415 entropy_flag = random_bool_source_->RandBool(); |
386 } | 416 } |
387 header->entropy_flag = entropy_flag; | 417 header->entropy_flag = entropy_flag; |
388 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; | 418 header->is_in_fec_group = fec_group == 0 ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; |
389 header->fec_group = fec_group; | 419 header->fec_group = fec_group; |
390 } | 420 } |
391 | 421 |
392 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { | 422 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { |
393 return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME && | 423 return frame.type != ACK_FRAME && frame.type != CONGESTION_FEEDBACK_FRAME && |
394 frame.type != PADDING_FRAME; | 424 frame.type != PADDING_FRAME; |
395 } | 425 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 if (!is_handshake) { | 476 if (!is_handshake) { |
447 return; | 477 return; |
448 } | 478 } |
449 | 479 |
450 QuicPaddingFrame padding; | 480 QuicPaddingFrame padding; |
451 bool success = AddFrame(QuicFrame(&padding), false); | 481 bool success = AddFrame(QuicFrame(&padding), false); |
452 DCHECK(success); | 482 DCHECK(success); |
453 } | 483 } |
454 | 484 |
455 } // namespace net | 485 } // namespace net |
OLD | NEW |