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_creator.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/logging.h" | |
10 #include "base/macros.h" | |
11 #include "net/quic/crypto/crypto_protocol.h" | |
12 #include "net/quic/crypto/quic_random.h" | |
13 #include "net/quic/quic_bug_tracker.h" | |
14 #include "net/quic/quic_data_writer.h" | |
15 #include "net/quic/quic_flags.h" | |
16 #include "net/quic/quic_utils.h" | |
17 | |
18 using base::StringPiece; | |
19 using std::make_pair; | |
20 using std::max; | |
21 using std::min; | |
22 using std::pair; | |
23 using std::string; | |
24 using std::vector; | |
25 | |
26 namespace net { | |
27 | |
28 QuicPacketCreator::QuicPacketCreator(QuicConnectionId connection_id, | |
29 QuicFramer* framer, | |
30 QuicRandom* random_generator, | |
31 QuicBufferAllocator* buffer_allocator, | |
32 DelegateInterface* delegate) | |
33 : delegate_(delegate), | |
34 debug_delegate_(nullptr), | |
35 framer_(framer), | |
36 random_bool_source_(random_generator), | |
37 buffer_allocator_(buffer_allocator), | |
38 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT), | |
39 send_path_id_in_packet_(false), | |
40 next_packet_number_length_(PACKET_1BYTE_PACKET_NUMBER), | |
41 have_diversification_nonce_(false), | |
42 max_packet_length_(0), | |
43 connection_id_length_(PACKET_8BYTE_CONNECTION_ID), | |
44 packet_size_(0), | |
45 connection_id_(connection_id), | |
46 packet_(kDefaultPathId, | |
47 0, | |
48 PACKET_1BYTE_PACKET_NUMBER, | |
49 nullptr, | |
50 0, | |
51 0, | |
52 false, | |
53 false) { | |
54 SetMaxPacketLength(kDefaultMaxPacketSize); | |
55 } | |
56 | |
57 QuicPacketCreator::~QuicPacketCreator() { | |
58 QuicUtils::DeleteFrames(&packet_.retransmittable_frames); | |
59 } | |
60 | |
61 void QuicPacketCreator::SetEncrypter(EncryptionLevel level, | |
62 QuicEncrypter* encrypter) { | |
63 framer_->SetEncrypter(level, encrypter); | |
64 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); | |
65 } | |
66 | |
67 bool QuicPacketCreator::CanSetMaxPacketLength() const { | |
68 // |max_packet_length_| should not be changed mid-packet. | |
69 return queued_frames_.empty(); | |
70 } | |
71 | |
72 void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) { | |
73 DCHECK(CanSetMaxPacketLength()); | |
74 | |
75 // Avoid recomputing |max_plaintext_size_| if the length does not actually | |
76 // change. | |
77 if (length == max_packet_length_) { | |
78 return; | |
79 } | |
80 | |
81 max_packet_length_ = length; | |
82 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_); | |
83 } | |
84 | |
85 void QuicPacketCreator::MaybeUpdatePacketNumberLength() { | |
86 DCHECK(!FLAGS_quic_simple_packet_number_length); | |
87 if (!queued_frames_.empty()) { | |
88 // Don't change creator state if there are frames queued. | |
89 return; | |
90 } | |
91 | |
92 // Update packet number length only on packet boundary. | |
93 packet_.packet_number_length = next_packet_number_length_; | |
94 } | |
95 | |
96 // Stops serializing version of the protocol in packets sent after this call. | |
97 // A packet that is already open might send kQuicVersionSize bytes less than the | |
98 // maximum packet size if we stop sending version before it is serialized. | |
99 void QuicPacketCreator::StopSendingVersion() { | |
100 DCHECK(send_version_in_packet_); | |
101 send_version_in_packet_ = false; | |
102 if (packet_size_ > 0) { | |
103 DCHECK_LT(kQuicVersionSize, packet_size_); | |
104 packet_size_ -= kQuicVersionSize; | |
105 } | |
106 } | |
107 | |
108 void QuicPacketCreator::SetDiversificationNonce( | |
109 const DiversificationNonce nonce) { | |
110 DCHECK(!have_diversification_nonce_); | |
111 have_diversification_nonce_ = true; | |
112 memcpy(&diversification_nonce_, nonce, sizeof(diversification_nonce_)); | |
113 } | |
114 | |
115 void QuicPacketCreator::UpdatePacketNumberLength( | |
116 QuicPacketNumber least_packet_awaited_by_peer, | |
117 QuicPacketCount max_packets_in_flight) { | |
118 if (FLAGS_quic_simple_packet_number_length && !queued_frames_.empty()) { | |
119 // Don't change creator state if there are frames queued. | |
120 QUIC_BUG << "Called UpdatePacketNumberLength with " << queued_frames_.size() | |
121 << " queued_frames. First frame type:" | |
122 << queued_frames_.front().type | |
123 << " last frame type:" << queued_frames_.back().type; | |
124 return; | |
125 } | |
126 | |
127 DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1); | |
128 const QuicPacketNumber current_delta = | |
129 packet_.packet_number + 1 - least_packet_awaited_by_peer; | |
130 const uint64_t delta = max(current_delta, max_packets_in_flight); | |
131 if (FLAGS_quic_simple_packet_number_length) { | |
132 packet_.packet_number_length = | |
133 QuicFramer::GetMinSequenceNumberLength(delta * 4); | |
134 } else { | |
135 next_packet_number_length_ = | |
136 QuicFramer::GetMinSequenceNumberLength(delta * 4); | |
137 } | |
138 } | |
139 | |
140 bool QuicPacketCreator::ConsumeData(QuicStreamId id, | |
141 QuicIOVector iov, | |
142 size_t iov_offset, | |
143 QuicStreamOffset offset, | |
144 bool fin, | |
145 bool needs_full_padding, | |
146 QuicFrame* frame) { | |
147 if (!HasRoomForStreamFrame(id, offset)) { | |
148 return false; | |
149 } | |
150 CreateStreamFrame(id, iov, iov_offset, offset, fin, frame); | |
151 // Explicitly disallow multi-packet CHLOs. | |
152 if (id == kCryptoStreamId && | |
153 frame->stream_frame->data_length >= sizeof(kCHLO) && | |
154 strncmp(frame->stream_frame->data_buffer, | |
155 reinterpret_cast<const char*>(&kCHLO), sizeof(kCHLO)) == 0) { | |
156 DCHECK_EQ(static_cast<size_t>(0), iov_offset); | |
157 if (frame->stream_frame->data_length < iov.iov->iov_len) { | |
158 const string error_details = "Client hello won't fit in a single packet."; | |
159 QUIC_BUG << error_details << " Constructed stream frame length: " | |
160 << frame->stream_frame->data_length | |
161 << " CHLO length: " << iov.iov->iov_len; | |
162 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details, | |
163 ConnectionCloseSource::FROM_SELF); | |
164 delete frame->stream_frame; | |
165 return false; | |
166 } | |
167 } | |
168 if (!AddFrame(*frame, /*save_retransmittable_frames=*/true)) { | |
169 // Fails if we try to write unencrypted stream data. | |
170 delete frame->stream_frame; | |
171 return false; | |
172 } | |
173 if (needs_full_padding) { | |
174 packet_.num_padding_bytes = -1; | |
175 } | |
176 return true; | |
177 } | |
178 | |
179 bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id, | |
180 QuicStreamOffset offset) { | |
181 return BytesFree() > QuicFramer::GetMinStreamFrameSize(id, offset, true); | |
182 } | |
183 | |
184 // static | |
185 size_t QuicPacketCreator::StreamFramePacketOverhead( | |
186 QuicVersion version, | |
187 QuicConnectionIdLength connection_id_length, | |
188 bool include_version, | |
189 bool include_path_id, | |
190 bool include_diversification_nonce, | |
191 QuicPacketNumberLength packet_number_length, | |
192 QuicStreamOffset offset) { | |
193 return GetPacketHeaderSize(version, connection_id_length, include_version, | |
194 include_path_id, include_diversification_nonce, | |
195 packet_number_length) + | |
196 // Assumes this is a stream with a single lone packet. | |
197 QuicFramer::GetMinStreamFrameSize(1u, offset, true); | |
198 } | |
199 | |
200 void QuicPacketCreator::CreateStreamFrame(QuicStreamId id, | |
201 QuicIOVector iov, | |
202 size_t iov_offset, | |
203 QuicStreamOffset offset, | |
204 bool fin, | |
205 QuicFrame* frame) { | |
206 DCHECK_GT(max_packet_length_, | |
207 StreamFramePacketOverhead(framer_->version(), connection_id_length_, | |
208 kIncludeVersion, kIncludePathId, | |
209 IncludeNonceInPublicHeader(), | |
210 PACKET_6BYTE_PACKET_NUMBER, offset)); | |
211 | |
212 if (!FLAGS_quic_simple_packet_number_length) { | |
213 MaybeUpdatePacketNumberLength(); | |
214 } | |
215 QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset)) | |
216 << "No room for Stream frame, BytesFree: " << BytesFree() | |
217 << " MinStreamFrameSize: " | |
218 << QuicFramer::GetMinStreamFrameSize(id, offset, true); | |
219 | |
220 if (iov_offset == iov.total_length) { | |
221 QUIC_BUG_IF(!fin) << "Creating a stream frame with no data or fin."; | |
222 // Create a new packet for the fin, if necessary. | |
223 *frame = QuicFrame(new QuicStreamFrame(id, true, offset, StringPiece())); | |
224 return; | |
225 } | |
226 | |
227 const size_t data_size = iov.total_length - iov_offset; | |
228 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( | |
229 id, offset, /* last_frame_in_packet= */ true); | |
230 size_t bytes_consumed = min<size_t>(BytesFree() - min_frame_size, data_size); | |
231 | |
232 bool set_fin = fin && bytes_consumed == data_size; // Last frame. | |
233 UniqueStreamBuffer buffer = | |
234 NewStreamBuffer(buffer_allocator_, bytes_consumed); | |
235 CopyToBuffer(iov, iov_offset, bytes_consumed, buffer.get()); | |
236 *frame = QuicFrame(new QuicStreamFrame(id, set_fin, offset, bytes_consumed, | |
237 std::move(buffer))); | |
238 } | |
239 | |
240 // static | |
241 void QuicPacketCreator::CopyToBuffer(QuicIOVector iov, | |
242 size_t iov_offset, | |
243 size_t length, | |
244 char* buffer) { | |
245 int iovnum = 0; | |
246 while (iovnum < iov.iov_count && iov_offset >= iov.iov[iovnum].iov_len) { | |
247 iov_offset -= iov.iov[iovnum].iov_len; | |
248 ++iovnum; | |
249 } | |
250 DCHECK_LE(iovnum, iov.iov_count); | |
251 DCHECK_LE(iov_offset, iov.iov[iovnum].iov_len); | |
252 if (iovnum >= iov.iov_count || length == 0) { | |
253 return; | |
254 } | |
255 | |
256 // Unroll the first iteration that handles iov_offset. | |
257 const size_t iov_available = iov.iov[iovnum].iov_len - iov_offset; | |
258 size_t copy_len = min(length, iov_available); | |
259 | |
260 // Try to prefetch the next iov if there is at least one more after the | |
261 // current. Otherwise, it looks like an irregular access that the hardware | |
262 // prefetcher won't speculatively prefetch. Only prefetch one iov because | |
263 // generally, the iov_offset is not 0, input iov consists of 2K buffers and | |
264 // the output buffer is ~1.4K. | |
265 if (copy_len == iov_available && iovnum + 1 < iov.iov_count) { | |
266 // TODO(ckrasic) - this is unused without prefetch() | |
267 // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base); | |
268 // char* next_base = static_cast<char*>(iov.iov[iovnum + 1].iov_base); | |
269 // Prefetch 2 cachelines worth of data to get the prefetcher started; leave | |
270 // it to the hardware prefetcher after that. | |
271 // TODO(ckrasic) - investigate what to do about prefetch directives. | |
272 // prefetch(next_base, PREFETCH_HINT_T0); | |
273 if (iov.iov[iovnum + 1].iov_len >= 64) { | |
274 // TODO(ckrasic) - investigate what to do about prefetch directives. | |
275 // prefetch(next_base + CACHELINE_SIZE, PREFETCH_HINT_T0); | |
276 } | |
277 } | |
278 | |
279 const char* src = static_cast<char*>(iov.iov[iovnum].iov_base) + iov_offset; | |
280 while (true) { | |
281 memcpy(buffer, src, copy_len); | |
282 length -= copy_len; | |
283 buffer += copy_len; | |
284 if (length == 0 || ++iovnum >= iov.iov_count) { | |
285 break; | |
286 } | |
287 src = static_cast<char*>(iov.iov[iovnum].iov_base); | |
288 copy_len = min(length, iov.iov[iovnum].iov_len); | |
289 } | |
290 QUIC_BUG_IF(length > 0) << "Failed to copy entire length to buffer."; | |
291 } | |
292 | |
293 void QuicPacketCreator::ReserializeAllFrames( | |
294 const PendingRetransmission& retransmission, | |
295 char* buffer, | |
296 size_t buffer_len) { | |
297 DCHECK(queued_frames_.empty()); | |
298 DCHECK_EQ(0, packet_.num_padding_bytes); | |
299 QUIC_BUG_IF(retransmission.retransmittable_frames.empty()) | |
300 << "Attempt to serialize empty packet"; | |
301 const QuicPacketNumberLength saved_length = packet_.packet_number_length; | |
302 const QuicPacketNumberLength saved_next_length = next_packet_number_length_; | |
303 const EncryptionLevel default_encryption_level = packet_.encryption_level; | |
304 | |
305 // Temporarily set the packet number length and change the encryption level. | |
306 packet_.packet_number_length = retransmission.packet_number_length; | |
307 if (!FLAGS_quic_simple_packet_number_length) { | |
308 next_packet_number_length_ = retransmission.packet_number_length; | |
309 } | |
310 packet_.num_padding_bytes = retransmission.num_padding_bytes; | |
311 // Only preserve the original encryption level if it's a handshake packet or | |
312 // if we haven't gone forward secure. | |
313 if (retransmission.has_crypto_handshake || | |
314 packet_.encryption_level != ENCRYPTION_FORWARD_SECURE) { | |
315 packet_.encryption_level = retransmission.encryption_level; | |
316 } | |
317 | |
318 // Serialize the packet and restore packet number length state. | |
319 for (const QuicFrame& frame : retransmission.retransmittable_frames) { | |
320 bool success = AddFrame(frame, false); | |
321 LOG_IF(DFATAL, !success) | |
322 << " Failed to add frame of type:" << frame.type | |
323 << " num_frames:" << retransmission.retransmittable_frames.size() | |
324 << " retransmission.packet_number_length:" | |
325 << retransmission.packet_number_length | |
326 << " packet_.packet_number_length:" << packet_.packet_number_length; | |
327 } | |
328 SerializePacket(buffer, buffer_len); | |
329 packet_.original_path_id = retransmission.path_id; | |
330 packet_.original_packet_number = retransmission.packet_number; | |
331 packet_.transmission_type = retransmission.transmission_type; | |
332 OnSerializedPacket(); | |
333 // Restore old values. | |
334 if (!FLAGS_quic_simple_packet_number_length) { | |
335 // OnSerializedPacket updates the packet_number_length, so it's incorrect to | |
336 // restore it here. | |
337 packet_.packet_number_length = saved_length; | |
338 next_packet_number_length_ = saved_next_length; | |
339 } | |
340 packet_.encryption_level = default_encryption_level; | |
341 } | |
342 | |
343 void QuicPacketCreator::Flush() { | |
344 if (!HasPendingFrames()) { | |
345 return; | |
346 } | |
347 | |
348 // TODO(rtenneti): Change the default 64 alignas value (used the default | |
349 // value from CACHELINE_SIZE). | |
350 ALIGNAS(64) char seralized_packet_buffer[kMaxPacketSize]; | |
351 SerializePacket(seralized_packet_buffer, kMaxPacketSize); | |
352 OnSerializedPacket(); | |
353 } | |
354 | |
355 void QuicPacketCreator::OnSerializedPacket() { | |
356 if (packet_.encrypted_buffer == nullptr) { | |
357 const string error_details = "Failed to SerializePacket."; | |
358 QUIC_BUG << error_details; | |
359 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET, | |
360 error_details, | |
361 ConnectionCloseSource::FROM_SELF); | |
362 return; | |
363 } | |
364 | |
365 delegate_->OnSerializedPacket(&packet_); | |
366 ClearPacket(); | |
367 // Maximum packet size may be only enacted while no packet is currently being | |
368 // constructed, so here we have a good opportunity to actually change it. | |
369 if (CanSetMaxPacketLength()) { | |
370 SetMaxPacketLength(max_packet_length_); | |
371 } | |
372 } | |
373 | |
374 void QuicPacketCreator::ClearPacket() { | |
375 packet_.has_ack = false; | |
376 packet_.has_stop_waiting = false; | |
377 packet_.has_crypto_handshake = NOT_HANDSHAKE; | |
378 packet_.num_padding_bytes = 0; | |
379 packet_.original_path_id = kInvalidPathId; | |
380 packet_.original_packet_number = 0; | |
381 packet_.transmission_type = NOT_RETRANSMISSION; | |
382 packet_.encrypted_buffer = nullptr; | |
383 packet_.encrypted_length = 0; | |
384 DCHECK(packet_.retransmittable_frames.empty()); | |
385 packet_.listeners.clear(); | |
386 } | |
387 | |
388 void QuicPacketCreator::CreateAndSerializeStreamFrame( | |
389 QuicStreamId id, | |
390 const QuicIOVector& iov, | |
391 QuicStreamOffset iov_offset, | |
392 QuicStreamOffset stream_offset, | |
393 bool fin, | |
394 QuicAckListenerInterface* listener, | |
395 char* encrypted_buffer, | |
396 size_t encrypted_buffer_len, | |
397 size_t* num_bytes_consumed) { | |
398 DCHECK(queued_frames_.empty()); | |
399 // Write out the packet header | |
400 QuicPacketHeader header; | |
401 FillPacketHeader(&header); | |
402 QuicDataWriter writer(kMaxPacketSize, encrypted_buffer); | |
403 if (!framer_->AppendPacketHeader(header, &writer)) { | |
404 QUIC_BUG << "AppendPacketHeader failed"; | |
405 return; | |
406 } | |
407 | |
408 // Create a Stream frame with the remaining space. | |
409 QUIC_BUG_IF(iov_offset == iov.total_length && !fin) | |
410 << "Creating a stream frame with no data or fin."; | |
411 const size_t remaining_data_size = iov.total_length - iov_offset; | |
412 const size_t min_frame_size = QuicFramer::GetMinStreamFrameSize( | |
413 id, stream_offset, /* last_frame_in_packet= */ true); | |
414 const size_t available_size = | |
415 max_plaintext_size_ - writer.length() - min_frame_size; | |
416 const size_t bytes_consumed = | |
417 min<size_t>(available_size, remaining_data_size); | |
418 | |
419 const bool set_fin = fin && (bytes_consumed == remaining_data_size); | |
420 UniqueStreamBuffer stream_buffer = | |
421 NewStreamBuffer(buffer_allocator_, bytes_consumed); | |
422 CopyToBuffer(iov, iov_offset, bytes_consumed, stream_buffer.get()); | |
423 std::unique_ptr<QuicStreamFrame> frame(new QuicStreamFrame( | |
424 id, set_fin, stream_offset, bytes_consumed, std::move(stream_buffer))); | |
425 | |
426 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized | |
427 // into one method that takes a QuicStreamFrame, if warranted. | |
428 if (!framer_->AppendTypeByte(QuicFrame(frame.get()), | |
429 /* no stream frame length */ true, &writer)) { | |
430 QUIC_BUG << "AppendTypeByte failed"; | |
431 return; | |
432 } | |
433 if (!framer_->AppendStreamFrame(*frame, /* no stream frame length */ true, | |
434 &writer)) { | |
435 QUIC_BUG << "AppendStreamFrame failed"; | |
436 return; | |
437 } | |
438 | |
439 size_t encrypted_length = framer_->EncryptInPlace( | |
440 packet_.encryption_level, packet_.path_id, packet_.packet_number, | |
441 GetStartOfEncryptedData(framer_->version(), header), writer.length(), | |
442 encrypted_buffer_len, encrypted_buffer); | |
443 if (encrypted_length == 0) { | |
444 QUIC_BUG << "Failed to encrypt packet number " << header.packet_number; | |
445 return; | |
446 } | |
447 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be | |
448 // unioned with a QuicStreamFrame and a UniqueStreamBuffer. | |
449 *num_bytes_consumed = bytes_consumed; | |
450 packet_size_ = 0; | |
451 packet_.entropy_hash = QuicFramer::GetPacketEntropyHash(header); | |
452 packet_.encrypted_buffer = encrypted_buffer; | |
453 packet_.encrypted_length = encrypted_length; | |
454 if (listener != nullptr) { | |
455 packet_.listeners.emplace_back(listener, bytes_consumed); | |
456 } | |
457 packet_.retransmittable_frames.push_back(QuicFrame(frame.release())); | |
458 OnSerializedPacket(); | |
459 } | |
460 | |
461 bool QuicPacketCreator::HasPendingFrames() const { | |
462 return !queued_frames_.empty(); | |
463 } | |
464 | |
465 bool QuicPacketCreator::HasPendingRetransmittableFrames() const { | |
466 return !packet_.retransmittable_frames.empty(); | |
467 } | |
468 | |
469 size_t QuicPacketCreator::ExpansionOnNewFrame() const { | |
470 // If the last frame in the packet is a stream frame, then it will expand to | |
471 // include the stream_length field when a new frame is added. | |
472 bool has_trailing_stream_frame = | |
473 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME; | |
474 return has_trailing_stream_frame ? kQuicStreamPayloadLengthSize : 0; | |
475 } | |
476 | |
477 size_t QuicPacketCreator::BytesFree() { | |
478 DCHECK_GE(max_plaintext_size_, PacketSize()); | |
479 return max_plaintext_size_ - | |
480 min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame()); | |
481 } | |
482 | |
483 size_t QuicPacketCreator::PacketSize() { | |
484 if (!queued_frames_.empty()) { | |
485 return packet_size_; | |
486 } | |
487 // Update packet number length on packet boundary. | |
488 if (!FLAGS_quic_simple_packet_number_length) { | |
489 packet_.packet_number_length = next_packet_number_length_; | |
490 } | |
491 packet_size_ = GetPacketHeaderSize( | |
492 framer_->version(), connection_id_length_, send_version_in_packet_, | |
493 send_path_id_in_packet_, IncludeNonceInPublicHeader(), | |
494 packet_.packet_number_length); | |
495 return packet_size_; | |
496 } | |
497 | |
498 bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame) { | |
499 return AddFrame(frame, /*save_retransmittable_frames=*/true); | |
500 } | |
501 | |
502 bool QuicPacketCreator::AddPaddedSavedFrame(const QuicFrame& frame) { | |
503 if (AddFrame(frame, /*save_retransmittable_frames=*/true)) { | |
504 packet_.num_padding_bytes = -1; | |
505 return true; | |
506 } | |
507 return false; | |
508 } | |
509 | |
510 void QuicPacketCreator::AddAckListener(QuicAckListenerInterface* listener, | |
511 QuicPacketLength length) { | |
512 DCHECK(!queued_frames_.empty()); | |
513 packet_.listeners.emplace_back(listener, length); | |
514 } | |
515 | |
516 void QuicPacketCreator::SerializePacket(char* encrypted_buffer, | |
517 size_t encrypted_buffer_len) { | |
518 DCHECK_LT(0u, encrypted_buffer_len); | |
519 QUIC_BUG_IF(queued_frames_.empty()) << "Attempt to serialize empty packet"; | |
520 QuicPacketHeader header; | |
521 // FillPacketHeader increments packet_number_. | |
522 FillPacketHeader(&header); | |
523 | |
524 MaybeAddPadding(); | |
525 | |
526 DCHECK_GE(max_plaintext_size_, packet_size_); | |
527 // Use the packet_size_ instead of the buffer size to ensure smaller | |
528 // packet sizes are properly used. | |
529 size_t length = framer_->BuildDataPacket(header, queued_frames_, | |
530 encrypted_buffer, packet_size_); | |
531 if (length == 0) { | |
532 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames."; | |
533 return; | |
534 } | |
535 | |
536 // ACK Frames will be truncated due to length only if they're the only frame | |
537 // in the packet, and if packet_size_ was set to max_plaintext_size_. If | |
538 // truncation due to length occurred, then GetSerializedFrameLength will have | |
539 // returned all bytes free. | |
540 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ && | |
541 queued_frames_.size() == 1 && | |
542 queued_frames_.back().type == ACK_FRAME; | |
543 // Because of possible truncation, we can't be confident that our | |
544 // packet size calculation worked correctly. | |
545 if (!possibly_truncated_by_length) { | |
546 DCHECK_EQ(packet_size_, length); | |
547 } | |
548 const size_t encrypted_length = framer_->EncryptInPlace( | |
549 packet_.encryption_level, packet_.path_id, packet_.packet_number, | |
550 GetStartOfEncryptedData(framer_->version(), header), length, | |
551 encrypted_buffer_len, encrypted_buffer); | |
552 if (encrypted_length == 0) { | |
553 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number; | |
554 return; | |
555 } | |
556 | |
557 packet_size_ = 0; | |
558 queued_frames_.clear(); | |
559 packet_.entropy_hash = QuicFramer::GetPacketEntropyHash(header); | |
560 packet_.encrypted_buffer = encrypted_buffer; | |
561 packet_.encrypted_length = encrypted_length; | |
562 } | |
563 | |
564 QuicEncryptedPacket* QuicPacketCreator::SerializeVersionNegotiationPacket( | |
565 const QuicVersionVector& supported_versions) { | |
566 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); | |
567 QuicEncryptedPacket* encrypted = QuicFramer::BuildVersionNegotiationPacket( | |
568 connection_id_, supported_versions); | |
569 DCHECK(encrypted); | |
570 DCHECK_GE(max_packet_length_, encrypted->length()); | |
571 return encrypted; | |
572 } | |
573 | |
574 // TODO(jri): Make this a public method of framer? | |
575 SerializedPacket QuicPacketCreator::NoPacket() { | |
576 return SerializedPacket(kInvalidPathId, 0, PACKET_1BYTE_PACKET_NUMBER, | |
577 nullptr, 0, 0, false, false); | |
578 } | |
579 | |
580 void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) { | |
581 header->public_header.connection_id = connection_id_; | |
582 header->public_header.connection_id_length = connection_id_length_; | |
583 header->public_header.multipath_flag = send_path_id_in_packet_; | |
584 header->public_header.reset_flag = false; | |
585 header->public_header.version_flag = send_version_in_packet_; | |
586 if (IncludeNonceInPublicHeader()) { | |
587 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective()); | |
588 header->public_header.nonce = &diversification_nonce_; | |
589 } else { | |
590 header->public_header.nonce = nullptr; | |
591 } | |
592 header->path_id = packet_.path_id; | |
593 header->packet_number = ++packet_.packet_number; | |
594 header->public_header.packet_number_length = packet_.packet_number_length; | |
595 header->entropy_flag = random_bool_source_.RandBool(); | |
596 } | |
597 | |
598 bool QuicPacketCreator::ShouldRetransmit(const QuicFrame& frame) { | |
599 switch (frame.type) { | |
600 case ACK_FRAME: | |
601 case PADDING_FRAME: | |
602 case STOP_WAITING_FRAME: | |
603 case MTU_DISCOVERY_FRAME: | |
604 return false; | |
605 default: | |
606 return true; | |
607 } | |
608 } | |
609 | |
610 bool QuicPacketCreator::AddFrame(const QuicFrame& frame, | |
611 bool save_retransmittable_frames) { | |
612 DVLOG(1) << "Adding frame: " << frame; | |
613 if (FLAGS_quic_never_write_unencrypted_data && frame.type == STREAM_FRAME && | |
614 frame.stream_frame->stream_id != kCryptoStreamId && | |
615 packet_.encryption_level == ENCRYPTION_NONE) { | |
616 const string error_details = "Cannot send stream data without encryption."; | |
617 QUIC_BUG << error_details; | |
618 delegate_->OnUnrecoverableError( | |
619 QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, error_details, | |
620 ConnectionCloseSource::FROM_SELF); | |
621 return false; | |
622 } | |
623 if (!FLAGS_quic_simple_packet_number_length) { | |
624 MaybeUpdatePacketNumberLength(); | |
625 } | |
626 size_t frame_len = framer_->GetSerializedFrameLength( | |
627 frame, BytesFree(), queued_frames_.empty(), true, | |
628 packet_.packet_number_length); | |
629 if (frame_len == 0) { | |
630 // Current open packet is full. | |
631 Flush(); | |
632 return false; | |
633 } | |
634 DCHECK_LT(0u, packet_size_); | |
635 packet_size_ += ExpansionOnNewFrame() + frame_len; | |
636 | |
637 if (save_retransmittable_frames && ShouldRetransmit(frame)) { | |
638 if (packet_.retransmittable_frames.empty()) { | |
639 packet_.retransmittable_frames.reserve(2); | |
640 } | |
641 packet_.retransmittable_frames.push_back(frame); | |
642 queued_frames_.push_back(frame); | |
643 if (frame.type == STREAM_FRAME && | |
644 frame.stream_frame->stream_id == kCryptoStreamId) { | |
645 packet_.has_crypto_handshake = IS_HANDSHAKE; | |
646 } | |
647 } else { | |
648 queued_frames_.push_back(frame); | |
649 } | |
650 | |
651 if (frame.type == ACK_FRAME) { | |
652 packet_.has_ack = true; | |
653 } | |
654 if (frame.type == STOP_WAITING_FRAME) { | |
655 packet_.has_stop_waiting = true; | |
656 } | |
657 if (debug_delegate_ != nullptr) { | |
658 debug_delegate_->OnFrameAddedToPacket(frame); | |
659 } | |
660 | |
661 return true; | |
662 } | |
663 | |
664 void QuicPacketCreator::MaybeAddPadding() { | |
665 if (packet_.num_padding_bytes == 0) { | |
666 return; | |
667 } | |
668 | |
669 if (BytesFree() == 0) { | |
670 // Don't pad full packets. | |
671 return; | |
672 } | |
673 | |
674 bool success = | |
675 AddFrame(QuicFrame(QuicPaddingFrame(packet_.num_padding_bytes)), false); | |
676 DCHECK(success); | |
677 } | |
678 | |
679 void QuicPacketCreator::SetCurrentPath( | |
680 QuicPathId path_id, | |
681 QuicPacketNumber least_packet_awaited_by_peer, | |
682 QuicPacketCount max_packets_in_flight) { | |
683 if (packet_.path_id == path_id) { | |
684 return; | |
685 } | |
686 | |
687 if (HasPendingFrames()) { | |
688 QUIC_BUG << "Unable to change paths when a packet is under construction."; | |
689 return; | |
690 } | |
691 // Save current packet number and load switching path's packet number. | |
692 multipath_packet_number_[packet_.path_id] = packet_.packet_number; | |
693 std::unordered_map<QuicPathId, QuicPacketNumber>::iterator it = | |
694 multipath_packet_number_.find(path_id); | |
695 // If path_id is not in the map, it's a new path. Set packet_number to 0. | |
696 packet_.packet_number = it == multipath_packet_number_.end() ? 0 : it->second; | |
697 packet_.path_id = path_id; | |
698 DCHECK(packet_.path_id != kInvalidPathId); | |
699 // Send path in packet if current path is not the default path. | |
700 send_path_id_in_packet_ = packet_.path_id != kDefaultPathId ? true : false; | |
701 // Switching path needs to update packet number length. | |
702 UpdatePacketNumberLength(least_packet_awaited_by_peer, max_packets_in_flight); | |
703 } | |
704 | |
705 bool QuicPacketCreator::IncludeNonceInPublicHeader() { | |
706 return have_diversification_nonce_ && | |
707 packet_.encryption_level == ENCRYPTION_INITIAL; | |
708 } | |
709 | |
710 QuicPacketCreator::QuicRandomBoolSource::QuicRandomBoolSource( | |
711 QuicRandom* random) | |
712 : random_(random), bit_bucket_(0), bit_mask_(0) {} | |
713 | |
714 QuicPacketCreator::QuicRandomBoolSource::~QuicRandomBoolSource() {} | |
715 | |
716 bool QuicPacketCreator::QuicRandomBoolSource::RandBool() { | |
717 if (bit_mask_ == 0) { | |
718 bit_bucket_ = random_->RandUint64(); | |
719 bit_mask_ = 1; | |
720 } | |
721 bool result = ((bit_bucket_ & bit_mask_) != 0); | |
722 bit_mask_ <<= 1; | |
723 return result; | |
724 } | |
725 | |
726 } // namespace net | |
OLD | NEW |