blob: d71a1afa36341e6fd9564b87a3bf21bf2b730137 [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
fayang4245c212019-11-05 13:33:46 -08005// Responsible for creating packets on behalf of a QuicConnection.
6// Packets are serialized just-in-time. Stream data and control frames will be
7// requested from the Connection just-in-time. Frames are accumulated into
8// "current" packet until no more frames can fit, then current packet gets
9// serialized and passed to connection via OnSerializedPacket().
10//
11// Whether a packet should be serialized is determined by whether delegate is
12// writable. If the Delegate is not writable, then no operations will cause
13// a packet to be serialized.
QUICHE teama6ef0a62019-03-07 20:34:33 -050014
15#ifndef QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
16#define QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_
17
18#include <cstddef>
19#include <memory>
20#include <utility>
21#include <vector>
22
renjietangdbe98342019-10-18 11:00:57 -070023#include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h"
danzhbf4836c2020-02-11 20:29:15 -080024#include "net/third_party/quiche/src/quic/core/quic_circular_deque.h"
fayang08750832019-10-24 11:25:34 -070025#include "net/third_party/quiche/src/quic/core/quic_coalesced_packet.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050026#include "net/third_party/quiche/src/quic/core/quic_framer.h"
27#include "net/third_party/quiche/src/quic/core/quic_packets.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050028#include "net/third_party/quiche/src/quic/core/quic_types.h"
29#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
dmcardlecf0bfcf2019-12-13 08:08:21 -080030#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050031
32namespace quic {
33namespace test {
34class QuicPacketCreatorPeer;
35}
36
37class QUIC_EXPORT_PRIVATE QuicPacketCreator {
38 public:
39 // A delegate interface for further processing serialized packet.
ianswettb023c7b2019-05-06 12:38:10 -070040 class QUIC_EXPORT_PRIVATE DelegateInterface {
QUICHE teama6ef0a62019-03-07 20:34:33 -050041 public:
ianswettb023c7b2019-05-06 12:38:10 -070042 virtual ~DelegateInterface() {}
dschinazi66dea072019-04-09 11:41:06 -070043 // Get a buffer of kMaxOutgoingPacketSize bytes to serialize the next
wub50d4c712020-05-19 15:48:28 -070044 // packet. If the return value's buffer is nullptr, QuicPacketCreator will
45 // serialize on a stack buffer.
46 virtual QuicPacketBuffer GetPacketBuffer() = 0;
wub8a5dafa2020-05-13 12:30:17 -070047 // Called when a packet is serialized. Delegate take the ownership of
48 // |serialized_packet|.
49 virtual void OnSerializedPacket(SerializedPacket serialized_packet) = 0;
ianswettb023c7b2019-05-06 12:38:10 -070050
51 // Called when an unrecoverable error is encountered.
52 virtual void OnUnrecoverableError(QuicErrorCode error,
fkastenholz85f18902019-05-28 12:47:00 -070053 const std::string& error_details) = 0;
fayangcad11792019-09-16 13:11:44 -070054
55 // Consults delegate whether a packet should be generated.
56 virtual bool ShouldGeneratePacket(HasRetransmittableData retransmittable,
57 IsHandshake handshake) = 0;
58 // Called when there is data to be sent. Retrieves updated ACK frame from
59 // the delegate.
60 virtual const QuicFrames MaybeBundleAckOpportunistically() = 0;
QUICHE teama6ef0a62019-03-07 20:34:33 -050061 };
62
63 // Interface which gets callbacks from the QuicPacketCreator at interesting
64 // points. Implementations must not mutate the state of the creator
65 // as a result of these callbacks.
66 class QUIC_EXPORT_PRIVATE DebugDelegate {
67 public:
68 virtual ~DebugDelegate() {}
69
70 // Called when a frame has been added to the current packet.
dschinazi17d42422019-06-18 16:35:07 -070071 virtual void OnFrameAddedToPacket(const QuicFrame& /*frame*/) {}
renjietangdbe98342019-10-18 11:00:57 -070072
73 // Called when a stream frame is coalesced with an existing stream frame.
74 // |frame| is the new stream frame.
75 virtual void OnStreamFrameCoalesced(const QuicStreamFrame& /*frame*/) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050076 };
77
dschinazi7b9278c2019-05-20 07:36:21 -070078 QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050079 QuicFramer* framer,
80 DelegateInterface* delegate);
dschinazi7b9278c2019-05-20 07:36:21 -070081 QuicPacketCreator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050082 QuicFramer* framer,
83 QuicRandom* random,
84 DelegateInterface* delegate);
85 QuicPacketCreator(const QuicPacketCreator&) = delete;
86 QuicPacketCreator& operator=(const QuicPacketCreator&) = delete;
87
88 ~QuicPacketCreator();
89
90 // Makes the framer not serialize the protocol version in sent packets.
91 void StopSendingVersion();
92
93 // SetDiversificationNonce sets the nonce that will be sent in each public
94 // header of packets encrypted at the initial encryption level. Should only
95 // be called by servers.
96 void SetDiversificationNonce(const DiversificationNonce& nonce);
97
98 // Update the packet number length to use in future packets as soon as it
99 // can be safely changed.
100 // TODO(fayang): Directly set packet number length instead of compute it in
101 // creator.
102 void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer,
103 QuicPacketCount max_packets_in_flight);
104
fayang4c1c2362019-09-13 07:20:01 -0700105 // Skip |count| packet numbers.
106 void SkipNPacketNumbers(QuicPacketCount count,
107 QuicPacketNumber least_packet_awaited_by_peer,
108 QuicPacketCount max_packets_in_flight);
109
QUICHE teama6ef0a62019-03-07 20:34:33 -0500110 // The overhead the framing will add for a packet with one frame.
111 static size_t StreamFramePacketOverhead(
112 QuicTransportVersion version,
113 QuicConnectionIdLength destination_connection_id_length,
114 QuicConnectionIdLength source_connection_id_length,
115 bool include_version,
116 bool include_diversification_nonce,
117 QuicPacketNumberLength packet_number_length,
118 QuicVariableLengthIntegerLength retry_token_length_length,
119 QuicVariableLengthIntegerLength length_length,
120 QuicStreamOffset offset);
121
122 // Returns false and flushes all pending frames if current open packet is
123 // full.
124 // If current packet is not full, creates a stream frame that fits into the
125 // open packet and adds it to the packet.
fayang62b637b2019-09-16 08:40:49 -0700126 bool ConsumeDataToFillCurrentPacket(QuicStreamId id,
127 size_t data_size,
128 QuicStreamOffset offset,
129 bool fin,
130 bool needs_full_padding,
131 TransmissionType transmission_type,
132 QuicFrame* frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500133
134 // Creates a CRYPTO frame that fits into the current packet (which must be
135 // empty) and adds it to the packet.
fayang62b637b2019-09-16 08:40:49 -0700136 bool ConsumeCryptoDataToFillCurrentPacket(EncryptionLevel level,
137 size_t write_length,
138 QuicStreamOffset offset,
139 bool needs_full_padding,
140 TransmissionType transmission_type,
141 QuicFrame* frame);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500142
143 // Returns true if current open packet can accommodate more stream frames of
144 // stream |id| at |offset| and data length |data_size|, false otherwise.
145 bool HasRoomForStreamFrame(QuicStreamId id,
146 QuicStreamOffset offset,
147 size_t data_size);
148
149 // Returns true if current open packet can accommodate a message frame of
150 // |length|.
151 bool HasRoomForMessageFrame(QuicByteCount length);
152
QUICHE teama6ef0a62019-03-07 20:34:33 -0500153 // Serializes all added frames into a single packet and invokes the delegate_
154 // to further process the SerializedPacket.
fayang62b637b2019-09-16 08:40:49 -0700155 void FlushCurrentPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500156
157 // Optimized method to create a QuicStreamFrame and serialize it. Adds the
158 // QuicStreamFrame to the returned SerializedPacket. Sets
159 // |num_bytes_consumed| to the number of bytes consumed to create the
160 // QuicStreamFrame.
161 void CreateAndSerializeStreamFrame(QuicStreamId id,
162 size_t write_length,
163 QuicStreamOffset iov_offset,
164 QuicStreamOffset stream_offset,
165 bool fin,
166 TransmissionType transmission_type,
167 size_t* num_bytes_consumed);
168
169 // Returns true if there are frames pending to be serialized.
170 bool HasPendingFrames() const;
171
172 // Returns true if there are retransmittable frames pending to be serialized.
173 bool HasPendingRetransmittableFrames() const;
174
175 // Returns true if there are stream frames for |id| pending to be serialized.
176 bool HasPendingStreamFramesOfStream(QuicStreamId id) const;
177
178 // Returns the number of bytes which are available to be used by additional
179 // frames in the packet. Since stream frames are slightly smaller when they
180 // are the last frame in a packet, this method will return a different
181 // value than max_packet_size - PacketSize(), in this case.
182 size_t BytesFree();
183
184 // Returns the number of bytes that the packet will expand by if a new frame
185 // is added to the packet. If the last frame was a stream frame, it will
186 // expand slightly when a new frame is added, and this method returns the
187 // amount of expected expansion.
188 size_t ExpansionOnNewFrame() const;
189
190 // Returns the number of bytes in the current packet, including the header,
191 // if serialized with the current frames. Adding a frame to the packet
192 // may change the serialized length of existing frames, as per the comment
193 // in BytesFree.
194 size_t PacketSize();
195
196 // Tries to add |frame| to the packet creator's list of frames to be
197 // serialized. If the frame does not fit into the current packet, flushes the
198 // packet and returns false.
renjietangb63005e2019-11-19 23:08:53 -0800199 bool AddFrame(const QuicFrame& frame, TransmissionType transmission_type);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500200
201 // Identical to AddSavedFrame, but allows the frame to be padded.
202 bool AddPaddedSavedFrame(const QuicFrame& frame,
203 TransmissionType transmission_type);
204
205 // Creates a version negotiation packet which supports |supported_versions|.
206 std::unique_ptr<QuicEncryptedPacket> SerializeVersionNegotiationPacket(
207 bool ietf_quic,
dschinazi48ac9192019-07-31 00:07:26 -0700208 bool use_length_prefix,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500209 const ParsedQuicVersionVector& supported_versions);
210
211 // Creates a connectivity probing packet for versions prior to version 99.
wub8a5dafa2020-05-13 12:30:17 -0700212 std::unique_ptr<SerializedPacket> SerializeConnectivityProbingPacket();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500213
214 // Create connectivity probing request and response packets using PATH
215 // CHALLENGE and PATH RESPONSE frames, respectively, for version 99/IETF QUIC.
216 // SerializePathChallengeConnectivityProbingPacket will pad the packet to be
217 // MTU bytes long.
wub8a5dafa2020-05-13 12:30:17 -0700218 std::unique_ptr<SerializedPacket>
219 SerializePathChallengeConnectivityProbingPacket(QuicPathFrameBuffer* payload);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500220
221 // If |is_padded| is true then SerializePathResponseConnectivityProbingPacket
222 // will pad the packet to be MTU bytes long, else it will not pad the packet.
223 // |payloads| is cleared.
wub8a5dafa2020-05-13 12:30:17 -0700224 std::unique_ptr<SerializedPacket>
225 SerializePathResponseConnectivityProbingPacket(
wuba750aab2020-02-10 06:43:15 -0800226 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500227 const bool is_padded);
228
229 // Returns a dummy packet that is valid but contains no useful information.
230 static SerializedPacket NoPacket();
231
QUICHE team2252b702019-05-14 23:55:14 -0400232 // Returns the destination connection ID to send over the wire.
233 QuicConnectionId GetDestinationConnectionId() const;
234
235 // Returns the source connection ID to send over the wire.
236 QuicConnectionId GetSourceConnectionId() const;
237
QUICHE teama6ef0a62019-03-07 20:34:33 -0500238 // Returns length of destination connection ID to send over the wire.
239 QuicConnectionIdLength GetDestinationConnectionIdLength() const;
240
241 // Returns length of source connection ID to send over the wire.
242 QuicConnectionIdLength GetSourceConnectionIdLength() const;
243
dschinazi7b9278c2019-05-20 07:36:21 -0700244 // Sets whether the server connection ID should be sent over the wire.
245 void SetServerConnectionIdIncluded(
246 QuicConnectionIdIncluded server_connection_id_included);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500247
dschinazi8ff74822019-05-28 16:37:20 -0700248 // Update the server connection ID used in outgoing packets.
dschinazi7b9278c2019-05-20 07:36:21 -0700249 void SetServerConnectionId(QuicConnectionId server_connection_id);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700250
dschinazi346b7ce2019-06-05 01:38:18 -0700251 // Update the client connection ID used in outgoing packets.
252 void SetClientConnectionId(QuicConnectionId client_connection_id);
253
QUICHE teama6ef0a62019-03-07 20:34:33 -0500254 // Sets the encryption level that will be applied to new packets.
255 void set_encryption_level(EncryptionLevel level) {
256 packet_.encryption_level = level;
257 }
dschinazi6458eb32020-06-23 12:38:41 -0700258 EncryptionLevel encryption_level() { return packet_.encryption_level; }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500259
260 // packet number of the last created packet, or 0 if no packets have been
261 // created.
262 QuicPacketNumber packet_number() const { return packet_.packet_number; }
263
264 QuicByteCount max_packet_length() const { return max_packet_length_; }
265
266 bool has_ack() const { return packet_.has_ack; }
267
268 bool has_stop_waiting() const { return packet_.has_stop_waiting; }
269
270 // Sets the encrypter to use for the encryption level and updates the max
271 // plaintext size.
272 void SetEncrypter(EncryptionLevel level,
273 std::unique_ptr<QuicEncrypter> encrypter);
274
275 // Indicates whether the packet creator is in a state where it can change
276 // current maximum packet length.
277 bool CanSetMaxPacketLength() const;
278
279 // Sets the maximum packet length.
280 void SetMaxPacketLength(QuicByteCount length);
281
dschinazied459c02020-05-07 16:12:23 -0700282 // Sets the maximum DATAGRAM/MESSAGE frame size we can send.
283 void SetMaxDatagramFrameSize(QuicByteCount max_datagram_frame_size);
284
fayang2ab1e852019-11-04 11:24:36 -0800285 // Set a soft maximum packet length in the creator. If a packet cannot be
286 // successfully created, creator will remove the soft limit and use the actual
287 // max packet length.
288 void SetSoftMaxPacketLength(QuicByteCount length);
289
QUICHE teama6ef0a62019-03-07 20:34:33 -0500290 // Increases pending_padding_bytes by |size|. Pending padding will be sent by
291 // MaybeAddPadding().
292 void AddPendingPadding(QuicByteCount size);
293
dschinazi244f6dc2019-05-06 15:45:16 -0700294 // Sets the retry token to be sent over the wire in IETF Initial packets.
dmcardlecf0bfcf2019-12-13 08:08:21 -0800295 void SetRetryToken(quiche::QuicheStringPiece retry_token);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500296
fayang18be79a2019-09-16 15:17:12 -0700297 // Consumes retransmittable control |frame|. Returns true if the frame is
298 // successfully consumed. Returns false otherwise.
299 bool ConsumeRetransmittableControlFrame(const QuicFrame& frame);
300
301 // Given some data, may consume part or all of it and pass it to the
302 // packet creator to be serialized into packets. If not in batch
303 // mode, these packets will also be sent during this call.
304 // When |state| is FIN_AND_PADDING, random padding of size [1, 256] will be
305 // added after stream frames. If current constructed packet cannot
306 // accommodate, the padding will overflow to the next packet(s).
307 QuicConsumedData ConsumeData(QuicStreamId id,
308 size_t write_length,
309 QuicStreamOffset offset,
310 StreamSendingState state);
311
312 // Sends as many data only packets as allowed by the send algorithm and the
313 // available iov.
314 // This path does not support padding, or bundling pending frames.
315 // In case we access this method from ConsumeData, total_bytes_consumed
316 // keeps track of how many bytes have already been consumed.
317 QuicConsumedData ConsumeDataFastPath(QuicStreamId id,
318 size_t write_length,
319 QuicStreamOffset offset,
320 bool fin,
321 size_t total_bytes_consumed);
322
323 // Consumes data for CRYPTO frames sent at |level| starting at |offset| for a
324 // total of |write_length| bytes, and returns the number of bytes consumed.
325 // The data is passed into the packet creator and serialized into one or more
326 // packets.
327 size_t ConsumeCryptoData(EncryptionLevel level,
328 size_t write_length,
329 QuicStreamOffset offset);
330
331 // Generates an MTU discovery packet of specified size.
332 void GenerateMtuDiscoveryPacket(QuicByteCount target_mtu);
333
334 // Called when there is data to be sent, Retrieves updated ACK frame from
335 // delegate_ and flushes it.
336 void MaybeBundleAckOpportunistically();
337
338 // Called to flush ACK and STOP_WAITING frames, returns false if the flush
339 // fails.
340 bool FlushAckFrame(const QuicFrames& frames);
341
342 // Adds a random amount of padding (between 1 to 256 bytes).
343 void AddRandomPadding();
344
345 // Attaches packet flusher.
346 void AttachPacketFlusher();
347
348 // Flushes everything, including current open packet and pending padding.
349 void Flush();
350
351 // Sends remaining pending padding.
352 // Pending paddings should only be sent when there is nothing else to send.
353 void SendRemainingPendingPadding();
354
355 // Set the minimum number of bytes for the server connection id length;
356 void SetServerConnectionIdLength(uint32_t length);
357
358 // Set transmission type of next constructed packets.
359 void SetTransmissionType(TransmissionType type);
360
361 // Tries to add a message frame containing |message| and returns the status.
362 MessageStatus AddMessageFrame(QuicMessageId message_id,
363 QuicMemSliceSpan message);
364
QUICHE teama6ef0a62019-03-07 20:34:33 -0500365 // Returns the largest payload that will fit into a single MESSAGE frame.
ianswettb239f862019-04-05 09:15:06 -0700366 QuicPacketLength GetCurrentLargestMessagePayload() const;
367 // Returns the largest payload that will fit into a single MESSAGE frame at
368 // any point during the connection. This assumes the version and
369 // connection ID lengths do not change.
370 QuicPacketLength GetGuaranteedLargestMessagePayload() const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500371
fayang354c9422019-05-21 08:10:35 -0700372 // Packet number of next created packet.
373 QuicPacketNumber NextSendingPacketNumber() const;
374
QUICHE teama6ef0a62019-03-07 20:34:33 -0500375 void set_debug_delegate(DebugDelegate* debug_delegate) {
376 debug_delegate_ = debug_delegate;
377 }
378
QUICHE teama6ef0a62019-03-07 20:34:33 -0500379 QuicByteCount pending_padding_bytes() const { return pending_padding_bytes_; }
380
381 QuicTransportVersion transport_version() const {
382 return framer_->transport_version();
383 }
384
nharper55fa6132019-05-07 19:37:21 -0700385 // Returns the minimum size that the plaintext of a packet must be.
QUICHE team2252b702019-05-14 23:55:14 -0400386 static size_t MinPlaintextPacketSize(const ParsedQuicVersion& version);
nharper55fa6132019-05-07 19:37:21 -0700387
fayang18be79a2019-09-16 15:17:12 -0700388 // Indicates whether packet flusher is currently attached.
389 bool PacketFlusherAttached() const;
390
nharper3907ac22019-09-25 15:32:28 -0700391 void set_fully_pad_crypto_handshake_packets(bool new_value) {
fayang18be79a2019-09-16 15:17:12 -0700392 fully_pad_crypto_handshake_packets_ = new_value;
393 }
394
395 bool fully_pad_crypto_handshake_packets() const {
fayang18be79a2019-09-16 15:17:12 -0700396 return fully_pad_crypto_handshake_packets_;
397 }
398
renjietang4c704c82019-10-07 16:39:11 -0700399 // Serialize a probing packet that uses IETF QUIC's PATH CHALLENGE frame. Also
400 // fills the packet with padding.
401 size_t BuildPaddedPathChallengePacket(const QuicPacketHeader& header,
402 char* buffer,
403 size_t packet_length,
404 QuicPathFrameBuffer* payload,
405 QuicRandom* randomizer,
406 EncryptionLevel level);
407
408 // Serialize a probing response packet that uses IETF QUIC's PATH RESPONSE
409 // frame. Also fills the packet with padding if |is_padded| is
410 // true. |payloads| is always emptied, even if the packet can not be
411 // successfully built.
wuba750aab2020-02-10 06:43:15 -0800412 size_t BuildPathResponsePacket(
413 const QuicPacketHeader& header,
414 char* buffer,
415 size_t packet_length,
416 const QuicCircularDeque<QuicPathFrameBuffer>& payloads,
417 const bool is_padded,
418 EncryptionLevel level);
renjietang4c704c82019-10-07 16:39:11 -0700419
420 // Serializes a probing packet, which is a padded PING packet. Returns the
421 // length of the packet. Returns 0 if it fails to serialize.
422 size_t BuildConnectivityProbingPacket(const QuicPacketHeader& header,
423 char* buffer,
424 size_t packet_length,
425 EncryptionLevel level);
426
fayang08750832019-10-24 11:25:34 -0700427 // Serializes |coalesced| to provided |buffer|, returns coalesced packet
428 // length if serialization succeeds. Otherwise, returns 0.
429 size_t SerializeCoalescedPacket(const QuicCoalescedPacket& coalesced,
430 char* buffer,
431 size_t buffer_len);
432
dschinazi6458eb32020-06-23 12:38:41 -0700433 void set_disable_padding_override(bool should_disable_padding) {
434 disable_padding_override_ = should_disable_padding;
435 }
436
QUICHE teama6ef0a62019-03-07 20:34:33 -0500437 private:
438 friend class test::QuicPacketCreatorPeer;
439
440 // Creates a stream frame which fits into the current open packet. If
QUICHE teamf08778a2019-03-14 08:10:26 -0700441 // |data_size| is 0 and fin is true, the expected behavior is to consume
442 // the fin.
QUICHE teama6ef0a62019-03-07 20:34:33 -0500443 void CreateStreamFrame(QuicStreamId id,
QUICHE teamf08778a2019-03-14 08:10:26 -0700444 size_t data_size,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500445 QuicStreamOffset offset,
446 bool fin,
447 QuicFrame* frame);
448
449 // Creates a CRYPTO frame which fits into the current open packet. Returns
450 // false if there isn't enough room in the current open packet for a CRYPTO
451 // frame, and true if there is.
452 bool CreateCryptoFrame(EncryptionLevel level,
453 size_t write_length,
454 QuicStreamOffset offset,
455 QuicFrame* frame);
456
457 void FillPacketHeader(QuicPacketHeader* header);
458
QUICHE teama6ef0a62019-03-07 20:34:33 -0500459 // Adds a padding frame to the current packet (if there is space) when (1)
460 // current packet needs full padding or (2) there are pending paddings.
461 void MaybeAddPadding();
462
463 // Serializes all frames which have been added and adds any which should be
464 // retransmitted to packet_.retransmittable_frames. All frames must fit into
465 // a single packet.
wub8a5dafa2020-05-13 12:30:17 -0700466 // Fails if |encrypted_buffer_len| isn't long enough for the encrypted packet.
wub50d4c712020-05-19 15:48:28 -0700467 void SerializePacket(QuicOwnedPacketBuffer encrypted_buffer,
468 size_t encrypted_buffer_len);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500469
470 // Called after a new SerialiedPacket is created to call the delegate's
471 // OnSerializedPacket and reset state.
472 void OnSerializedPacket();
473
474 // Clears all fields of packet_ that should be cleared between serializations.
475 void ClearPacket();
476
fayang08750832019-10-24 11:25:34 -0700477 // Re-serialzes frames of ENCRYPTION_INITIAL packet in coalesced packet with
478 // the original packet's packet number and packet number length.
479 // |padding_size| indicates the size of necessary padding. Returns 0 if
480 // serialization fails.
481 size_t ReserializeInitialPacketInCoalescedPacket(
482 const SerializedPacket& packet,
483 size_t padding_size,
484 char* buffer,
485 size_t buffer_len);
486
renjietangdbe98342019-10-18 11:00:57 -0700487 // Tries to coalesce |frame| with the back of |queued_frames_|.
488 // Returns true on success.
489 bool MaybeCoalesceStreamFrame(const QuicStreamFrame& frame);
490
fayang2ab1e852019-11-04 11:24:36 -0800491 // Called to remove the soft max_packet_length and restores
492 // latched_hard_max_packet_length_ if the packet cannot accommodate a single
493 // frame. Returns true if the soft limit is successfully removed. Returns
494 // false if either there is no current soft limit or there are queued frames
495 // (such that the packet length cannot be changed).
496 bool RemoveSoftMaxPacketLength();
497
QUICHE teama6ef0a62019-03-07 20:34:33 -0500498 // Returns true if a diversification nonce should be included in the current
499 // packet's header.
500 bool IncludeNonceInPublicHeader() const;
501
502 // Returns true if version should be included in current packet's header.
503 bool IncludeVersionInHeader() const;
504
505 // Returns length of packet number to send over the wire.
506 // packet_.packet_number_length should never be read directly, use this
507 // function instead.
508 QuicPacketNumberLength GetPacketNumberLength() const;
509
nharper55fa6132019-05-07 19:37:21 -0700510 // Returns the size in bytes of the packet header.
511 size_t PacketHeaderSize() const;
512
QUICHE teama6ef0a62019-03-07 20:34:33 -0500513 // Returns whether the destination connection ID is sent over the wire.
514 QuicConnectionIdIncluded GetDestinationConnectionIdIncluded() const;
515
516 // Returns whether the source connection ID is sent over the wire.
517 QuicConnectionIdIncluded GetSourceConnectionIdIncluded() const;
518
519 // Returns length of the retry token variable length integer to send over the
520 // wire. Is non-zero for v99 IETF Initial packets.
521 QuicVariableLengthIntegerLength GetRetryTokenLengthLength() const;
522
523 // Returns the retry token to send over the wire, only sent in
524 // v99 IETF Initial packets.
dmcardlecf0bfcf2019-12-13 08:08:21 -0800525 quiche::QuicheStringPiece GetRetryToken() const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500526
527 // Returns length of the length variable length integer to send over the
528 // wire. Is non-zero for v99 IETF Initial, 0-RTT or Handshake packets.
529 QuicVariableLengthIntegerLength GetLengthLength() const;
530
ianswette28f0222019-04-04 13:31:22 -0700531 // Returns true if |frame| is a ClientHello.
532 bool StreamFrameIsClientHello(const QuicStreamFrame& frame) const;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500533
534 // Returns true if packet under construction has IETF long header.
535 bool HasIetfLongHeader() const;
536
537 // Does not own these delegates or the framer.
538 DelegateInterface* delegate_;
539 DebugDelegate* debug_delegate_;
540 QuicFramer* framer_;
541 QuicRandom* random_;
542
543 // Controls whether version should be included while serializing the packet.
544 // send_version_in_packet_ should never be read directly, use
545 // IncludeVersionInHeader() instead.
546 bool send_version_in_packet_;
547 // If true, then |diversification_nonce_| will be included in the header of
548 // all packets created at the initial encryption level.
549 bool have_diversification_nonce_;
550 DiversificationNonce diversification_nonce_;
551 // Maximum length including headers and encryption (UDP payload length.)
552 QuicByteCount max_packet_length_;
553 size_t max_plaintext_size_;
dschinazi7b9278c2019-05-20 07:36:21 -0700554 // Whether the server_connection_id is sent over the wire.
555 QuicConnectionIdIncluded server_connection_id_included_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500556
557 // Frames to be added to the next SerializedPacket
558 QuicFrames queued_frames_;
559
560 // packet_size should never be read directly, use PacketSize() instead.
561 // TODO(ianswett): Move packet_size_ into SerializedPacket once
562 // QuicEncryptedPacket has been flattened into SerializedPacket.
563 size_t packet_size_;
dschinazi7b9278c2019-05-20 07:36:21 -0700564 QuicConnectionId server_connection_id_;
dschinazi346b7ce2019-06-05 01:38:18 -0700565 QuicConnectionId client_connection_id_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500566
567 // Packet used to invoke OnSerializedPacket.
568 SerializedPacket packet_;
569
570 // Retry token to send over the wire in v99 IETF Initial packets.
vasilvvc48c8712019-03-11 13:38:16 -0700571 std::string retry_token_;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500572
573 // Pending padding bytes to send. Pending padding bytes will be sent in next
574 // packet(s) (after all other frames) if current constructed packet does not
575 // have room to send all of them.
576 QuicByteCount pending_padding_bytes_;
577
578 // Indicates whether current constructed packet needs full padding to max
579 // packet size. Please note, full padding does not consume pending padding
580 // bytes.
581 bool needs_full_padding_;
582
fayang18be79a2019-09-16 15:17:12 -0700583 // Transmission type of the next serialized packet.
584 TransmissionType next_transmission_type_;
585
586 // True if packet flusher is currently attached.
587 bool flusher_attached_;
588
589 // Whether crypto handshake packets should be fully padded.
590 bool fully_pad_crypto_handshake_packets_;
591
592 // Packet number of the first packet of a write operation. This gets set
593 // when the out-most flusher attaches and gets cleared when the out-most
594 // flusher detaches.
595 QuicPacketNumber write_start_packet_number_;
596
fayang2ab1e852019-11-04 11:24:36 -0800597 // If not 0, this latches the actual max_packet_length when
598 // SetSoftMaxPacketLength is called and max_packet_length_ gets
599 // set to a soft value.
600 QuicByteCount latched_hard_max_packet_length_;
dschinazied459c02020-05-07 16:12:23 -0700601
602 // The maximum length of a MESSAGE/DATAGRAM frame that our peer is willing to
603 // accept. There is no limit for QUIC_CRYPTO connections, but QUIC+TLS
604 // negotiates this during the handshake.
605 QuicByteCount max_datagram_frame_size_;
wub50d4c712020-05-19 15:48:28 -0700606
607 const bool avoid_leak_writer_buffer_ =
608 GetQuicReloadableFlag(quic_avoid_leak_writer_buffer);
fayang04bd30d2020-06-22 15:04:57 -0700609
610 const bool fix_min_crypto_frame_size_ =
611 GetQuicReloadableFlag(quic_fix_min_crypto_frame_size);
dschinazi6458eb32020-06-23 12:38:41 -0700612
613 // When true, this will override the padding generation code to disable it.
614 bool disable_padding_override_ = false;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500615};
616
617} // namespace quic
618
619#endif // QUICHE_QUIC_CORE_QUIC_PACKET_CREATOR_H_