OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 // | |
5 // Accumulates frames for the next packet until more frames no longer fit or | |
6 // it's time to create a packet from them. If multipath enabled, only creates | |
7 // packets on one path at the same time. Currently, next packet number is | |
8 // tracked per-path. | |
9 | |
10 #ifndef NET_QUIC_QUIC_PACKET_CREATOR_H_ | |
11 #define NET_QUIC_QUIC_PACKET_CREATOR_H_ | |
12 | |
13 #include <stddef.h> | |
14 | |
15 #include <memory> | |
16 #include <string> | |
17 #include <unordered_map> | |
18 #include <utility> | |
19 #include <vector> | |
20 | |
21 #include "base/macros.h" | |
22 #include "base/strings/string_piece.h" | |
23 #include "net/quic/quic_framer.h" | |
24 #include "net/quic/quic_protocol.h" | |
25 | |
26 namespace net { | |
27 namespace test { | |
28 class QuicPacketCreatorPeer; | |
29 } | |
30 | |
31 class QuicRandom; | |
32 | |
33 class NET_EXPORT_PRIVATE QuicPacketCreator { | |
34 public: | |
35 // A delegate interface for further processing serialized packet. | |
36 class NET_EXPORT_PRIVATE DelegateInterface | |
37 : public QuicConnectionCloseDelegateInterface { | |
38 public: | |
39 ~DelegateInterface() override {} | |
40 // Called when a packet is serialized. Delegate does not take the ownership | |
41 // of |serialized_packet|, but takes ownership of any frames it removes | |
42 // from |packet.retransmittable_frames|. | |
43 virtual void OnSerializedPacket(SerializedPacket* serialized_packet) = 0; | |
44 }; | |
45 | |
46 // Interface which gets callbacks from the QuicPacketCreator at interesting | |
47 // points. Implementations must not mutate the state of the creator | |
48 // as a result of these callbacks. | |
49 class NET_EXPORT_PRIVATE DebugDelegate { | |
50 public: | |
51 virtual ~DebugDelegate() {} | |
52 | |
53 // Called when a frame has been added to the current packet. | |
54 virtual void OnFrameAddedToPacket(const QuicFrame& frame) {} | |
55 }; | |
56 | |
57 // QuicRandom* required for packet entropy. | |
58 QuicPacketCreator(QuicConnectionId connection_id, | |
59 QuicFramer* framer, | |
60 QuicRandom* random_generator, | |
61 QuicBufferAllocator* buffer_allocator, | |
62 DelegateInterface* delegate); | |
63 | |
64 ~QuicPacketCreator(); | |
65 | |
66 // Makes the framer not serialize the protocol version in sent packets. | |
67 void StopSendingVersion(); | |
68 | |
69 // SetDiversificationNonce sets the nonce that will be sent in each public | |
70 // header of packets encrypted at the initial encryption level. Should only | |
71 // be called by servers. | |
72 void SetDiversificationNonce(const DiversificationNonce nonce); | |
73 | |
74 // Update the packet number length to use in future packets as soon as it | |
75 // can be safely changed. | |
76 // TODO(fayang): Directly set packet number length instead of compute it in | |
77 // creator. | |
78 void UpdatePacketNumberLength(QuicPacketNumber least_packet_awaited_by_peer, | |
79 QuicPacketCount max_packets_in_flight); | |
80 | |
81 // The overhead the framing will add for a packet with one frame. | |
82 static size_t StreamFramePacketOverhead( | |
83 QuicVersion version, | |
84 QuicConnectionIdLength connection_id_length, | |
85 bool include_version, | |
86 bool include_path_id, | |
87 bool include_diversification_nonce, | |
88 QuicPacketNumberLength packet_number_length, | |
89 QuicStreamOffset offset); | |
90 | |
91 // Returns false and flushes all pending frames if current open packet is | |
92 // full. | |
93 // If current packet is not full, converts a raw payload into a stream frame | |
94 // that fits into the open packet and adds it to the packet. | |
95 // The payload begins at |iov_offset| into the |iov|. | |
96 bool ConsumeData(QuicStreamId id, | |
97 QuicIOVector iov, | |
98 size_t iov_offset, | |
99 QuicStreamOffset offset, | |
100 bool fin, | |
101 bool needs_full_padding, | |
102 QuicFrame* frame); | |
103 | |
104 // Returns true if current open packet can accommodate more stream frames of | |
105 // stream |id| at |offset|, false otherwise. | |
106 bool HasRoomForStreamFrame(QuicStreamId id, QuicStreamOffset offset); | |
107 | |
108 // Re-serializes frames with the original packet's packet number length. | |
109 // Used for retransmitting packets to ensure they aren't too long. | |
110 void ReserializeAllFrames(const PendingRetransmission& retransmission, | |
111 char* buffer, | |
112 size_t buffer_len); | |
113 | |
114 // Serializes all added frames into a single packet and invokes the delegate_ | |
115 // to further process the SerializedPacket. | |
116 void Flush(); | |
117 | |
118 // Optimized method to create a QuicStreamFrame, serialize it, and encrypt it | |
119 // into |encrypted_buffer|. Adds the QuicStreamFrame to the returned | |
120 // SerializedPacket. Sets |num_bytes_consumed| to the number of bytes | |
121 // consumed to create the QuicStreamFrame. | |
122 void CreateAndSerializeStreamFrame(QuicStreamId id, | |
123 const QuicIOVector& iov, | |
124 QuicStreamOffset iov_offset, | |
125 QuicStreamOffset stream_offset, | |
126 bool fin, | |
127 QuicAckListenerInterface* listener, | |
128 char* encrypted_buffer, | |
129 size_t encrypted_buffer_len, | |
130 size_t* num_bytes_consumed); | |
131 | |
132 // Returns true if there are frames pending to be serialized. | |
133 bool HasPendingFrames() const; | |
134 | |
135 // Returns true if there are retransmittable frames pending to be serialized. | |
136 bool HasPendingRetransmittableFrames() const; | |
137 | |
138 // Returns the number of bytes which are available to be used by additional | |
139 // frames in the packet. Since stream frames are slightly smaller when they | |
140 // are the last frame in a packet, this method will return a different | |
141 // value than max_packet_size - PacketSize(), in this case. | |
142 size_t BytesFree(); | |
143 | |
144 // Returns the number of bytes that the packet will expand by if a new frame | |
145 // is added to the packet. If the last frame was a stream frame, it will | |
146 // expand slightly when a new frame is added, and this method returns the | |
147 // amount of expected expansion. | |
148 size_t ExpansionOnNewFrame() const; | |
149 | |
150 // Returns the number of bytes in the current packet, including the header, | |
151 // if serialized with the current frames. Adding a frame to the packet | |
152 // may change the serialized length of existing frames, as per the comment | |
153 // in BytesFree. | |
154 size_t PacketSize(); | |
155 | |
156 // Tries to add |frame| to the packet creator's list of frames to be | |
157 // serialized. If the frame does not fit into the current packet, flushes the | |
158 // packet and returns false. | |
159 bool AddSavedFrame(const QuicFrame& frame); | |
160 | |
161 // Identical to AddSavedFrame, but allows the frame to be padded. | |
162 bool AddPaddedSavedFrame(const QuicFrame& frame); | |
163 | |
164 // Adds |listener| to the next serialized packet and notifies the | |
165 // std::listener with |length| as the number of acked bytes. | |
166 void AddAckListener(QuicAckListenerInterface* listener, | |
167 QuicPacketLength length); | |
168 | |
169 // Creates a version negotiation packet which supports |supported_versions|. | |
170 // Caller owns the created packet. Also, sets the entropy hash of the | |
171 // serialized packet to a random bool and returns that value as a member of | |
172 // SerializedPacket. | |
173 QuicEncryptedPacket* SerializeVersionNegotiationPacket( | |
174 const QuicVersionVector& supported_versions); | |
175 | |
176 // Returns a dummy packet that is valid but contains no useful information. | |
177 static SerializedPacket NoPacket(); | |
178 | |
179 // Sets the encryption level that will be applied to new packets. | |
180 void set_encryption_level(EncryptionLevel level) { | |
181 packet_.encryption_level = level; | |
182 } | |
183 | |
184 // packet number of the last created packet, or 0 if no packets have been | |
185 // created. | |
186 QuicPacketNumber packet_number() const { return packet_.packet_number; } | |
187 | |
188 QuicConnectionIdLength connection_id_length() const { | |
189 return connection_id_length_; | |
190 } | |
191 | |
192 void set_connection_id_length(QuicConnectionIdLength length) { | |
193 connection_id_length_ = length; | |
194 } | |
195 | |
196 QuicByteCount max_packet_length() const { return max_packet_length_; } | |
197 | |
198 bool has_ack() const { return packet_.has_ack; } | |
199 | |
200 bool has_stop_waiting() const { return packet_.has_stop_waiting; } | |
201 | |
202 // Sets the encrypter to use for the encryption level and updates the max | |
203 // plaintext size. | |
204 void SetEncrypter(EncryptionLevel level, QuicEncrypter* encrypter); | |
205 | |
206 // Indicates whether the packet creator is in a state where it can change | |
207 // current maximum packet length. | |
208 bool CanSetMaxPacketLength() const; | |
209 | |
210 // Sets the maximum packet length. | |
211 void SetMaxPacketLength(QuicByteCount length); | |
212 | |
213 // Sets the path on which subsequent packets will be created. It is the | |
214 // caller's responsibility to guarantee no packet is under construction before | |
215 // calling this function. If |path_id| is different from current_path_, | |
216 // next_packet_number_length_ is recalculated. | |
217 void SetCurrentPath(QuicPathId path_id, | |
218 QuicPacketNumber least_packet_awaited_by_peer, | |
219 QuicPacketCount max_packets_in_flight); | |
220 | |
221 void set_debug_delegate(DebugDelegate* debug_delegate) { | |
222 debug_delegate_ = debug_delegate; | |
223 } | |
224 | |
225 private: | |
226 friend class test::QuicPacketCreatorPeer; | |
227 | |
228 // A QuicRandom wrapper that gets a bucket of entropy and distributes it | |
229 // bit-by-bit. Replenishes the bucket as needed. Not thread-safe. Expose this | |
230 // class if single bit randomness is needed elsewhere. | |
231 class QuicRandomBoolSource { | |
232 public: | |
233 // random: Source of entropy. Not owned. | |
234 explicit QuicRandomBoolSource(QuicRandom* random); | |
235 | |
236 ~QuicRandomBoolSource(); | |
237 | |
238 // Returns the next random bit from the bucket. | |
239 bool RandBool(); | |
240 | |
241 private: | |
242 // Source of entropy. | |
243 QuicRandom* random_; | |
244 // Stored random bits. | |
245 uint64_t bit_bucket_; | |
246 // The next available bit has "1" in the mask. Zero means empty bucket. | |
247 uint64_t bit_mask_; | |
248 | |
249 DISALLOW_COPY_AND_ASSIGN(QuicRandomBoolSource); | |
250 }; | |
251 | |
252 static bool ShouldRetransmit(const QuicFrame& frame); | |
253 | |
254 // Converts a raw payload to a frame which fits into the current open | |
255 // packet. The payload begins at |iov_offset| into the |iov|. | |
256 // If data is empty and fin is true, the expected behavior is to consume the | |
257 // fin but return 0. If any data is consumed, it will be copied into a | |
258 // new buffer that |frame| will point to and own. | |
259 void CreateStreamFrame(QuicStreamId id, | |
260 QuicIOVector iov, | |
261 size_t iov_offset, | |
262 QuicStreamOffset offset, | |
263 bool fin, | |
264 QuicFrame* frame); | |
265 | |
266 // Copies |length| bytes from iov starting at offset |iov_offset| into buffer. | |
267 // |iov| must be at least iov_offset+length total length and buffer must be | |
268 // at least |length| long. | |
269 static void CopyToBuffer(QuicIOVector iov, | |
270 size_t iov_offset, | |
271 size_t length, | |
272 char* buffer); | |
273 | |
274 // Updates packet number length on packet boundary. | |
275 void MaybeUpdatePacketNumberLength(); | |
276 | |
277 void FillPacketHeader(QuicPacketHeader* header); | |
278 | |
279 // Adds a |frame| if there is space and returns false and flushes all pending | |
280 // frames if there isn't room. If |save_retransmittable_frames| is true, | |
281 // saves the |frame| in the next SerializedPacket. | |
282 bool AddFrame(const QuicFrame& frame, bool save_retransmittable_frames); | |
283 | |
284 // Adds a padding frame to the current packet only if the current packet | |
285 // contains a handshake message, and there is sufficient room to fit a | |
286 // padding frame. | |
287 void MaybeAddPadding(); | |
288 | |
289 // Serializes all frames which have been added and adds any which should be | |
290 // retransmitted to packet_.retransmittable_frames. All frames must fit into | |
291 // a single packet. Sets the entropy hash of the serialized packet to a | |
292 // random bool. | |
293 // Fails if |buffer_len| isn't long enough for the encrypted packet. | |
294 void SerializePacket(char* encrypted_buffer, size_t buffer_len); | |
295 | |
296 // Called after a new SerialiedPacket is created to call the delegate's | |
297 // OnSerializedPacket and reset state. | |
298 void OnSerializedPacket(); | |
299 | |
300 // Clears all fields of packet_ that should be cleared between serializations. | |
301 void ClearPacket(); | |
302 | |
303 // Returns true if a diversification nonce should be included in the current | |
304 // packet's public header. | |
305 bool IncludeNonceInPublicHeader(); | |
306 | |
307 // Does not own these delegates or the framer. | |
308 DelegateInterface* delegate_; | |
309 DebugDelegate* debug_delegate_; | |
310 QuicFramer* framer_; | |
311 | |
312 QuicRandomBoolSource random_bool_source_; | |
313 QuicBufferAllocator* const buffer_allocator_; | |
314 | |
315 // Controls whether version should be included while serializing the packet. | |
316 bool send_version_in_packet_; | |
317 // Controls whether path id should be included while serializing the packet. | |
318 bool send_path_id_in_packet_; | |
319 // Staging variable to hold next packet number length. When sequence | |
320 // number length is to be changed, this variable holds the new length until | |
321 // a packet boundary, when the creator's packet_number_length_ can be changed | |
322 // to this new value. | |
323 QuicPacketNumberLength next_packet_number_length_; | |
324 // If true, then |nonce_for_public_header_| will be included in the public | |
325 // header of all packets created at the initial encryption level. | |
326 bool have_diversification_nonce_; | |
327 DiversificationNonce diversification_nonce_; | |
328 // Maximum length including headers and encryption (UDP payload length.) | |
329 QuicByteCount max_packet_length_; | |
330 size_t max_plaintext_size_; | |
331 // Length of connection_id to send over the wire. | |
332 QuicConnectionIdLength connection_id_length_; | |
333 | |
334 // Frames to be added to the next SerializedPacket | |
335 QuicFrames queued_frames_; | |
336 | |
337 // packet_size should never be read directly, use PacketSize() instead. | |
338 // TODO(ianswett): Move packet_size_ into SerializedPacket once | |
339 // QuicEncryptedPacket has been flattened into SerializedPacket. | |
340 size_t packet_size_; | |
341 QuicConnectionId connection_id_; | |
342 | |
343 // Packet used to invoke OnSerializedPacket. | |
344 SerializedPacket packet_; | |
345 | |
346 // Map mapping path_id to last sent packet number on the path. | |
347 std::unordered_map<QuicPathId, QuicPacketNumber> multipath_packet_number_; | |
348 | |
349 DISALLOW_COPY_AND_ASSIGN(QuicPacketCreator); | |
350 }; | |
351 | |
352 } // namespace net | |
353 | |
354 #endif // NET_QUIC_QUIC_PACKET_CREATOR_H_ | |
OLD | NEW |