blob: 70d5ccb045906eafac451373325e857526c256a2 [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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/third_party/quiche/src/quic/core/quic_packet_creator.h"
6
7#include <algorithm>
8#include <cstdint>
vasilvv872e7a32019-03-12 16:42:44 -07009#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -050010
QUICHE teama6ef0a62019-03-07 20:34:33 -050011#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
12#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
ianswettb239f862019-04-05 09:15:06 -070013#include "net/third_party/quiche/src/quic/core/quic_constants.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050014#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
15#include "net/third_party/quiche/src/quic/core/quic_types.h"
16#include "net/third_party/quiche/src/quic/core/quic_utils.h"
ianswettb239f862019-04-05 09:15:06 -070017#include "net/third_party/quiche/src/quic/core/quic_versions.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018#include "net/third_party/quiche/src/quic/platform/api/quic_aligned.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_arraysize.h"
20#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
21#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
22#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
23#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
24#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
bnc2c2444e2019-05-03 08:18:23 -070025#include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050026#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
27#include "net/third_party/quiche/src/quic/platform/api/quic_text_utils.h"
28
29namespace quic {
30namespace {
31
32QuicLongHeaderType EncryptionlevelToLongHeaderType(EncryptionLevel level) {
33 switch (level) {
QUICHE team6987b4a2019-03-15 16:23:04 -070034 case ENCRYPTION_INITIAL:
QUICHE teama6ef0a62019-03-07 20:34:33 -050035 return INITIAL;
QUICHE team88ea0082019-03-15 10:05:26 -070036 case ENCRYPTION_HANDSHAKE:
37 return HANDSHAKE;
QUICHE teama6ef0a62019-03-07 20:34:33 -050038 case ENCRYPTION_ZERO_RTT:
39 return ZERO_RTT_PROTECTED;
40 case ENCRYPTION_FORWARD_SECURE:
41 QUIC_BUG
42 << "Try to derive long header type for packet with encryption level: "
43 << QuicUtils::EncryptionLevelToString(level);
44 return INVALID_PACKET_TYPE;
45 default:
46 QUIC_BUG << QuicUtils::EncryptionLevelToString(level);
47 return INVALID_PACKET_TYPE;
48 }
49}
50
51} // namespace
52
53#define ENDPOINT \
54 (framer_->perspective() == Perspective::IS_SERVER ? "Server: " : "Client: ")
55
dschinazi7b9278c2019-05-20 07:36:21 -070056QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050057 QuicFramer* framer,
58 DelegateInterface* delegate)
dschinazi7b9278c2019-05-20 07:36:21 -070059 : QuicPacketCreator(server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050060 framer,
61 QuicRandom::GetInstance(),
62 delegate) {}
63
dschinazi7b9278c2019-05-20 07:36:21 -070064QuicPacketCreator::QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050065 QuicFramer* framer,
66 QuicRandom* random,
67 DelegateInterface* delegate)
68 : delegate_(delegate),
69 debug_delegate_(nullptr),
70 framer_(framer),
71 random_(random),
72 send_version_in_packet_(framer->perspective() == Perspective::IS_CLIENT),
73 have_diversification_nonce_(false),
74 max_packet_length_(0),
dschinazi7b9278c2019-05-20 07:36:21 -070075 server_connection_id_included_(CONNECTION_ID_PRESENT),
QUICHE teama6ef0a62019-03-07 20:34:33 -050076 packet_size_(0),
dschinazi7b9278c2019-05-20 07:36:21 -070077 server_connection_id_(server_connection_id),
dschinazi346b7ce2019-06-05 01:38:18 -070078 client_connection_id_(EmptyQuicConnectionId()),
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 packet_(QuicPacketNumber(),
80 PACKET_1BYTE_PACKET_NUMBER,
81 nullptr,
82 0,
83 false,
84 false),
85 pending_padding_bytes_(0),
86 needs_full_padding_(false),
nharperd43f1d62019-07-01 15:18:20 -070087 can_set_transmission_type_(false),
88 fix_get_packet_header_size_(
89 GetQuicReloadableFlag(quic_fix_get_packet_header_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050090 SetMaxPacketLength(kDefaultMaxPacketSize);
91}
92
93QuicPacketCreator::~QuicPacketCreator() {
94 DeleteFrames(&packet_.retransmittable_frames);
95}
96
97void QuicPacketCreator::SetEncrypter(EncryptionLevel level,
98 std::unique_ptr<QuicEncrypter> encrypter) {
99 framer_->SetEncrypter(level, std::move(encrypter));
100 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
101}
102
103bool QuicPacketCreator::CanSetMaxPacketLength() const {
104 // |max_packet_length_| should not be changed mid-packet.
105 return queued_frames_.empty();
106}
107
108void QuicPacketCreator::SetMaxPacketLength(QuicByteCount length) {
109 DCHECK(CanSetMaxPacketLength());
110
111 // Avoid recomputing |max_plaintext_size_| if the length does not actually
112 // change.
113 if (length == max_packet_length_) {
114 return;
115 }
116
117 max_packet_length_ = length;
118 max_plaintext_size_ = framer_->GetMaxPlaintextSize(max_packet_length_);
nharper55fa6132019-05-07 19:37:21 -0700119 QUIC_BUG_IF(max_plaintext_size_ - PacketHeaderSize() <
QUICHE team2252b702019-05-14 23:55:14 -0400120 MinPlaintextPacketSize(framer_->version()))
nharper55fa6132019-05-07 19:37:21 -0700121 << "Attempted to set max packet length too small";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500122}
123
124// Stops serializing version of the protocol in packets sent after this call.
125// A packet that is already open might send kQuicVersionSize bytes less than the
126// maximum packet size if we stop sending version before it is serialized.
127void QuicPacketCreator::StopSendingVersion() {
128 DCHECK(send_version_in_packet_);
fayangd4291e42019-05-30 10:31:21 -0700129 DCHECK(!VersionHasIetfInvariantHeader(framer_->transport_version()));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500130 send_version_in_packet_ = false;
131 if (packet_size_ > 0) {
132 DCHECK_LT(kQuicVersionSize, packet_size_);
133 packet_size_ -= kQuicVersionSize;
134 }
135}
136
137void QuicPacketCreator::SetDiversificationNonce(
138 const DiversificationNonce& nonce) {
139 DCHECK(!have_diversification_nonce_);
140 have_diversification_nonce_ = true;
141 diversification_nonce_ = nonce;
142}
143
144void QuicPacketCreator::UpdatePacketNumberLength(
145 QuicPacketNumber least_packet_awaited_by_peer,
146 QuicPacketCount max_packets_in_flight) {
147 if (!queued_frames_.empty()) {
148 // Don't change creator state if there are frames queued.
149 QUIC_BUG << "Called UpdatePacketNumberLength with " << queued_frames_.size()
150 << " queued_frames. First frame type:"
151 << queued_frames_.front().type
152 << " last frame type:" << queued_frames_.back().type;
153 return;
154 }
155
156 DCHECK_LE(least_packet_awaited_by_peer, packet_.packet_number + 1);
157 const uint64_t current_delta =
158 packet_.packet_number + 1 - least_packet_awaited_by_peer;
159 const uint64_t delta = std::max(current_delta, max_packets_in_flight);
160 packet_.packet_number_length = QuicFramer::GetMinPacketNumberLength(
161 framer_->transport_version(), QuicPacketNumber(delta * 4));
162}
163
164bool QuicPacketCreator::ConsumeCryptoData(EncryptionLevel level,
165 size_t write_length,
166 QuicStreamOffset offset,
nharper51961cf2019-05-13 13:23:24 -0700167 bool needs_full_padding,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500168 TransmissionType transmission_type,
169 QuicFrame* frame) {
170 if (!CreateCryptoFrame(level, write_length, offset, frame)) {
171 return false;
172 }
173 // When crypto data was sent in stream frames, ConsumeData is called with
174 // |needs_full_padding = true|. Keep the same behavior here when sending
175 // crypto frames.
176 //
177 // TODO(nharper): Check what the IETF drafts say about padding out initial
178 // messages and change this as appropriate.
nharper51961cf2019-05-13 13:23:24 -0700179 if (needs_full_padding) {
180 needs_full_padding_ = true;
181 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500182 return AddFrame(*frame, /*save_retransmittable_frames*/ true,
183 transmission_type);
184}
185
186bool QuicPacketCreator::ConsumeData(QuicStreamId id,
ianswette28f0222019-04-04 13:31:22 -0700187 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188 QuicStreamOffset offset,
189 bool fin,
190 bool needs_full_padding,
191 TransmissionType transmission_type,
192 QuicFrame* frame) {
QUICHE teamf08778a2019-03-14 08:10:26 -0700193 if (!HasRoomForStreamFrame(id, offset, data_size)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500194 return false;
195 }
QUICHE teamf08778a2019-03-14 08:10:26 -0700196 CreateStreamFrame(id, data_size, offset, fin, frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500197 // Explicitly disallow multi-packet CHLOs.
danzh88e3e052019-06-13 11:47:18 -0700198 if (GetQuicFlag(FLAGS_quic_enforce_single_packet_chlo) &&
ianswette28f0222019-04-04 13:31:22 -0700199 StreamFrameIsClientHello(frame->stream_frame) &&
200 frame->stream_frame.data_length < data_size) {
vasilvvc48c8712019-03-11 13:38:16 -0700201 const std::string error_details =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500202 "Client hello won't fit in a single packet.";
203 QUIC_BUG << error_details << " Constructed stream frame length: "
204 << frame->stream_frame.data_length
ianswette28f0222019-04-04 13:31:22 -0700205 << " CHLO length: " << data_size;
fkastenholz85f18902019-05-28 12:47:00 -0700206 delegate_->OnUnrecoverableError(QUIC_CRYPTO_CHLO_TOO_LARGE, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500207 return false;
208 }
209 if (!AddFrame(*frame, /*save_retransmittable_frames=*/true,
210 transmission_type)) {
211 // Fails if we try to write unencrypted stream data.
212 return false;
213 }
214 if (needs_full_padding) {
215 needs_full_padding_ = true;
216 }
217
218 return true;
219}
220
221bool QuicPacketCreator::HasRoomForStreamFrame(QuicStreamId id,
222 QuicStreamOffset offset,
223 size_t data_size) {
224 return BytesFree() >
225 QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
226 offset, true, data_size);
227}
228
229bool QuicPacketCreator::HasRoomForMessageFrame(QuicByteCount length) {
230 return BytesFree() >= QuicFramer::GetMessageFrameSize(
231 framer_->transport_version(), true, length);
232}
233
234// TODO(fkastenholz): this method should not use constant values for
235// the last-frame-in-packet and data-length parameters to
236// GetMinStreamFrameSize. Proper values should be plumbed in from
237// higher up. This was left this way for now for a few reasons. First,
238// higher up calls to StreamFramePacketOverhead() do not always know
239// this information, leading to a cascade of changes and B) the
240// higher-up software does not always loop, calling
241// StreamFramePacketOverhead() once for every packet -- eg there is
242// a test in quic_connection_test that calls it once and assumes that
243// the value is the same for all packets.
244
245// static
246size_t QuicPacketCreator::StreamFramePacketOverhead(
247 QuicTransportVersion version,
248 QuicConnectionIdLength destination_connection_id_length,
249 QuicConnectionIdLength source_connection_id_length,
250 bool include_version,
251 bool include_diversification_nonce,
252 QuicPacketNumberLength packet_number_length,
253 QuicVariableLengthIntegerLength retry_token_length_length,
254 QuicVariableLengthIntegerLength length_length,
255 QuicStreamOffset offset) {
256 return GetPacketHeaderSize(version, destination_connection_id_length,
257 source_connection_id_length, include_version,
258 include_diversification_nonce,
259 packet_number_length, retry_token_length_length, 0,
260 length_length) +
261
262 // Assumes this is a packet with a single stream frame in it. Since
263 // last_frame_in_packet is set true, the size of the length field is
264 // not included in the calculation. This is OK because in other places
265 // in the code, the logic adds back 2 (the size of the Google QUIC
266 // length) when a frame is not the last frame of the packet. This is
267 // also acceptable for IETF Quic; even though the length field could be
268 // 8 bytes long, in practice it will not be longer than 2 bytes (enough
269 // to encode 16K). A length that would be encoded in 2 bytes (0xfff)
270 // is passed just for cleanliness.
271 //
272 // TODO(fkastenholz): This is very hacky and feels brittle. Ideally we
273 // would calculate the correct lengths at the correct time, based on
274 // the state at that time/place.
275 QuicFramer::GetMinStreamFrameSize(version, 1u, offset, true,
dschinazi66dea072019-04-09 11:41:06 -0700276 kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500277}
278
279void QuicPacketCreator::CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700280 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500281 QuicStreamOffset offset,
282 bool fin,
283 QuicFrame* frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500284 DCHECK_GT(
285 max_packet_length_,
286 StreamFramePacketOverhead(
287 framer_->transport_version(), GetDestinationConnectionIdLength(),
288 GetSourceConnectionIdLength(), kIncludeVersion,
289 IncludeNonceInPublicHeader(), PACKET_6BYTE_PACKET_NUMBER,
290 GetRetryTokenLengthLength(), GetLengthLength(), offset));
291
292 QUIC_BUG_IF(!HasRoomForStreamFrame(id, offset, data_size))
293 << "No room for Stream frame, BytesFree: " << BytesFree()
294 << " MinStreamFrameSize: "
295 << QuicFramer::GetMinStreamFrameSize(framer_->transport_version(), id,
296 offset, true, data_size);
297
QUICHE teamf08778a2019-03-14 08:10:26 -0700298 QUIC_BUG_IF(data_size == 0 && !fin)
299 << "Creating a stream frame for stream ID:" << id
300 << " with no data or fin.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500301 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
302 framer_->transport_version(), id, offset,
303 /* last_frame_in_packet= */ true, data_size);
304 size_t bytes_consumed =
305 std::min<size_t>(BytesFree() - min_frame_size, data_size);
306
307 bool set_fin = fin && bytes_consumed == data_size; // Last frame.
308 *frame = QuicFrame(QuicStreamFrame(id, set_fin, offset, bytes_consumed));
309}
310
311bool QuicPacketCreator::CreateCryptoFrame(EncryptionLevel level,
312 size_t write_length,
313 QuicStreamOffset offset,
314 QuicFrame* frame) {
315 size_t min_frame_size =
316 QuicFramer::GetMinCryptoFrameSize(write_length, offset);
317 if (BytesFree() <= min_frame_size) {
318 return false;
319 }
320 size_t max_write_length = BytesFree() - min_frame_size;
321 size_t bytes_consumed = std::min<size_t>(max_write_length, write_length);
322 *frame = QuicFrame(new QuicCryptoFrame(level, offset, bytes_consumed));
323 return true;
324}
325
326void QuicPacketCreator::ReserializeAllFrames(
327 const QuicPendingRetransmission& retransmission,
328 char* buffer,
329 size_t buffer_len) {
330 DCHECK(queued_frames_.empty());
331 DCHECK_EQ(0, packet_.num_padding_bytes);
332 QUIC_BUG_IF(retransmission.retransmittable_frames.empty())
333 << "Attempt to serialize empty packet";
334 const EncryptionLevel default_encryption_level = packet_.encryption_level;
335
336 // Temporarily set the packet number length and change the encryption level.
337 packet_.packet_number_length = retransmission.packet_number_length;
338 if (retransmission.num_padding_bytes == -1) {
339 // Only retransmit padding when original packet needs full padding. Padding
340 // from pending_padding_bytes_ are not retransmitted.
341 needs_full_padding_ = true;
342 }
343 // Only preserve the original encryption level if it's a handshake packet or
344 // if we haven't gone forward secure.
345 if (retransmission.has_crypto_handshake ||
346 packet_.encryption_level != ENCRYPTION_FORWARD_SECURE) {
347 packet_.encryption_level = retransmission.encryption_level;
348 }
349
350 // Serialize the packet and restore packet number length state.
351 for (const QuicFrame& frame : retransmission.retransmittable_frames) {
352 bool success = AddFrame(frame, false, retransmission.transmission_type);
353 QUIC_BUG_IF(!success) << " Failed to add frame of type:" << frame.type
354 << " num_frames:"
355 << retransmission.retransmittable_frames.size()
356 << " retransmission.packet_number_length:"
357 << retransmission.packet_number_length
358 << " packet_.packet_number_length:"
359 << packet_.packet_number_length;
360 }
361 packet_.transmission_type = retransmission.transmission_type;
362 SerializePacket(buffer, buffer_len);
363 packet_.original_packet_number = retransmission.packet_number;
364 OnSerializedPacket();
365 // Restore old values.
366 packet_.encryption_level = default_encryption_level;
367}
368
369void QuicPacketCreator::Flush() {
370 if (!HasPendingFrames() && pending_padding_bytes_ == 0) {
371 return;
372 }
373
dschinazi66dea072019-04-09 11:41:06 -0700374 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500375 char* serialized_packet_buffer = delegate_->GetPacketBuffer();
376 if (serialized_packet_buffer == nullptr) {
377 serialized_packet_buffer = stack_buffer;
378 }
379
dschinazi66dea072019-04-09 11:41:06 -0700380 SerializePacket(serialized_packet_buffer, kMaxOutgoingPacketSize);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500381 OnSerializedPacket();
382}
383
384void QuicPacketCreator::OnSerializedPacket() {
385 if (packet_.encrypted_buffer == nullptr) {
vasilvvc48c8712019-03-11 13:38:16 -0700386 const std::string error_details = "Failed to SerializePacket.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500387 QUIC_BUG << error_details;
388 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
fkastenholz85f18902019-05-28 12:47:00 -0700389 error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500390 return;
391 }
392
393 SerializedPacket packet(std::move(packet_));
394 ClearPacket();
395 delegate_->OnSerializedPacket(&packet);
396}
397
398void QuicPacketCreator::ClearPacket() {
399 packet_.has_ack = false;
400 packet_.has_stop_waiting = false;
401 packet_.has_crypto_handshake = NOT_HANDSHAKE;
402 packet_.num_padding_bytes = 0;
403 packet_.original_packet_number.Clear();
wub98669f52019-04-18 10:49:18 -0700404 packet_.transmission_type = NOT_RETRANSMISSION;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500405 packet_.encrypted_buffer = nullptr;
406 packet_.encrypted_length = 0;
407 DCHECK(packet_.retransmittable_frames.empty());
408 packet_.largest_acked.Clear();
409 needs_full_padding_ = false;
410}
411
412void QuicPacketCreator::CreateAndSerializeStreamFrame(
413 QuicStreamId id,
414 size_t write_length,
415 QuicStreamOffset iov_offset,
416 QuicStreamOffset stream_offset,
417 bool fin,
418 TransmissionType transmission_type,
419 size_t* num_bytes_consumed) {
420 DCHECK(queued_frames_.empty());
421 // Write out the packet header
422 QuicPacketHeader header;
423 FillPacketHeader(&header);
424
dschinazi66dea072019-04-09 11:41:06 -0700425 QUIC_CACHELINE_ALIGNED char stack_buffer[kMaxOutgoingPacketSize];
QUICHE teama6ef0a62019-03-07 20:34:33 -0500426 char* encrypted_buffer = delegate_->GetPacketBuffer();
427 if (encrypted_buffer == nullptr) {
428 encrypted_buffer = stack_buffer;
429 }
430
dschinazi66dea072019-04-09 11:41:06 -0700431 QuicDataWriter writer(kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500432 size_t length_field_offset = 0;
433 if (!framer_->AppendPacketHeader(header, &writer, &length_field_offset)) {
434 QUIC_BUG << "AppendPacketHeader failed";
435 return;
436 }
437
438 // Create a Stream frame with the remaining space.
439 QUIC_BUG_IF(iov_offset == write_length && !fin)
440 << "Creating a stream frame with no data or fin.";
441 const size_t remaining_data_size = write_length - iov_offset;
nharperebabffd2019-06-03 17:34:45 -0700442 size_t min_frame_size = QuicFramer::GetMinStreamFrameSize(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500443 framer_->transport_version(), id, stream_offset,
444 /* last_frame_in_packet= */ true, remaining_data_size);
nharperebabffd2019-06-03 17:34:45 -0700445 size_t available_size =
QUICHE teama6ef0a62019-03-07 20:34:33 -0500446 max_plaintext_size_ - writer.length() - min_frame_size;
nharperebabffd2019-06-03 17:34:45 -0700447 size_t bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
448 size_t plaintext_bytes_written = min_frame_size + bytes_consumed;
449 bool needs_padding = false;
450 if (plaintext_bytes_written < MinPlaintextPacketSize(framer_->version())) {
451 needs_padding = true;
452 // Recalculate sizes with the stream frame not being marked as the last
453 // frame in the packet.
454 min_frame_size = QuicFramer::GetMinStreamFrameSize(
455 framer_->transport_version(), id, stream_offset,
456 /* last_frame_in_packet= */ false, remaining_data_size);
457 available_size = max_plaintext_size_ - writer.length() - min_frame_size;
458 bytes_consumed = std::min<size_t>(available_size, remaining_data_size);
459 plaintext_bytes_written = min_frame_size + bytes_consumed;
460 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500461
462 const bool set_fin = fin && (bytes_consumed == remaining_data_size);
463 QuicStreamFrame frame(id, set_fin, stream_offset, bytes_consumed);
rchc76cd742019-03-26 16:00:03 -0700464 if (debug_delegate_ != nullptr) {
465 debug_delegate_->OnFrameAddedToPacket(QuicFrame(frame));
466 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500467 QUIC_DVLOG(1) << ENDPOINT << "Adding frame: " << frame;
468
dschinazi118934b2019-06-13 18:09:08 -0700469 QUIC_DVLOG(2) << ENDPOINT << "Serializing stream packet " << header << frame;
470
QUICHE teama6ef0a62019-03-07 20:34:33 -0500471 // TODO(ianswett): AppendTypeByte and AppendStreamFrame could be optimized
472 // into one method that takes a QuicStreamFrame, if warranted.
nharperebabffd2019-06-03 17:34:45 -0700473 bool omit_frame_length = !needs_padding;
474 if (!framer_->AppendTypeByte(QuicFrame(frame), omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500475 QUIC_BUG << "AppendTypeByte failed";
476 return;
477 }
nharperebabffd2019-06-03 17:34:45 -0700478 if (!framer_->AppendStreamFrame(frame, omit_frame_length, &writer)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500479 QUIC_BUG << "AppendStreamFrame failed";
480 return;
481 }
nharperebabffd2019-06-03 17:34:45 -0700482 if (needs_padding &&
483 plaintext_bytes_written < MinPlaintextPacketSize(framer_->version()) &&
QUICHE team2252b702019-05-14 23:55:14 -0400484 !writer.WritePaddingBytes(MinPlaintextPacketSize(framer_->version()) -
nharper55fa6132019-05-07 19:37:21 -0700485 plaintext_bytes_written)) {
486 QUIC_BUG << "Unable to add padding bytes";
487 return;
488 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500489
490 if (!framer_->WriteIetfLongHeaderLength(header, &writer, length_field_offset,
491 packet_.encryption_level)) {
492 return;
493 }
494
wub98669f52019-04-18 10:49:18 -0700495 if (can_set_transmission_type()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500496 packet_.transmission_type = transmission_type;
497 }
498
499 size_t encrypted_length = framer_->EncryptInPlace(
500 packet_.encryption_level, packet_.packet_number,
501 GetStartOfEncryptedData(framer_->transport_version(), header),
dschinazi66dea072019-04-09 11:41:06 -0700502 writer.length(), kMaxOutgoingPacketSize, encrypted_buffer);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500503 if (encrypted_length == 0) {
504 QUIC_BUG << "Failed to encrypt packet number " << header.packet_number;
505 return;
506 }
507 // TODO(ianswett): Optimize the storage so RetransmitableFrames can be
508 // unioned with a QuicStreamFrame and a UniqueStreamBuffer.
509 *num_bytes_consumed = bytes_consumed;
510 packet_size_ = 0;
511 packet_.encrypted_buffer = encrypted_buffer;
512 packet_.encrypted_length = encrypted_length;
513 packet_.retransmittable_frames.push_back(QuicFrame(frame));
514 OnSerializedPacket();
515}
516
517bool QuicPacketCreator::HasPendingFrames() const {
518 return !queued_frames_.empty();
519}
520
521bool QuicPacketCreator::HasPendingRetransmittableFrames() const {
522 return !packet_.retransmittable_frames.empty();
523}
524
525bool QuicPacketCreator::HasPendingStreamFramesOfStream(QuicStreamId id) const {
526 for (const auto& frame : packet_.retransmittable_frames) {
527 if (frame.type == STREAM_FRAME && frame.stream_frame.stream_id == id) {
528 return true;
529 }
530 }
531 return false;
532}
533
534size_t QuicPacketCreator::ExpansionOnNewFrame() const {
535 // If the last frame in the packet is a message frame, then it will expand to
536 // include the varint message length when a new frame is added.
537 const bool has_trailing_message_frame =
538 !queued_frames_.empty() && queued_frames_.back().type == MESSAGE_FRAME;
539 if (has_trailing_message_frame) {
540 return QuicDataWriter::GetVarInt62Len(
541 queued_frames_.back().message_frame->message_length);
542 }
543 // If the last frame in the packet is a stream frame, then it will expand to
544 // include the stream_length field when a new frame is added.
545 const bool has_trailing_stream_frame =
546 !queued_frames_.empty() && queued_frames_.back().type == STREAM_FRAME;
547 if (!has_trailing_stream_frame) {
548 return 0;
549 }
fkastenholz305e1732019-06-18 05:01:22 -0700550 if (VersionHasIetfQuicFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500551 return QuicDataWriter::GetVarInt62Len(
552 queued_frames_.back().stream_frame.data_length);
553 }
554 return kQuicStreamPayloadLengthSize;
555}
556
557size_t QuicPacketCreator::BytesFree() {
558 DCHECK_GE(max_plaintext_size_, PacketSize());
559 return max_plaintext_size_ -
560 std::min(max_plaintext_size_, PacketSize() + ExpansionOnNewFrame());
561}
562
563size_t QuicPacketCreator::PacketSize() {
564 if (!queued_frames_.empty()) {
565 return packet_size_;
566 }
nharper55fa6132019-05-07 19:37:21 -0700567 packet_size_ = PacketHeaderSize();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500568 return packet_size_;
569}
570
571bool QuicPacketCreator::AddSavedFrame(const QuicFrame& frame,
572 TransmissionType transmission_type) {
573 return AddFrame(frame, /*save_retransmittable_frames=*/true,
574 transmission_type);
575}
576
577bool QuicPacketCreator::AddPaddedSavedFrame(
578 const QuicFrame& frame,
579 TransmissionType transmission_type) {
580 if (AddFrame(frame, /*save_retransmittable_frames=*/true,
581 transmission_type)) {
582 needs_full_padding_ = true;
583 return true;
584 }
585 return false;
586}
587
588void QuicPacketCreator::SerializePacket(char* encrypted_buffer,
589 size_t encrypted_buffer_len) {
590 DCHECK_LT(0u, encrypted_buffer_len);
591 QUIC_BUG_IF(queued_frames_.empty() && pending_padding_bytes_ == 0)
592 << "Attempt to serialize empty packet";
593 QuicPacketHeader header;
594 // FillPacketHeader increments packet_number_.
595 FillPacketHeader(&header);
596
597 MaybeAddPadding();
598
dschinazi118934b2019-06-13 18:09:08 -0700599 QUIC_DVLOG(2) << ENDPOINT << "Serializing packet " << header
600 << QuicFramesToString(queued_frames_);
601
QUICHE teama6ef0a62019-03-07 20:34:33 -0500602 DCHECK_GE(max_plaintext_size_, packet_size_);
603 // Use the packet_size_ instead of the buffer size to ensure smaller
604 // packet sizes are properly used.
605 size_t length =
606 framer_->BuildDataPacket(header, queued_frames_, encrypted_buffer,
607 packet_size_, packet_.encryption_level);
608 if (length == 0) {
609 QUIC_BUG << "Failed to serialize " << queued_frames_.size() << " frames.";
610 return;
611 }
612
613 // ACK Frames will be truncated due to length only if they're the only frame
614 // in the packet, and if packet_size_ was set to max_plaintext_size_. If
615 // truncation due to length occurred, then GetSerializedFrameLength will have
616 // returned all bytes free.
617 bool possibly_truncated_by_length = packet_size_ == max_plaintext_size_ &&
618 queued_frames_.size() == 1 &&
619 queued_frames_.back().type == ACK_FRAME;
620 // Because of possible truncation, we can't be confident that our
621 // packet size calculation worked correctly.
622 if (!possibly_truncated_by_length) {
623 DCHECK_EQ(packet_size_, length);
624 }
625 const size_t encrypted_length = framer_->EncryptInPlace(
626 packet_.encryption_level, packet_.packet_number,
627 GetStartOfEncryptedData(framer_->transport_version(), header), length,
628 encrypted_buffer_len, encrypted_buffer);
629 if (encrypted_length == 0) {
630 QUIC_BUG << "Failed to encrypt packet number " << packet_.packet_number;
631 return;
632 }
633
634 packet_size_ = 0;
635 queued_frames_.clear();
636 packet_.encrypted_buffer = encrypted_buffer;
637 packet_.encrypted_length = encrypted_length;
638}
639
640std::unique_ptr<QuicEncryptedPacket>
641QuicPacketCreator::SerializeVersionNegotiationPacket(
642 bool ietf_quic,
dschinazi48ac9192019-07-31 00:07:26 -0700643 bool use_length_prefix,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500644 const ParsedQuicVersionVector& supported_versions) {
645 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
646 std::unique_ptr<QuicEncryptedPacket> encrypted =
dschinazi48ac9192019-07-31 00:07:26 -0700647 QuicFramer::BuildVersionNegotiationPacket(
648 server_connection_id_, client_connection_id_, ietf_quic,
649 use_length_prefix, supported_versions);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500650 DCHECK(encrypted);
651 DCHECK_GE(max_packet_length_, encrypted->length());
652 return encrypted;
653}
654
655OwningSerializedPacketPointer
656QuicPacketCreator::SerializeConnectivityProbingPacket() {
fkastenholz305e1732019-06-18 05:01:22 -0700657 QUIC_BUG_IF(VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500658 << "Must not be version 99 to serialize padded ping connectivity probe";
659 QuicPacketHeader header;
660 // FillPacketHeader increments packet_number_.
661 FillPacketHeader(&header);
662
dschinazi118934b2019-06-13 18:09:08 -0700663 QUIC_DVLOG(2) << ENDPOINT << "Serializing connectivity probing packet "
664 << header;
665
dschinazi66dea072019-04-09 11:41:06 -0700666 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500667 size_t length = framer_->BuildConnectivityProbingPacket(
668 header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
669 DCHECK(length);
670
671 const size_t encrypted_length = framer_->EncryptInPlace(
672 packet_.encryption_level, packet_.packet_number,
673 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700674 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500675 DCHECK(encrypted_length);
676
677 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
678 header.packet_number, header.packet_number_length, buffer.release(),
679 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
680
681 serialize_packet->encryption_level = packet_.encryption_level;
682 serialize_packet->transmission_type = NOT_RETRANSMISSION;
683
684 return serialize_packet;
685}
686
687OwningSerializedPacketPointer
688QuicPacketCreator::SerializePathChallengeConnectivityProbingPacket(
689 QuicPathFrameBuffer* payload) {
fkastenholz305e1732019-06-18 05:01:22 -0700690 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500691 << "Must be version 99 to serialize path challenge connectivity probe, "
692 "is version "
693 << framer_->transport_version();
694 QuicPacketHeader header;
695 // FillPacketHeader increments packet_number_.
696 FillPacketHeader(&header);
697
dschinazi118934b2019-06-13 18:09:08 -0700698 QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
699
dschinazi66dea072019-04-09 11:41:06 -0700700 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500701 size_t length = framer_->BuildPaddedPathChallengePacket(
702 header, buffer.get(), max_plaintext_size_, payload, random_,
703 packet_.encryption_level);
704 DCHECK(length);
705
706 const size_t encrypted_length = framer_->EncryptInPlace(
707 packet_.encryption_level, packet_.packet_number,
708 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700709 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500710 DCHECK(encrypted_length);
711
712 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
713 header.packet_number, header.packet_number_length, buffer.release(),
714 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
715
716 serialize_packet->encryption_level = packet_.encryption_level;
717 serialize_packet->transmission_type = NOT_RETRANSMISSION;
718
719 return serialize_packet;
720}
721
722OwningSerializedPacketPointer
723QuicPacketCreator::SerializePathResponseConnectivityProbingPacket(
724 const QuicDeque<QuicPathFrameBuffer>& payloads,
725 const bool is_padded) {
fkastenholz305e1732019-06-18 05:01:22 -0700726 QUIC_BUG_IF(!VersionHasIetfQuicFrames(framer_->transport_version()))
QUICHE teama6ef0a62019-03-07 20:34:33 -0500727 << "Must be version 99 to serialize path response connectivity probe, is "
728 "version "
729 << framer_->transport_version();
730 QuicPacketHeader header;
731 // FillPacketHeader increments packet_number_.
732 FillPacketHeader(&header);
733
dschinazi118934b2019-06-13 18:09:08 -0700734 QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
735
dschinazi66dea072019-04-09 11:41:06 -0700736 std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500737 size_t length = framer_->BuildPathResponsePacket(
738 header, buffer.get(), max_plaintext_size_, payloads, is_padded,
739 packet_.encryption_level);
740 DCHECK(length);
741
742 const size_t encrypted_length = framer_->EncryptInPlace(
743 packet_.encryption_level, packet_.packet_number,
744 GetStartOfEncryptedData(framer_->transport_version(), header), length,
dschinazi66dea072019-04-09 11:41:06 -0700745 kMaxOutgoingPacketSize, buffer.get());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500746 DCHECK(encrypted_length);
747
748 OwningSerializedPacketPointer serialize_packet(new SerializedPacket(
749 header.packet_number, header.packet_number_length, buffer.release(),
750 encrypted_length, /*has_ack=*/false, /*has_stop_waiting=*/false));
751
752 serialize_packet->encryption_level = packet_.encryption_level;
753 serialize_packet->transmission_type = NOT_RETRANSMISSION;
754
755 return serialize_packet;
756}
757
758// TODO(b/74062209): Make this a public method of framer?
759SerializedPacket QuicPacketCreator::NoPacket() {
760 return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
761 nullptr, 0, false, false);
762}
763
QUICHE team2252b702019-05-14 23:55:14 -0400764QuicConnectionId QuicPacketCreator::GetDestinationConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -0400765 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi346b7ce2019-06-05 01:38:18 -0700766 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400767 }
dschinazi7b9278c2019-05-20 07:36:21 -0700768 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400769}
770
771QuicConnectionId QuicPacketCreator::GetSourceConnectionId() const {
QUICHE team2252b702019-05-14 23:55:14 -0400772 if (framer_->perspective() == Perspective::IS_CLIENT) {
dschinazi346b7ce2019-06-05 01:38:18 -0700773 return client_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400774 }
dschinazi7b9278c2019-05-20 07:36:21 -0700775 return server_connection_id_;
QUICHE team2252b702019-05-14 23:55:14 -0400776}
777
QUICHE teama6ef0a62019-03-07 20:34:33 -0500778QuicConnectionIdIncluded QuicPacketCreator::GetDestinationConnectionIdIncluded()
779 const {
dschinazi5e1a7b22019-07-31 12:23:21 -0700780 // In versions that do not support client connection IDs, the destination
781 // connection ID is only sent from client to server.
782 return (framer_->perspective() == Perspective::IS_CLIENT ||
783 framer_->version().SupportsClientConnectionIds())
784 ? CONNECTION_ID_PRESENT
785 : CONNECTION_ID_ABSENT;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500786}
787
788QuicConnectionIdIncluded QuicPacketCreator::GetSourceConnectionIdIncluded()
789 const {
790 // Long header packets sent by server include source connection ID.
dschinazi346b7ce2019-06-05 01:38:18 -0700791 // Ones sent by the client only include source connection ID if the version
792 // supports client connection IDs.
793 if (HasIetfLongHeader() &&
794 (framer_->perspective() == Perspective::IS_SERVER ||
795 framer_->version().SupportsClientConnectionIds())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500796 return CONNECTION_ID_PRESENT;
797 }
dschinazi5e1a7b22019-07-31 12:23:21 -0700798 if (framer_->perspective() == Perspective::IS_SERVER) {
dschinazi7b9278c2019-05-20 07:36:21 -0700799 return server_connection_id_included_;
QUICHE team2252b702019-05-14 23:55:14 -0400800 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500801 return CONNECTION_ID_ABSENT;
802}
803
804QuicConnectionIdLength QuicPacketCreator::GetDestinationConnectionIdLength()
805 const {
dschinazi7b9278c2019-05-20 07:36:21 -0700806 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500807 transport_version()));
808 return GetDestinationConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -0400809 ? static_cast<QuicConnectionIdLength>(
810 GetDestinationConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -0500811 : PACKET_0BYTE_CONNECTION_ID;
812}
813
814QuicConnectionIdLength QuicPacketCreator::GetSourceConnectionIdLength() const {
dschinazi7b9278c2019-05-20 07:36:21 -0700815 DCHECK(QuicUtils::IsConnectionIdValidForVersion(server_connection_id_,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500816 transport_version()));
817 return GetSourceConnectionIdIncluded() == CONNECTION_ID_PRESENT
QUICHE team2252b702019-05-14 23:55:14 -0400818 ? static_cast<QuicConnectionIdLength>(
819 GetSourceConnectionId().length())
QUICHE teama6ef0a62019-03-07 20:34:33 -0500820 : PACKET_0BYTE_CONNECTION_ID;
821}
822
823QuicPacketNumberLength QuicPacketCreator::GetPacketNumberLength() const {
fayang3ac15c12019-06-14 14:04:51 -0700824 if (HasIetfLongHeader() &&
825 !framer_->version().SendsVariableLengthPacketNumberInLongHeader()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500826 return PACKET_4BYTE_PACKET_NUMBER;
827 }
828 return packet_.packet_number_length;
829}
830
nharper55fa6132019-05-07 19:37:21 -0700831size_t QuicPacketCreator::PacketHeaderSize() const {
832 return GetPacketHeaderSize(
833 framer_->transport_version(), GetDestinationConnectionIdLength(),
834 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
835 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
836 GetRetryTokenLengthLength(), GetRetryToken().length(), GetLengthLength());
837}
838
QUICHE teama6ef0a62019-03-07 20:34:33 -0500839QuicVariableLengthIntegerLength QuicPacketCreator::GetRetryTokenLengthLength()
840 const {
841 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
842 HasIetfLongHeader() &&
843 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
844 return QuicDataWriter::GetVarInt62Len(GetRetryToken().length());
845 }
846 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
847}
848
849QuicStringPiece QuicPacketCreator::GetRetryToken() const {
dschinazi0db87092019-05-20 07:59:15 -0700850 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
851 HasIetfLongHeader() &&
852 EncryptionlevelToLongHeaderType(packet_.encryption_level) == INITIAL) {
853 return retry_token_;
854 }
855 return QuicStringPiece();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500856}
857
858void QuicPacketCreator::SetRetryToken(QuicStringPiece retry_token) {
vasilvvc48c8712019-03-11 13:38:16 -0700859 retry_token_ = std::string(retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500860}
861
862QuicVariableLengthIntegerLength QuicPacketCreator::GetLengthLength() const {
863 if (QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
864 HasIetfLongHeader()) {
865 QuicLongHeaderType long_header_type =
866 EncryptionlevelToLongHeaderType(packet_.encryption_level);
867 if (long_header_type == INITIAL || long_header_type == ZERO_RTT_PROTECTED ||
868 long_header_type == HANDSHAKE) {
869 return VARIABLE_LENGTH_INTEGER_LENGTH_2;
870 }
871 }
872 return VARIABLE_LENGTH_INTEGER_LENGTH_0;
873}
874
875void QuicPacketCreator::FillPacketHeader(QuicPacketHeader* header) {
QUICHE team2252b702019-05-14 23:55:14 -0400876 header->destination_connection_id = GetDestinationConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500877 header->destination_connection_id_included =
878 GetDestinationConnectionIdIncluded();
QUICHE team2252b702019-05-14 23:55:14 -0400879 header->source_connection_id = GetSourceConnectionId();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500880 header->source_connection_id_included = GetSourceConnectionIdIncluded();
881 header->reset_flag = false;
882 header->version_flag = IncludeVersionInHeader();
883 if (IncludeNonceInPublicHeader()) {
884 DCHECK_EQ(Perspective::IS_SERVER, framer_->perspective());
885 header->nonce = &diversification_nonce_;
886 } else {
887 header->nonce = nullptr;
888 }
fayang354c9422019-05-21 08:10:35 -0700889 packet_.packet_number = NextSendingPacketNumber();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500890 header->packet_number = packet_.packet_number;
891 header->packet_number_length = GetPacketNumberLength();
892 header->retry_token_length_length = GetRetryTokenLengthLength();
893 header->retry_token = GetRetryToken();
894 header->length_length = GetLengthLength();
895 header->remaining_packet_length = 0;
896 if (!HasIetfLongHeader()) {
897 return;
898 }
899 header->long_packet_type =
900 EncryptionlevelToLongHeaderType(packet_.encryption_level);
901}
902
903bool QuicPacketCreator::AddFrame(const QuicFrame& frame,
904 bool save_retransmittable_frames,
905 TransmissionType transmission_type) {
906 QUIC_DVLOG(1) << ENDPOINT << "Adding frame with transmission type "
907 << transmission_type << ": " << frame;
908 if (frame.type == STREAM_FRAME &&
nharper46833c32019-05-15 21:33:05 -0700909 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
910 frame.stream_frame.stream_id) &&
fayang49523232019-05-03 06:28:22 -0700911 (packet_.encryption_level == ENCRYPTION_INITIAL ||
912 packet_.encryption_level == ENCRYPTION_HANDSHAKE)) {
913 const std::string error_details = QuicStrCat(
914 "Cannot send stream data with level: ",
915 QuicUtils::EncryptionLevelToString(packet_.encryption_level));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500916 QUIC_BUG << error_details;
917 delegate_->OnUnrecoverableError(
fkastenholz85f18902019-05-28 12:47:00 -0700918 QUIC_ATTEMPT_TO_SEND_UNENCRYPTED_STREAM_DATA, error_details);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500919 return false;
920 }
921 size_t frame_len = framer_->GetSerializedFrameLength(
922 frame, BytesFree(), queued_frames_.empty(),
923 /* last_frame_in_packet= */ true, GetPacketNumberLength());
924 if (frame_len == 0) {
925 // Current open packet is full.
926 Flush();
927 return false;
928 }
929 DCHECK_LT(0u, packet_size_);
930
931 packet_size_ += ExpansionOnNewFrame() + frame_len;
932
933 if (save_retransmittable_frames &&
934 QuicUtils::IsRetransmittableFrame(frame.type)) {
935 packet_.retransmittable_frames.push_back(frame);
936 queued_frames_.push_back(frame);
937 if (QuicUtils::IsHandshakeFrame(frame, framer_->transport_version())) {
938 packet_.has_crypto_handshake = IS_HANDSHAKE;
939 }
940 } else {
941 queued_frames_.push_back(frame);
942 }
943
944 if (frame.type == ACK_FRAME) {
945 packet_.has_ack = true;
946 packet_.largest_acked = LargestAcked(*frame.ack_frame);
947 }
948 if (frame.type == STOP_WAITING_FRAME) {
949 packet_.has_stop_waiting = true;
950 }
951 if (debug_delegate_ != nullptr) {
952 debug_delegate_->OnFrameAddedToPacket(frame);
953 }
954
955 // Packet transmission type is determined by the last added retransmittable
956 // frame.
wub98669f52019-04-18 10:49:18 -0700957 if (can_set_transmission_type() &&
QUICHE teama6ef0a62019-03-07 20:34:33 -0500958 QuicUtils::IsRetransmittableFrame(frame.type)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500959 packet_.transmission_type = transmission_type;
960 }
961 return true;
962}
963
964void QuicPacketCreator::MaybeAddPadding() {
965 // The current packet should have no padding bytes because padding is only
966 // added when this method is called just before the packet is serialized.
967 DCHECK_EQ(0, packet_.num_padding_bytes);
968 if (BytesFree() == 0) {
969 // Don't pad full packets.
970 return;
971 }
972
973 if (packet_.transmission_type == PROBING_RETRANSMISSION) {
974 needs_full_padding_ = true;
975 }
976
nharper55fa6132019-05-07 19:37:21 -0700977 // Header protection requires a minimum plaintext packet size.
978 size_t extra_padding_bytes = 0;
979 if (framer_->version().HasHeaderProtection()) {
980 size_t frame_bytes = PacketSize() - PacketHeaderSize();
981
QUICHE team2252b702019-05-14 23:55:14 -0400982 if (frame_bytes + pending_padding_bytes_ <
983 MinPlaintextPacketSize(framer_->version()) &&
nharper55fa6132019-05-07 19:37:21 -0700984 !needs_full_padding_) {
QUICHE team2252b702019-05-14 23:55:14 -0400985 extra_padding_bytes =
986 MinPlaintextPacketSize(framer_->version()) - frame_bytes;
nharper55fa6132019-05-07 19:37:21 -0700987 }
988 }
989
990 if (!needs_full_padding_ && pending_padding_bytes_ == 0 &&
991 extra_padding_bytes == 0) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500992 // Do not need padding.
993 return;
994 }
995
nharper55fa6132019-05-07 19:37:21 -0700996 int padding_bytes = -1;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500997 if (needs_full_padding_) {
998 // Full padding does not consume pending padding bytes.
999 packet_.num_padding_bytes = -1;
1000 } else {
1001 packet_.num_padding_bytes =
1002 std::min<int16_t>(pending_padding_bytes_, BytesFree());
1003 pending_padding_bytes_ -= packet_.num_padding_bytes;
nharper55fa6132019-05-07 19:37:21 -07001004 padding_bytes =
1005 std::max<int16_t>(packet_.num_padding_bytes, extra_padding_bytes);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001006 }
1007
nharper55fa6132019-05-07 19:37:21 -07001008 bool success = AddFrame(QuicFrame(QuicPaddingFrame(padding_bytes)), false,
1009 packet_.transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001010 DCHECK(success);
1011}
1012
1013bool QuicPacketCreator::IncludeNonceInPublicHeader() const {
1014 return have_diversification_nonce_ &&
1015 packet_.encryption_level == ENCRYPTION_ZERO_RTT;
1016}
1017
1018bool QuicPacketCreator::IncludeVersionInHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001019 if (VersionHasIetfInvariantHeader(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001020 return packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1021 }
1022 return send_version_in_packet_;
1023}
1024
1025void QuicPacketCreator::AddPendingPadding(QuicByteCount size) {
1026 pending_padding_bytes_ += size;
1027}
1028
ianswette28f0222019-04-04 13:31:22 -07001029bool QuicPacketCreator::StreamFrameIsClientHello(
QUICHE teama6ef0a62019-03-07 20:34:33 -05001030 const QuicStreamFrame& frame) const {
1031 if (framer_->perspective() == Perspective::IS_SERVER ||
nharper46833c32019-05-15 21:33:05 -07001032 !QuicUtils::IsCryptoStreamId(framer_->transport_version(),
1033 frame.stream_id)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001034 return false;
1035 }
ianswette28f0222019-04-04 13:31:22 -07001036 // The ClientHello is always sent with INITIAL encryption.
1037 return packet_.encryption_level == ENCRYPTION_INITIAL;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001038}
1039
dschinazi7b9278c2019-05-20 07:36:21 -07001040void QuicPacketCreator::SetServerConnectionIdIncluded(
1041 QuicConnectionIdIncluded server_connection_id_included) {
1042 DCHECK(server_connection_id_included == CONNECTION_ID_PRESENT ||
1043 server_connection_id_included == CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -05001044 DCHECK(framer_->perspective() == Perspective::IS_SERVER ||
dschinazi7b9278c2019-05-20 07:36:21 -07001045 server_connection_id_included != CONNECTION_ID_ABSENT);
1046 server_connection_id_included_ = server_connection_id_included;
QUICHE teama6ef0a62019-03-07 20:34:33 -05001047}
1048
dschinazi7b9278c2019-05-20 07:36:21 -07001049void QuicPacketCreator::SetServerConnectionId(
1050 QuicConnectionId server_connection_id) {
1051 server_connection_id_ = server_connection_id;
QUICHE teamc65d1d12019-03-19 20:58:04 -07001052}
1053
dschinazi346b7ce2019-06-05 01:38:18 -07001054void QuicPacketCreator::SetClientConnectionId(
1055 QuicConnectionId client_connection_id) {
1056 DCHECK(client_connection_id.IsEmpty() ||
1057 framer_->version().SupportsClientConnectionIds());
dschinazi346b7ce2019-06-05 01:38:18 -07001058 client_connection_id_ = client_connection_id;
1059}
1060
QUICHE teama6ef0a62019-03-07 20:34:33 -05001061void QuicPacketCreator::SetTransmissionType(TransmissionType type) {
1062 DCHECK(can_set_transmission_type_);
1063
wub98669f52019-04-18 10:49:18 -07001064 if (!can_set_transmission_type()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001065 QUIC_DVLOG_IF(1, type != packet_.transmission_type)
1066 << ENDPOINT << "Setting Transmission type to "
1067 << QuicUtils::TransmissionTypeToString(type);
1068
1069 packet_.transmission_type = type;
1070 }
1071}
1072
ianswettb239f862019-04-05 09:15:06 -07001073QuicPacketLength QuicPacketCreator::GetCurrentLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001074 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
QUICHE teama6ef0a62019-03-07 20:34:33 -05001075 return 0;
1076 }
1077 const size_t packet_header_size = GetPacketHeaderSize(
1078 framer_->transport_version(), GetDestinationConnectionIdLength(),
1079 GetSourceConnectionIdLength(), IncludeVersionInHeader(),
1080 IncludeNonceInPublicHeader(), GetPacketNumberLength(),
ianswettb239f862019-04-05 09:15:06 -07001081 // No Retry token on packets containing application data.
1082 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, GetLengthLength());
QUICHE teama6ef0a62019-03-07 20:34:33 -05001083 // This is the largest possible message payload when the length field is
1084 // omitted.
1085 return max_plaintext_size_ -
1086 std::min(max_plaintext_size_, packet_header_size + kQuicFrameTypeSize);
1087}
1088
ianswettb239f862019-04-05 09:15:06 -07001089QuicPacketLength QuicPacketCreator::GetGuaranteedLargestMessagePayload() const {
fayangd4291e42019-05-30 10:31:21 -07001090 if (!VersionSupportsMessageFrames(framer_->transport_version())) {
ianswettb239f862019-04-05 09:15:06 -07001091 return 0;
1092 }
1093 // QUIC Crypto server packets may include a diversification nonce.
1094 const bool may_include_nonce =
1095 framer_->version().handshake_protocol == PROTOCOL_QUIC_CRYPTO &&
1096 framer_->perspective() == Perspective::IS_SERVER;
1097 // IETF QUIC long headers include a length on client 0RTT packets.
1098 QuicVariableLengthIntegerLength length_length =
nharperd43f1d62019-07-01 15:18:20 -07001099 VARIABLE_LENGTH_INTEGER_LENGTH_0;
1100 if (framer_->perspective() == Perspective::IS_CLIENT) {
1101 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_2;
1102 }
1103 if (!QuicVersionHasLongHeaderLengths(framer_->transport_version()) &&
1104 fix_get_packet_header_size_) {
1105 QUIC_RELOADABLE_FLAG_COUNT_N(quic_fix_get_packet_header_size, 3, 3);
1106 length_length = VARIABLE_LENGTH_INTEGER_LENGTH_0;
1107 }
ianswettb239f862019-04-05 09:15:06 -07001108 const size_t packet_header_size = GetPacketHeaderSize(
1109 framer_->transport_version(), GetDestinationConnectionIdLength(),
1110 // Assume CID lengths don't change, but version may be present.
1111 GetSourceConnectionIdLength(), kIncludeVersion, may_include_nonce,
1112 PACKET_4BYTE_PACKET_NUMBER,
1113 // No Retry token on packets containing application data.
1114 VARIABLE_LENGTH_INTEGER_LENGTH_0, 0, length_length);
1115 // This is the largest possible message payload when the length field is
1116 // omitted.
1117 const QuicPacketLength largest_payload =
1118 max_plaintext_size_ -
1119 std::min(max_plaintext_size_, packet_header_size + kQuicFrameTypeSize);
1120 // This must always be less than or equal to GetCurrentLargestMessagePayload.
1121 DCHECK_LE(largest_payload, GetCurrentLargestMessagePayload());
1122 return largest_payload;
1123}
1124
QUICHE teama6ef0a62019-03-07 20:34:33 -05001125bool QuicPacketCreator::HasIetfLongHeader() const {
fayangd4291e42019-05-30 10:31:21 -07001126 return VersionHasIetfInvariantHeader(framer_->transport_version()) &&
QUICHE teama6ef0a62019-03-07 20:34:33 -05001127 packet_.encryption_level < ENCRYPTION_FORWARD_SECURE;
1128}
1129
nharper6f8a7612019-07-08 12:31:20 -07001130// static
QUICHE team2252b702019-05-14 23:55:14 -04001131size_t QuicPacketCreator::MinPlaintextPacketSize(
1132 const ParsedQuicVersion& version) {
1133 if (!version.HasHeaderProtection()) {
nharper55fa6132019-05-07 19:37:21 -07001134 return 0;
1135 }
1136 // Header protection samples 16 bytes of ciphertext starting 4 bytes after the
1137 // packet number. In IETF QUIC, all AEAD algorithms have a 16-byte auth tag
1138 // (i.e. the ciphertext is 16 bytes larger than the plaintext). Since packet
1139 // numbers could be as small as 1 byte, but the sample starts 4 bytes after
1140 // the packet number, at least 3 bytes of plaintext are needed to make sure
1141 // that there is enough ciphertext to sample.
1142 //
1143 // Google QUIC crypto uses different AEAD algorithms - in particular the auth
1144 // tags are only 12 bytes instead of 16 bytes. Since the auth tag is 4 bytes
1145 // shorter, 4 more bytes of plaintext are needed to guarantee there is enough
1146 // ciphertext to sample.
1147 //
1148 // This method could check for PROTOCOL_TLS1_3 vs PROTOCOL_QUIC_CRYPTO and
1149 // return 3 when TLS 1.3 is in use (the use of IETF vs Google QUIC crypters is
1150 // determined based on the handshake protocol used). However, even when TLS
1151 // 1.3 is used, unittests still use NullEncrypter/NullDecrypter (and other
1152 // test crypters) which also only use 12 byte tags.
1153 //
1154 // TODO(nharper): Set this based on the handshake protocol in use.
1155 return 7;
1156}
1157
fayang354c9422019-05-21 08:10:35 -07001158QuicPacketNumber QuicPacketCreator::NextSendingPacketNumber() const {
1159 if (!packet_number().IsInitialized()) {
1160 return framer_->first_sending_packet_number();
1161 }
1162 return packet_number() + 1;
1163}
1164
QUICHE teama6ef0a62019-03-07 20:34:33 -05001165#undef ENDPOINT // undef for jumbo builds
1166} // namespace quic