| 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_generator.h" | 5 #include "net/quic/quic_packet_generator.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/quic_fec_group.h" | 9 #include "net/quic/quic_fec_group.h" |
| 10 #include "net/quic/quic_utils.h" | 10 #include "net/quic/quic_utils.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 | 86 |
| 87 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { | 87 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { |
| 88 queued_control_frames_.push_back(frame); | 88 queued_control_frames_.push_back(frame); |
| 89 SendQueuedFrames(false); | 89 SendQueuedFrames(false); |
| 90 } | 90 } |
| 91 | 91 |
| 92 QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id, | 92 QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id, |
| 93 const IOVector& data_to_write, | 93 const IOVector& data_to_write, |
| 94 QuicStreamOffset offset, | 94 QuicStreamOffset offset, |
| 95 bool fin, | 95 bool fin, |
| 96 FecProtection fec_protection, |
| 96 QuicAckNotifier* notifier) { | 97 QuicAckNotifier* notifier) { |
| 97 IsHandshake handshake = id == kCryptoStreamId ? IS_HANDSHAKE : NOT_HANDSHAKE; | 98 IsHandshake handshake = id == kCryptoStreamId ? IS_HANDSHAKE : NOT_HANDSHAKE; |
| 98 SendQueuedFrames(false); | 99 SendQueuedFrames(false); |
| 99 | 100 |
| 100 size_t total_bytes_consumed = 0; | 101 size_t total_bytes_consumed = 0; |
| 101 bool fin_consumed = false; | 102 bool fin_consumed = false; |
| 102 | 103 |
| 103 if (!packet_creator_->HasRoomForStreamFrame(id, offset)) { | 104 if (!packet_creator_->HasRoomForStreamFrame(id, offset)) { |
| 104 SerializeAndSendPacket(); | 105 SerializeAndSendPacket(); |
| 105 } | 106 } |
| 106 | 107 |
| 108 if (fec_protection == MUST_FEC_PROTECT) { |
| 109 MaybeStartFecProtection(); |
| 110 } |
| 111 |
| 107 IOVector data = data_to_write; | 112 IOVector data = data_to_write; |
| 108 size_t data_size = data.TotalBufferSize(); | 113 size_t data_size = data.TotalBufferSize(); |
| 109 while (delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, | 114 while (delegate_->ShouldGeneratePacket(NOT_RETRANSMISSION, |
| 110 HAS_RETRANSMITTABLE_DATA, handshake)) { | 115 HAS_RETRANSMITTABLE_DATA, handshake)) { |
| 111 QuicFrame frame; | 116 QuicFrame frame; |
| 112 size_t bytes_consumed; | 117 size_t bytes_consumed; |
| 113 if (notifier != NULL) { | 118 if (notifier != NULL) { |
| 114 // We want to track which packet this stream frame ends up in. | 119 // We want to track which packet this stream frame ends up in. |
| 115 bytes_consumed = packet_creator_->CreateStreamFrameWithNotifier( | 120 bytes_consumed = packet_creator_->CreateStreamFrameWithNotifier( |
| 116 id, data, offset + total_bytes_consumed, fin, notifier, &frame); | 121 id, data, offset + total_bytes_consumed, fin, notifier, &frame); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 133 | 138 |
| 134 // TODO(ianswett): Restore packet reordering. | 139 // TODO(ianswett): Restore packet reordering. |
| 135 if (!InBatchMode() || !packet_creator_->HasRoomForStreamFrame(id, offset)) { | 140 if (!InBatchMode() || !packet_creator_->HasRoomForStreamFrame(id, offset)) { |
| 136 SerializeAndSendPacket(); | 141 SerializeAndSendPacket(); |
| 137 } | 142 } |
| 138 | 143 |
| 139 if (data.Empty()) { | 144 if (data.Empty()) { |
| 140 // We're done writing the data. Exit the loop. | 145 // We're done writing the data. Exit the loop. |
| 141 // We don't make this a precondition because we could have 0 bytes of data | 146 // We don't make this a precondition because we could have 0 bytes of data |
| 142 // if we're simply writing a fin. | 147 // if we're simply writing a fin. |
| 148 if (fec_protection == MUST_FEC_PROTECT) { |
| 149 // Turn off FEC protection when we're done writing protected data. |
| 150 DVLOG(1) << "Turning FEC protection OFF"; |
| 151 should_fec_protect_ = false; |
| 152 } |
| 143 break; | 153 break; |
| 144 } | 154 } |
| 145 } | 155 } |
| 146 | 156 |
| 147 // Try to close FEC group since we've either run out of data to send or we're | 157 // Try to close FEC group since we've either run out of data to send or we're |
| 148 // blocked. If not in batch mode, force close the group. | 158 // blocked. If not in batch mode, force close the group. |
| 149 MaybeSendFecPacketAndCloseGroup(!InBatchMode()); | 159 MaybeSendFecPacketAndCloseGroup(!InBatchMode()); |
| 150 | 160 |
| 151 DCHECK(InBatchMode() || !packet_creator_->HasPendingFrames()); | 161 DCHECK(InBatchMode() || !packet_creator_->HasPendingFrames()); |
| 152 return QuicConsumedData(total_bytes_consumed, fin_consumed); | 162 return QuicConsumedData(total_bytes_consumed, fin_consumed); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 // pending frames when FEC protection is turned on. If current packet can be | 209 // pending frames when FEC protection is turned on. If current packet can be |
| 200 // converted to an FEC protected packet, do it. This will require the | 210 // converted to an FEC protected packet, do it. This will require the |
| 201 // generator to check if the resulting expansion still allows the incoming | 211 // generator to check if the resulting expansion still allows the incoming |
| 202 // frame to be added to the packet. | 212 // frame to be added to the packet. |
| 203 SendQueuedFrames(true); | 213 SendQueuedFrames(true); |
| 204 } | 214 } |
| 205 packet_creator_->StartFecProtectingPackets(); | 215 packet_creator_->StartFecProtectingPackets(); |
| 206 DCHECK(packet_creator_->IsFecProtected()); | 216 DCHECK(packet_creator_->IsFecProtected()); |
| 207 } | 217 } |
| 208 | 218 |
| 209 void QuicPacketGenerator::MaybeStopFecProtection(bool force) { | |
| 210 DVLOG(1) << "Turning FEC protection OFF"; | |
| 211 // FEC protection will stop after the next FEC packet is transmitted. | |
| 212 should_fec_protect_ = false; | |
| 213 MaybeSendFecPacketAndCloseGroup(force); | |
| 214 } | |
| 215 | |
| 216 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) { | 219 void QuicPacketGenerator::MaybeSendFecPacketAndCloseGroup(bool force) { |
| 217 if (!packet_creator_->IsFecProtected() || | 220 if (!packet_creator_->IsFecProtected() || |
| 218 packet_creator_->HasPendingFrames()) { | 221 packet_creator_->HasPendingFrames()) { |
| 219 return; | 222 return; |
| 220 } | 223 } |
| 221 | 224 |
| 222 if (packet_creator_->ShouldSendFec(force)) { | 225 if (packet_creator_->ShouldSendFec(force)) { |
| 223 // TODO(jri): SerializeFec can return a NULL packet, and this should | 226 // TODO(jri): SerializeFec can return a NULL packet, and this should |
| 224 // cause an early return, with a call to | 227 // cause an early return, with a call to |
| 225 // delegate_->OnPacketGenerationError. | 228 // delegate_->OnPacketGenerationError. |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 } | 314 } |
| 312 | 315 |
| 313 void QuicPacketGenerator::SerializeAndSendPacket() { | 316 void QuicPacketGenerator::SerializeAndSendPacket() { |
| 314 SerializedPacket serialized_packet = packet_creator_->SerializePacket(); | 317 SerializedPacket serialized_packet = packet_creator_->SerializePacket(); |
| 315 DCHECK(serialized_packet.packet); | 318 DCHECK(serialized_packet.packet); |
| 316 delegate_->OnSerializedPacket(serialized_packet); | 319 delegate_->OnSerializedPacket(serialized_packet); |
| 317 MaybeSendFecPacketAndCloseGroup(false); | 320 MaybeSendFecPacketAndCloseGroup(false); |
| 318 } | 321 } |
| 319 | 322 |
| 320 } // namespace net | 323 } // namespace net |
| OLD | NEW |