| 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 |