Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: net/quic/quic_packet_creator.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/quic_packet_creator.h ('k') | net/quic/quic_packet_creator_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « net/quic/quic_packet_creator.h ('k') | net/quic/quic_packet_creator_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698