| 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/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "net/quic/crypto/quic_random.h" | 9 #include "net/quic/crypto/quic_random.h" |
| 10 #include "net/quic/quic_ack_notifier.h" | 10 #include "net/quic/quic_ack_notifier.h" |
| 11 #include "net/quic/quic_fec_group.h" | 11 #include "net/quic/quic_fec_group.h" |
| 12 #include "net/quic/quic_utils.h" | 12 #include "net/quic/quic_utils.h" |
| 13 | 13 |
| 14 using base::StringPiece; | 14 using base::StringPiece; |
| 15 using std::make_pair; | 15 using std::make_pair; |
| 16 using std::max; | 16 using std::max; |
| 17 using std::min; | 17 using std::min; |
| 18 using std::pair; | 18 using std::pair; |
| 19 using std::vector; | 19 using std::vector; |
| 20 | 20 |
| 21 namespace net { | 21 namespace net { |
| 22 | 22 |
| 23 // A QuicRandom wrapper that gets a bucket of entropy and distributes it | 23 // A QuicRandom wrapper that gets a bucket of entropy and distributes it |
| 24 // bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this | 24 // bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this |
| 25 // class if single bit randomness is needed elsewhere. | 25 // class if single bit randomness is needed elsewhere. |
| 26 class QuicRandomBoolSource { | 26 class QuicRandomBoolSource { |
| 27 public: | 27 public: |
| 28 // random: Source of entropy. Not owned. | 28 // random: Source of entropy. Not owned. |
| 29 explicit QuicRandomBoolSource(QuicRandom* random) | 29 explicit QuicRandomBoolSource(QuicRandom* random) |
| 30 : random_(random), | 30 : random_(random), bit_bucket_(0), bit_mask_(0) {} |
| 31 bit_bucket_(0), | |
| 32 bit_mask_(0) {} | |
| 33 | 31 |
| 34 ~QuicRandomBoolSource() {} | 32 ~QuicRandomBoolSource() {} |
| 35 | 33 |
| 36 // Returns the next random bit from the bucket. | 34 // Returns the next random bit from the bucket. |
| 37 bool RandBool() { | 35 bool RandBool() { |
| 38 if (bit_mask_ == 0) { | 36 if (bit_mask_ == 0) { |
| 39 bit_bucket_ = random_->RandUint64(); | 37 bit_bucket_ = random_->RandUint64(); |
| 40 bit_mask_ = 1; | 38 bit_mask_ = 1; |
| 41 } | 39 } |
| 42 bool result = ((bit_bucket_ & bit_mask_) != 0); | 40 bool result = ((bit_bucket_ & bit_mask_) != 0); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 68 send_version_in_packet_(!is_server), | 66 send_version_in_packet_(!is_server), |
| 69 sequence_number_length_(options_.send_sequence_number_length), | 67 sequence_number_length_(options_.send_sequence_number_length), |
| 70 packet_size_(0) { | 68 packet_size_(0) { |
| 71 framer_->set_fec_builder(this); | 69 framer_->set_fec_builder(this); |
| 72 } | 70 } |
| 73 | 71 |
| 74 QuicPacketCreator::~QuicPacketCreator() { | 72 QuicPacketCreator::~QuicPacketCreator() { |
| 75 } | 73 } |
| 76 | 74 |
| 77 void QuicPacketCreator::OnBuiltFecProtectedPayload( | 75 void QuicPacketCreator::OnBuiltFecProtectedPayload( |
| 78 const QuicPacketHeader& header, StringPiece payload) { | 76 const QuicPacketHeader& header, |
| 77 StringPiece payload) { |
| 79 if (fec_group_.get()) { | 78 if (fec_group_.get()) { |
| 80 DCHECK_NE(0u, header.fec_group); | 79 DCHECK_NE(0u, header.fec_group); |
| 81 fec_group_->Update(header, payload); | 80 fec_group_->Update(header, payload); |
| 82 } | 81 } |
| 83 } | 82 } |
| 84 | 83 |
| 85 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { | 84 bool QuicPacketCreator::ShouldSendFec(bool force_close) const { |
| 86 return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 && | 85 return fec_group_.get() != NULL && fec_group_->NumReceivedPackets() > 0 && |
| 87 (force_close || | 86 (force_close || |
| 88 fec_group_->NumReceivedPackets() >= options_.max_packets_per_fec_group); | 87 fec_group_->NumReceivedPackets() >= |
| 88 options_.max_packets_per_fec_group); |
| 89 } | 89 } |
| 90 | 90 |
| 91 InFecGroup QuicPacketCreator::MaybeStartFEC() { | 91 InFecGroup QuicPacketCreator::MaybeStartFEC() { |
| 92 if (IsFecEnabled() && fec_group_.get() == NULL) { | 92 if (IsFecEnabled() && fec_group_.get() == NULL) { |
| 93 DCHECK(queued_frames_.empty()); | 93 DCHECK(queued_frames_.empty()); |
| 94 // Set the fec group number to the sequence number of the next packet. | 94 // Set the fec group number to the sequence number of the next packet. |
| 95 fec_group_number_ = sequence_number() + 1; | 95 fec_group_number_ = sequence_number() + 1; |
| 96 fec_group_.reset(new QuicFecGroup()); | 96 fec_group_.reset(new QuicFecGroup()); |
| 97 } | 97 } |
| 98 return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; | 98 return fec_group_.get() == NULL ? NOT_IN_FEC_GROUP : IN_FEC_GROUP; |
| 99 } | 99 } |
| 100 | 100 |
| 101 // Stops serializing version of the protocol in packets sent after this call. | 101 // Stops serializing version of the protocol in packets sent after this call. |
| 102 // A packet that is already open might send kQuicVersionSize bytes less than the | 102 // A packet that is already open might send kQuicVersionSize bytes less than the |
| 103 // maximum packet size if we stop sending version before it is serialized. | 103 // maximum packet size if we stop sending version before it is serialized. |
| 104 void QuicPacketCreator::StopSendingVersion() { | 104 void QuicPacketCreator::StopSendingVersion() { |
| 105 DCHECK(send_version_in_packet_); | 105 DCHECK(send_version_in_packet_); |
| 106 send_version_in_packet_ = false; | 106 send_version_in_packet_ = false; |
| 107 if (packet_size_ > 0) { | 107 if (packet_size_ > 0) { |
| 108 DCHECK_LT(kQuicVersionSize, packet_size_); | 108 DCHECK_LT(kQuicVersionSize, packet_size_); |
| 109 packet_size_ -= kQuicVersionSize; | 109 packet_size_ -= kQuicVersionSize; |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 | 112 |
| 113 void QuicPacketCreator::UpdateSequenceNumberLength( | 113 void QuicPacketCreator::UpdateSequenceNumberLength( |
| 114 QuicPacketSequenceNumber least_packet_awaited_by_peer, | 114 QuicPacketSequenceNumber least_packet_awaited_by_peer, |
| 115 QuicByteCount congestion_window) { | 115 QuicByteCount congestion_window) { |
| 116 DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1); | 116 DCHECK_LE(least_packet_awaited_by_peer, sequence_number_ + 1); |
| 117 // Since the packet creator will not change sequence number length mid FEC | 117 // Since the packet creator will not change sequence number length mid FEC |
| 118 // group, include the size of an FEC group to be safe. | 118 // group, include the size of an FEC group to be safe. |
| 119 const QuicPacketSequenceNumber current_delta = | 119 const QuicPacketSequenceNumber current_delta = |
| 120 options_.max_packets_per_fec_group + sequence_number_ + 1 | 120 options_.max_packets_per_fec_group + sequence_number_ + 1 - |
| 121 - least_packet_awaited_by_peer; | 121 least_packet_awaited_by_peer; |
| 122 const uint64 congestion_window_packets = | 122 const uint64 congestion_window_packets = |
| 123 congestion_window / options_.max_packet_length; | 123 congestion_window / options_.max_packet_length; |
| 124 const uint64 delta = max(current_delta, congestion_window_packets); | 124 const uint64 delta = max(current_delta, congestion_window_packets); |
| 125 options_.send_sequence_number_length = | 125 options_.send_sequence_number_length = |
| 126 QuicFramer::GetMinSequenceNumberLength(delta * 4); | 126 QuicFramer::GetMinSequenceNumberLength(delta * 4); |
| 127 } | 127 } |
| 128 | 128 |
| 129 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, | 129 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, |
| 130 QuicStreamOffset offset) const { | 130 QuicStreamOffset offset) const { |
| 131 // TODO(jri): This is a simple safe decision for now, but make | 131 // TODO(jri): This is a simple safe decision for now, but make |
| 132 // is_in_fec_group a parameter. Same as with all public methods in | 132 // is_in_fec_group a parameter. Same as with all public methods in |
| 133 // QuicPacketCreator. | 133 // QuicPacketCreator. |
| 134 return BytesFree() > | 134 return BytesFree() > |
| 135 QuicFramer::GetMinStreamFrameSize(framer_->version(), id, offset, true, | 135 QuicFramer::GetMinStreamFrameSize( |
| 136 IsFecEnabled()); | 136 framer_->version(), id, offset, true, IsFecEnabled()); |
| 137 } | 137 } |
| 138 | 138 |
| 139 // static | 139 // static |
| 140 size_t QuicPacketCreator::StreamFramePacketOverhead( | 140 size_t QuicPacketCreator::StreamFramePacketOverhead( |
| 141 QuicVersion version, | 141 QuicVersion version, |
| 142 QuicConnectionIdLength connection_id_length, | 142 QuicConnectionIdLength connection_id_length, |
| 143 bool include_version, | 143 bool include_version, |
| 144 QuicSequenceNumberLength sequence_number_length, | 144 QuicSequenceNumberLength sequence_number_length, |
| 145 InFecGroup is_in_fec_group) { | 145 InFecGroup is_in_fec_group) { |
| 146 return GetPacketHeaderSize(connection_id_length, include_version, | 146 return GetPacketHeaderSize(connection_id_length, |
| 147 sequence_number_length, is_in_fec_group) + | 147 include_version, |
| 148 // Assumes this is a stream with a single lone packet. | 148 sequence_number_length, |
| 149 QuicFramer::GetMinStreamFrameSize(version, 1u, 0u, true, is_in_fec_group); | 149 is_in_fec_group) + |
| 150 // Assumes this is a stream with a single lone packet. |
| 151 QuicFramer::GetMinStreamFrameSize( |
| 152 version, 1u, 0u, true, is_in_fec_group); |
| 150 } | 153 } |
| 151 | 154 |
| 152 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, | 155 size_t QuicPacketCreator::CreateStreamFrame(QuicStreamId id, |
| 153 const IOVector& data, | 156 const IOVector& data, |
| 154 QuicStreamOffset offset, | 157 QuicStreamOffset offset, |
| 155 bool fin, | 158 bool fin, |
| 156 QuicFrame* frame) { | 159 QuicFrame* frame) { |
| 157 DCHECK_GT(options_.max_packet_length, | 160 DCHECK_GT(options_.max_packet_length, |
| 158 StreamFramePacketOverhead( | 161 StreamFramePacketOverhead(framer_->version(), |
| 159 framer_->version(), PACKET_8BYTE_CONNECTION_ID, kIncludeVersion, | 162 PACKET_8BYTE_CONNECTION_ID, |
| 160 PACKET_6BYTE_SEQUENCE_NUMBER, IN_FEC_GROUP)); | 163 kIncludeVersion, |
| 164 PACKET_6BYTE_SEQUENCE_NUMBER, |
| 165 IN_FEC_GROUP)); |
| 161 InFecGroup is_in_fec_group = MaybeStartFEC(); | 166 InFecGroup is_in_fec_group = MaybeStartFEC(); |
| 162 | 167 |
| 163 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) | 168 LOG_IF(DFATAL, !HasRoomForStreamFrame(id, offset)) |
| 164 << "No room for Stream frame, BytesFree: " << BytesFree() | 169 << "No room for Stream frame, BytesFree: " << BytesFree() |
| 165 << " MinStreamFrameSize: " | 170 << " MinStreamFrameSize: " |
| 166 << QuicFramer::GetMinStreamFrameSize( | 171 << QuicFramer::GetMinStreamFrameSize( |
| 167 framer_->version(), id, offset, true, is_in_fec_group); | 172 framer_->version(), id, offset, true, is_in_fec_group); |
| 168 | 173 |
| 169 if (data.Empty()) { | 174 if (data.Empty()) { |
| 170 LOG_IF(DFATAL, !fin) | 175 LOG_IF(DFATAL, !fin) << "Creating a stream frame with no data or fin."; |
| 171 << "Creating a stream frame with no data or fin."; | |
| 172 // Create a new packet for the fin, if necessary. | 176 // Create a new packet for the fin, if necessary. |
| 173 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, data)); | 177 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, data)); |
| 174 return 0; | 178 return 0; |
| 175 } | 179 } |
| 176 | 180 |
| 177 const size_t data_size = data.TotalBufferSize(); | 181 const size_t data_size = data.TotalBufferSize(); |
| 178 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( | 182 size_t min_frame_size = |
| 179 framer_->version(), id, offset, /*last_frame_in_packet=*/ true, | 183 QuicFramer::GetMinStreamFrameSize(framer_->version(), |
| 180 is_in_fec_group); | 184 id, |
| 185 offset, |
| 186 /*last_frame_in_packet=*/true, |
| 187 is_in_fec_group); |
| 181 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); | 188 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); |
| 182 | 189 |
| 183 bool set_fin = fin && bytes_consumed == data_size; // Last frame. | 190 bool set_fin = fin && bytes_consumed == data_size; // Last frame. |
| 184 IOVector frame_data; | 191 IOVector frame_data; |
| 185 frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(), | 192 frame_data.AppendIovecAtMostBytes(data.iovec(), data.Size(), bytes_consumed); |
| 186 bytes_consumed); | |
| 187 DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed); | 193 DCHECK_EQ(frame_data.TotalBufferSize(), bytes_consumed); |
| 188 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data)); | 194 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, frame_data)); |
| 189 return bytes_consumed; | 195 return bytes_consumed; |
| 190 } | 196 } |
| 191 | 197 |
| 192 size_t QuicPacketCreator::CreateStreamFrameWithNotifier( | 198 size_t QuicPacketCreator::CreateStreamFrameWithNotifier( |
| 193 QuicStreamId id, | 199 QuicStreamId id, |
| 194 const IOVector& data, | 200 const IOVector& data, |
| 195 QuicStreamOffset offset, | 201 QuicStreamOffset offset, |
| 196 bool fin, | 202 bool fin, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 | 237 |
| 232 return serialized_packet; | 238 return serialized_packet; |
| 233 } | 239 } |
| 234 | 240 |
| 235 SerializedPacket QuicPacketCreator::SerializeAllFrames( | 241 SerializedPacket QuicPacketCreator::SerializeAllFrames( |
| 236 const QuicFrames& frames) { | 242 const QuicFrames& frames) { |
| 237 // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued | 243 // TODO(satyamshekhar): Verify that this DCHECK won't fail. What about queued |
| 238 // frames from SendStreamData()[send_stream_should_flush_ == false && | 244 // frames from SendStreamData()[send_stream_should_flush_ == false && |
| 239 // data.empty() == true] and retransmit due to RTO. | 245 // data.empty() == true] and retransmit due to RTO. |
| 240 DCHECK_EQ(0u, queued_frames_.size()); | 246 DCHECK_EQ(0u, queued_frames_.size()); |
| 241 LOG_IF(DFATAL, frames.empty()) | 247 LOG_IF(DFATAL, frames.empty()) << "Attempt to serialize empty packet"; |
| 242 << "Attempt to serialize empty packet"; | |
| 243 for (size_t i = 0; i < frames.size(); ++i) { | 248 for (size_t i = 0; i < frames.size(); ++i) { |
| 244 bool success = AddFrame(frames[i], false); | 249 bool success = AddFrame(frames[i], false); |
| 245 DCHECK(success); | 250 DCHECK(success); |
| 246 } | 251 } |
| 247 SerializedPacket packet = SerializePacket(); | 252 SerializedPacket packet = SerializePacket(); |
| 248 DCHECK(packet.retransmittable_frames == NULL); | 253 DCHECK(packet.retransmittable_frames == NULL); |
| 249 return packet; | 254 return packet; |
| 250 } | 255 } |
| 251 | 256 |
| 252 bool QuicPacketCreator::HasPendingFrames() { | 257 bool QuicPacketCreator::HasPendingFrames() { |
| 253 return !queued_frames_.empty(); | 258 return !queued_frames_.empty(); |
| 254 } | 259 } |
| 255 | 260 |
| 256 size_t QuicPacketCreator::ExpansionOnNewFrame() const { | 261 size_t QuicPacketCreator::ExpansionOnNewFrame() const { |
| 257 // If packet is FEC protected, there's no expansion. | 262 // If packet is FEC protected, there's no expansion. |
| 258 if (fec_group_.get() != NULL) { | 263 if (fec_group_.get() != NULL) { |
| 259 return 0; | 264 return 0; |
| 260 } | 265 } |
| 261 // If the last frame in the packet is a stream frame, then it will expand to | 266 // If the last frame in the packet is a stream frame, then it will expand to |
| 262 // include the stream_length field when a new frame is added. | 267 // include the stream_length field when a new frame is added. |
| 263 bool has_trailing_stream_frame = | 268 bool has_trailing_stream_frame = |
| 264 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; | 269 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; |
| 265 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; | 270 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; |
| 266 } | 271 } |
| 267 | 272 |
| 268 size_t QuicPacketCreator::BytesFree() const { | 273 size_t QuicPacketCreator::BytesFree() const { |
| 269 const size_t max_plaintext_size = | 274 const size_t max_plaintext_size = |
| 270 framer_->GetMaxPlaintextSize(options_.max_packet_length); | 275 framer_->GetMaxPlaintextSize(options_.max_packet_length); |
| 271 DCHECK_GE(max_plaintext_size, PacketSize()); | 276 DCHECK_GE(max_plaintext_size, PacketSize()); |
| 272 return max_plaintext_size - min(max_plaintext_size, PacketSize() | 277 return max_plaintext_size - |
| 273 + ExpansionOnNewFrame()); | 278 min(max_plaintext_size, PacketSize() + ExpansionOnNewFrame()); |
| 274 } | 279 } |
| 275 | 280 |
| 276 InFecGroup QuicPacketCreator::IsFecEnabled() const { | 281 InFecGroup QuicPacketCreator::IsFecEnabled() const { |
| 277 return (options_.max_packets_per_fec_group == 0) ? | 282 return (options_.max_packets_per_fec_group == 0) ? NOT_IN_FEC_GROUP |
| 278 NOT_IN_FEC_GROUP : IN_FEC_GROUP; | 283 : IN_FEC_GROUP; |
| 279 } | 284 } |
| 280 | 285 |
| 281 size_t QuicPacketCreator::PacketSize() const { | 286 size_t QuicPacketCreator::PacketSize() const { |
| 282 if (queued_frames_.empty()) { | 287 if (queued_frames_.empty()) { |
| 283 // Only adjust the sequence number length when the FEC group is not open, | 288 // Only adjust the sequence number length when the FEC group is not open, |
| 284 // to ensure no packets in a group are too large. | 289 // to ensure no packets in a group are too large. |
| 285 if (fec_group_.get() == NULL || | 290 if (fec_group_.get() == NULL || fec_group_->NumReceivedPackets() == 0) { |
| 286 fec_group_->NumReceivedPackets() == 0) { | |
| 287 sequence_number_length_ = options_.send_sequence_number_length; | 291 sequence_number_length_ = options_.send_sequence_number_length; |
| 288 } | 292 } |
| 289 packet_size_ = GetPacketHeaderSize(options_.send_connection_id_length, | 293 packet_size_ = GetPacketHeaderSize(options_.send_connection_id_length, |
| 290 send_version_in_packet_, | 294 send_version_in_packet_, |
| 291 sequence_number_length_, | 295 sequence_number_length_, |
| 292 IsFecEnabled()); | 296 IsFecEnabled()); |
| 293 } | 297 } |
| 294 return packet_size_; | 298 return packet_size_; |
| 295 } | 299 } |
| 296 | 300 |
| 297 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { | 301 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { |
| 298 return AddFrame(frame, true); | 302 return AddFrame(frame, true); |
| 299 } | 303 } |
| 300 | 304 |
| 301 SerializedPacket QuicPacketCreator::SerializePacket() { | 305 SerializedPacket QuicPacketCreator::SerializePacket() { |
| 302 LOG_IF(DFATAL, queued_frames_.empty()) | 306 LOG_IF(DFATAL, queued_frames_.empty()) << "Attempt to serialize empty packet"; |
| 303 << "Attempt to serialize empty packet"; | |
| 304 QuicPacketHeader header; | 307 QuicPacketHeader header; |
| 305 FillPacketHeader(fec_group_number_, false, &header); | 308 FillPacketHeader(fec_group_number_, false, &header); |
| 306 | 309 |
| 307 MaybeAddPadding(); | 310 MaybeAddPadding(); |
| 308 | 311 |
| 309 size_t max_plaintext_size = | 312 size_t max_plaintext_size = |
| 310 framer_->GetMaxPlaintextSize(options_.max_packet_length); | 313 framer_->GetMaxPlaintextSize(options_.max_packet_length); |
| 311 DCHECK_GE(max_plaintext_size, packet_size_); | 314 DCHECK_GE(max_plaintext_size, packet_size_); |
| 312 // ACK and CONNECTION_CLOSE Frames will be truncated only if they're | 315 // ACK and CONNECTION_CLOSE Frames will be truncated only if they're |
| 313 // the first frame in the packet. If truncation is to occur, then | 316 // the first frame in the packet. If truncation is to occur, then |
| 314 // GetSerializedFrameLength will have returned all bytes free. | 317 // GetSerializedFrameLength will have returned all bytes free. |
| 315 bool possibly_truncated = | 318 bool possibly_truncated = |
| 316 packet_size_ != max_plaintext_size || | 319 packet_size_ != max_plaintext_size || queued_frames_.size() != 1 || |
| 317 queued_frames_.size() != 1 || | |
| 318 (queued_frames_.back().type == ACK_FRAME || | 320 (queued_frames_.back().type == ACK_FRAME || |
| 319 queued_frames_.back().type == CONNECTION_CLOSE_FRAME); | 321 queued_frames_.back().type == CONNECTION_CLOSE_FRAME); |
| 320 SerializedPacket serialized = | 322 SerializedPacket serialized = |
| 321 framer_->BuildDataPacket(header, queued_frames_, packet_size_); | 323 framer_->BuildDataPacket(header, queued_frames_, packet_size_); |
| 322 LOG_IF(DFATAL, !serialized.packet) | 324 LOG_IF(DFATAL, !serialized.packet) << "Failed to serialize " |
| 323 << "Failed to serialize " << queued_frames_.size() << " frames."; | 325 << queued_frames_.size() << " frames."; |
| 324 // Because of possible truncation, we can't be confident that our | 326 // Because of possible truncation, we can't be confident that our |
| 325 // packet size calculation worked correctly. | 327 // packet size calculation worked correctly. |
| 326 if (!possibly_truncated) | 328 if (!possibly_truncated) |
| 327 DCHECK_EQ(packet_size_, serialized.packet->length()); | 329 DCHECK_EQ(packet_size_, serialized.packet->length()); |
| 328 | 330 |
| 329 packet_size_ = 0; | 331 packet_size_ = 0; |
| 330 queued_frames_.clear(); | 332 queued_frames_.clear(); |
| 331 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); | 333 serialized.retransmittable_frames = queued_retransmittable_frames_.release(); |
| 332 return serialized; | 334 return serialized; |
| 333 } | 335 } |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 return false; | 402 return false; |
| 401 default: | 403 default: |
| 402 return true; | 404 return true; |
| 403 } | 405 } |
| 404 } | 406 } |
| 405 | 407 |
| 406 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, | 408 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, |
| 407 bool save_retransmittable_frames) { | 409 bool save_retransmittable_frames) { |
| 408 DVLOG(1) << "Adding frame: " << frame; | 410 DVLOG(1) << "Adding frame: " << frame; |
| 409 InFecGroup is_in_fec_group = MaybeStartFEC(); | 411 InFecGroup is_in_fec_group = MaybeStartFEC(); |
| 410 size_t frame_len = framer_->GetSerializedFrameLength( | 412 size_t frame_len = |
| 411 frame, BytesFree(), queued_frames_.empty(), true, is_in_fec_group, | 413 framer_->GetSerializedFrameLength(frame, |
| 412 options()->send_sequence_number_length); | 414 BytesFree(), |
| 415 queued_frames_.empty(), |
| 416 true, |
| 417 is_in_fec_group, |
| 418 options()->send_sequence_number_length); |
| 413 if (frame_len == 0) { | 419 if (frame_len == 0) { |
| 414 return false; | 420 return false; |
| 415 } | 421 } |
| 416 DCHECK_LT(0u, packet_size_); | 422 DCHECK_LT(0u, packet_size_); |
| 417 packet_size_ += ExpansionOnNewFrame() + frame_len; | 423 packet_size_ += ExpansionOnNewFrame() + frame_len; |
| 418 | 424 |
| 419 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | 425 if (save_retransmittable_frames && ShouldRetransmit(frame)) { |
| 420 if (queued_retransmittable_frames_.get() == NULL) { | 426 if (queued_retransmittable_frames_.get() == NULL) { |
| 421 queued_retransmittable_frames_.reset(new RetransmittableFrames()); | 427 queued_retransmittable_frames_.reset(new RetransmittableFrames()); |
| 422 } | 428 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 452 if (!is_handshake) { | 458 if (!is_handshake) { |
| 453 return; | 459 return; |
| 454 } | 460 } |
| 455 | 461 |
| 456 QuicPaddingFrame padding; | 462 QuicPaddingFrame padding; |
| 457 bool success = AddFrame(QuicFrame(&padding), false); | 463 bool success = AddFrame(QuicFrame(&padding), false); |
| 458 DCHECK(success); | 464 DCHECK(success); |
| 459 } | 465 } |
| 460 | 466 |
| 461 } // namespace net | 467 } // namespace net |
| OLD | NEW |