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 |