OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/quic/quic_packet_generator.h" | |
6 | |
7 #include "base/logging.h" | |
8 #include "net/quic/quic_bug_tracker.h" | |
9 #include "net/quic/quic_flags.h" | |
10 #include "net/quic/quic_utils.h" | |
11 | |
12 using base::StringPiece; | |
13 | |
14 namespace net { | |
15 | |
16 QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId connection_id, | |
17 QuicFramer* framer, | |
18 QuicRandom* random_generator, | |
19 QuicBufferAllocator* buffer_allocator, | |
20 DelegateInterface* delegate) | |
21 : delegate_(delegate), | |
22 packet_creator_(connection_id, | |
23 framer, | |
24 random_generator, | |
25 buffer_allocator, | |
26 delegate), | |
27 batch_mode_(false), | |
28 should_send_ack_(false), | |
29 should_send_stop_waiting_(false) {} | |
30 | |
31 QuicPacketGenerator::~QuicPacketGenerator() { | |
32 QuicUtils::DeleteFrames(&queued_control_frames_); | |
33 } | |
34 | |
35 void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) { | |
36 if (packet_creator_.has_ack()) { | |
37 // Ack already queued, nothing to do. | |
38 return; | |
39 } | |
40 | |
41 if (also_send_stop_waiting && packet_creator_.has_stop_waiting()) { | |
42 QUIC_BUG << "Should only ever be one pending stop waiting frame."; | |
43 return; | |
44 } | |
45 | |
46 should_send_ack_ = true; | |
47 should_send_stop_waiting_ = also_send_stop_waiting; | |
48 SendQueuedFrames(/*flush=*/false); | |
49 } | |
50 | |
51 void QuicPacketGenerator::AddControlFrame(const QuicFrame& frame) { | |
52 queued_control_frames_.push_back(frame); | |
53 SendQueuedFrames(/*flush=*/false); | |
54 } | |
55 | |
56 QuicConsumedData QuicPacketGenerator::ConsumeData( | |
57 QuicStreamId id, | |
58 QuicIOVector iov, | |
59 QuicStreamOffset offset, | |
60 bool fin, | |
61 QuicAckListenerInterface* listener) { | |
62 bool has_handshake = (id == kCryptoStreamId); | |
63 QUIC_BUG_IF(has_handshake && fin) | |
64 << "Handshake packets should never send a fin"; | |
65 // To make reasoning about crypto frames easier, we don't combine them with | |
66 // other retransmittable frames in a single packet. | |
67 const bool flush = | |
68 has_handshake && packet_creator_.HasPendingRetransmittableFrames(); | |
69 SendQueuedFrames(flush); | |
70 | |
71 size_t total_bytes_consumed = 0; | |
72 bool fin_consumed = false; | |
73 | |
74 if (!packet_creator_.HasRoomForStreamFrame(id, offset)) { | |
75 packet_creator_.Flush(); | |
76 } | |
77 | |
78 if (!fin && (iov.total_length == 0)) { | |
79 QUIC_BUG << "Attempt to consume empty data without FIN."; | |
80 return QuicConsumedData(0, false); | |
81 } | |
82 | |
83 while (delegate_->ShouldGeneratePacket( | |
84 HAS_RETRANSMITTABLE_DATA, has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) { | |
85 QuicFrame frame; | |
86 if (!packet_creator_.ConsumeData(id, iov, total_bytes_consumed, | |
87 offset + total_bytes_consumed, fin, | |
88 has_handshake, &frame)) { | |
89 // The creator is always flushed if there's not enough room for a new | |
90 // stream frame before ConsumeData, so ConsumeData should always succeed. | |
91 QUIC_BUG << "Failed to ConsumeData, stream:" << id; | |
92 return QuicConsumedData(0, false); | |
93 } | |
94 | |
95 // A stream frame is created and added. | |
96 size_t bytes_consumed = frame.stream_frame->data_length; | |
97 if (listener != nullptr) { | |
98 packet_creator_.AddAckListener(listener, bytes_consumed); | |
99 } | |
100 total_bytes_consumed += bytes_consumed; | |
101 fin_consumed = fin && total_bytes_consumed == iov.total_length; | |
102 DCHECK(total_bytes_consumed == iov.total_length || | |
103 (bytes_consumed > 0 && packet_creator_.HasPendingFrames())); | |
104 | |
105 if (!InBatchMode()) { | |
106 packet_creator_.Flush(); | |
107 } | |
108 | |
109 if (total_bytes_consumed == iov.total_length) { | |
110 // We're done writing the data. Exit the loop. | |
111 // We don't make this a precondition because we could have 0 bytes of data | |
112 // if we're simply writing a fin. | |
113 break; | |
114 } | |
115 // TODO(ianswett): Move to having the creator flush itself when it's full. | |
116 packet_creator_.Flush(); | |
117 } | |
118 | |
119 // Don't allow the handshake to be bundled with other retransmittable frames. | |
120 if (has_handshake) { | |
121 SendQueuedFrames(/*flush=*/true); | |
122 } | |
123 | |
124 DCHECK(InBatchMode() || !packet_creator_.HasPendingFrames()); | |
125 return QuicConsumedData(total_bytes_consumed, fin_consumed); | |
126 } | |
127 | |
128 QuicConsumedData QuicPacketGenerator::ConsumeDataFastPath( | |
129 QuicStreamId id, | |
130 const QuicIOVector& iov, | |
131 QuicStreamOffset offset, | |
132 bool fin, | |
133 QuicAckListenerInterface* listener) { | |
134 DCHECK_NE(id, kCryptoStreamId); | |
135 size_t total_bytes_consumed = 0; | |
136 while (total_bytes_consumed < iov.total_length && | |
137 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA, | |
138 NOT_HANDSHAKE)) { | |
139 // Serialize and encrypt the packet. | |
140 ALIGNAS(64) char encrypted_buffer[kMaxPacketSize]; | |
141 size_t bytes_consumed = 0; | |
142 packet_creator_.CreateAndSerializeStreamFrame( | |
143 id, iov, total_bytes_consumed, offset + total_bytes_consumed, fin, | |
144 listener, encrypted_buffer, kMaxPacketSize, &bytes_consumed); | |
145 total_bytes_consumed += bytes_consumed; | |
146 } | |
147 | |
148 return QuicConsumedData(total_bytes_consumed, | |
149 fin && (total_bytes_consumed == iov.total_length)); | |
150 } | |
151 | |
152 void QuicPacketGenerator::GenerateMtuDiscoveryPacket( | |
153 QuicByteCount target_mtu, | |
154 QuicAckListenerInterface* listener) { | |
155 // MTU discovery frames must be sent by themselves. | |
156 if (!packet_creator_.CanSetMaxPacketLength()) { | |
157 QUIC_BUG << "MTU discovery packets should only be sent when no other " | |
158 << "frames needs to be sent."; | |
159 return; | |
160 } | |
161 const QuicByteCount current_mtu = GetCurrentMaxPacketLength(); | |
162 | |
163 // The MTU discovery frame is allocated on the stack, since it is going to be | |
164 // serialized within this function. | |
165 QuicMtuDiscoveryFrame mtu_discovery_frame; | |
166 QuicFrame frame(mtu_discovery_frame); | |
167 | |
168 // Send the probe packet with the new length. | |
169 SetMaxPacketLength(target_mtu); | |
170 const bool success = packet_creator_.AddPaddedSavedFrame(frame); | |
171 if (listener != nullptr) { | |
172 packet_creator_.AddAckListener(listener, 0); | |
173 } | |
174 packet_creator_.Flush(); | |
175 // The only reason AddFrame can fail is that the packet is too full to fit in | |
176 // a ping. This is not possible for any sane MTU. | |
177 DCHECK(success); | |
178 | |
179 // Reset the packet length back. | |
180 SetMaxPacketLength(current_mtu); | |
181 } | |
182 | |
183 bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const { | |
184 DCHECK(HasPendingFrames()); | |
185 HasRetransmittableData retransmittable = | |
186 (should_send_ack_ || should_send_stop_waiting_) | |
187 ? NO_RETRANSMITTABLE_DATA | |
188 : HAS_RETRANSMITTABLE_DATA; | |
189 if (retransmittable == HAS_RETRANSMITTABLE_DATA) { | |
190 DCHECK(!queued_control_frames_.empty()); // These are retransmittable. | |
191 } | |
192 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE); | |
193 } | |
194 | |
195 void QuicPacketGenerator::SendQueuedFrames(bool flush) { | |
196 // Only add pending frames if we are SURE we can then send the whole packet. | |
197 while (HasPendingFrames() && | |
198 (flush || CanSendWithNextPendingFrameAddition())) { | |
199 AddNextPendingFrame(); | |
200 } | |
201 if (flush || !InBatchMode()) { | |
202 packet_creator_.Flush(); | |
203 } | |
204 } | |
205 | |
206 bool QuicPacketGenerator::InBatchMode() { | |
207 return batch_mode_; | |
208 } | |
209 | |
210 void QuicPacketGenerator::StartBatchOperations() { | |
211 batch_mode_ = true; | |
212 } | |
213 | |
214 void QuicPacketGenerator::FinishBatchOperations() { | |
215 batch_mode_ = false; | |
216 SendQueuedFrames(/*flush=*/false); | |
217 } | |
218 | |
219 void QuicPacketGenerator::FlushAllQueuedFrames() { | |
220 SendQueuedFrames(/*flush=*/true); | |
221 } | |
222 | |
223 bool QuicPacketGenerator::HasQueuedFrames() const { | |
224 return packet_creator_.HasPendingFrames() || HasPendingFrames(); | |
225 } | |
226 | |
227 bool QuicPacketGenerator::IsPendingPacketEmpty() const { | |
228 return !packet_creator_.HasPendingFrames(); | |
229 } | |
230 | |
231 bool QuicPacketGenerator::HasPendingFrames() const { | |
232 return should_send_ack_ || should_send_stop_waiting_ || | |
233 !queued_control_frames_.empty(); | |
234 } | |
235 | |
236 bool QuicPacketGenerator::AddNextPendingFrame() { | |
237 if (should_send_ack_) { | |
238 should_send_ack_ = | |
239 !packet_creator_.AddSavedFrame(delegate_->GetUpdatedAckFrame()); | |
240 return !should_send_ack_; | |
241 } | |
242 | |
243 if (should_send_stop_waiting_) { | |
244 delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_); | |
245 // If we can't this add the frame now, then we still need to do so later. | |
246 should_send_stop_waiting_ = | |
247 !packet_creator_.AddSavedFrame(QuicFrame(&pending_stop_waiting_frame_)); | |
248 // Return success if we have cleared out this flag (i.e., added the frame). | |
249 // If we still need to send, then the frame is full, and we have failed. | |
250 return !should_send_stop_waiting_; | |
251 } | |
252 | |
253 QUIC_BUG_IF(queued_control_frames_.empty()) | |
254 << "AddNextPendingFrame called with no queued control frames."; | |
255 if (!packet_creator_.AddSavedFrame(queued_control_frames_.back())) { | |
256 // Packet was full. | |
257 return false; | |
258 } | |
259 queued_control_frames_.pop_back(); | |
260 return true; | |
261 } | |
262 | |
263 void QuicPacketGenerator::StopSendingVersion() { | |
264 packet_creator_.StopSendingVersion(); | |
265 } | |
266 | |
267 void QuicPacketGenerator::SetDiversificationNonce( | |
268 const DiversificationNonce nonce) { | |
269 packet_creator_.SetDiversificationNonce(nonce); | |
270 } | |
271 | |
272 QuicPacketNumber QuicPacketGenerator::packet_number() const { | |
273 return packet_creator_.packet_number(); | |
274 } | |
275 | |
276 QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const { | |
277 return packet_creator_.max_packet_length(); | |
278 } | |
279 | |
280 void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) { | |
281 DCHECK(packet_creator_.CanSetMaxPacketLength()); | |
282 packet_creator_.SetMaxPacketLength(length); | |
283 } | |
284 | |
285 QuicEncryptedPacket* QuicPacketGenerator::SerializeVersionNegotiationPacket( | |
286 const QuicVersionVector& supported_versions) { | |
287 return packet_creator_.SerializeVersionNegotiationPacket(supported_versions); | |
288 } | |
289 | |
290 void QuicPacketGenerator::ReserializeAllFrames( | |
291 const PendingRetransmission& retransmission, | |
292 char* buffer, | |
293 size_t buffer_len) { | |
294 packet_creator_.ReserializeAllFrames(retransmission, buffer, buffer_len); | |
295 } | |
296 | |
297 void QuicPacketGenerator::UpdateSequenceNumberLength( | |
298 QuicPacketNumber least_packet_awaited_by_peer, | |
299 QuicPacketCount max_packets_in_flight) { | |
300 return packet_creator_.UpdatePacketNumberLength(least_packet_awaited_by_peer, | |
301 max_packets_in_flight); | |
302 } | |
303 | |
304 void QuicPacketGenerator::SetConnectionIdLength(uint32_t length) { | |
305 if (length == 0) { | |
306 packet_creator_.set_connection_id_length(PACKET_0BYTE_CONNECTION_ID); | |
307 } else { | |
308 packet_creator_.set_connection_id_length(PACKET_8BYTE_CONNECTION_ID); | |
309 } | |
310 } | |
311 | |
312 void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) { | |
313 packet_creator_.set_encryption_level(level); | |
314 } | |
315 | |
316 void QuicPacketGenerator::SetEncrypter(EncryptionLevel level, | |
317 QuicEncrypter* encrypter) { | |
318 packet_creator_.SetEncrypter(level, encrypter); | |
319 } | |
320 | |
321 void QuicPacketGenerator::SetCurrentPath( | |
322 QuicPathId path_id, | |
323 QuicPacketNumber least_packet_awaited_by_peer, | |
324 QuicPacketCount max_packets_in_flight) { | |
325 packet_creator_.SetCurrentPath(path_id, least_packet_awaited_by_peer, | |
326 max_packets_in_flight); | |
327 } | |
328 | |
329 } // namespace net | |
OLD | NEW |