blob: 210e24d94908b3aa513341eb9f5cec5cba314ba6 [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_generator.h"
6
7#include <cstdint>
8
9#include "net/third_party/quiche/src/quic/core/crypto/quic_random.h"
10#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
11#include "net/third_party/quiche/src/quic/core/quic_types.h"
12#include "net/third_party/quiche/src/quic/core/quic_utils.h"
13#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
fayang354c9422019-05-21 08:10:35 -070017#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050018
19namespace quic {
20
dschinazi7b9278c2019-05-20 07:36:21 -070021QuicPacketGenerator::QuicPacketGenerator(QuicConnectionId server_connection_id,
QUICHE teama6ef0a62019-03-07 20:34:33 -050022 QuicFramer* framer,
23 QuicRandom* random_generator,
24 DelegateInterface* delegate)
25 : delegate_(delegate),
dschinazi7b9278c2019-05-20 07:36:21 -070026 packet_creator_(server_connection_id, framer, random_generator, delegate),
QUICHE teama6ef0a62019-03-07 20:34:33 -050027 next_transmission_type_(NOT_RETRANSMISSION),
28 flusher_attached_(false),
QUICHE teama6ef0a62019-03-07 20:34:33 -050029 random_generator_(random_generator),
30 fully_pad_crypto_handshake_packets_(true),
fayang3203f252019-05-03 06:00:03 -070031 deprecate_queued_control_frames_(
fayang3203f252019-05-03 06:00:03 -070032 GetQuicReloadableFlag(quic_deprecate_queued_control_frames)) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050033
34QuicPacketGenerator::~QuicPacketGenerator() {
35 DeleteFrames(&queued_control_frames_);
36}
37
fayang3203f252019-05-03 06:00:03 -070038bool QuicPacketGenerator::ConsumeRetransmittableControlFrame(
39 const QuicFrame& frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050040 QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
41 << "Adding a control frame with no control frame id: " << frame;
fayang3203f252019-05-03 06:00:03 -070042 DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
fayanga4b37b22019-06-18 13:37:47 -070043 MaybeBundleAckOpportunistically();
fayang3203f252019-05-03 06:00:03 -070044 if (deprecate_queued_control_frames_) {
45 QUIC_RELOADABLE_FLAG_COUNT(quic_deprecate_queued_control_frames);
46 if (packet_creator_.HasPendingFrames()) {
47 if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) {
48 // There is pending frames and current frame fits.
49 return true;
50 }
51 }
52 DCHECK(!packet_creator_.HasPendingFrames());
53 if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
54 !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
55 NOT_HANDSHAKE)) {
56 // Do not check congestion window for ping or connection close frames.
57 return false;
58 }
59 const bool success =
60 packet_creator_.AddSavedFrame(frame, next_transmission_type_);
61 DCHECK(success);
62 return success;
63 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050064 queued_control_frames_.push_back(frame);
65 SendQueuedFrames(/*flush=*/false);
fayang3203f252019-05-03 06:00:03 -070066 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -050067}
68
69size_t QuicPacketGenerator::ConsumeCryptoData(EncryptionLevel level,
70 size_t write_length,
71 QuicStreamOffset offset) {
72 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
73 "generator tries to write crypto data.";
fayanga4b37b22019-06-18 13:37:47 -070074 MaybeBundleAckOpportunistically();
QUICHE teama6ef0a62019-03-07 20:34:33 -050075 // To make reasoning about crypto frames easier, we don't combine them with
76 // other retransmittable frames in a single packet.
77 // TODO(nharper): Once we have separate packet number spaces, everything
78 // should be driven by encryption level, and we should stop flushing in this
79 // spot.
80 const bool flush = packet_creator_.HasPendingRetransmittableFrames();
81 SendQueuedFrames(flush);
82
83 size_t total_bytes_consumed = 0;
84
85 while (total_bytes_consumed < write_length) {
86 QuicFrame frame;
87 if (!packet_creator_.ConsumeCryptoData(
88 level, write_length - total_bytes_consumed,
nharper51961cf2019-05-13 13:23:24 -070089 offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
90 next_transmission_type_, &frame)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050091 // The only pending data in the packet is non-retransmittable frames. I'm
92 // assuming here that they won't occupy so much of the packet that a
93 // CRYPTO frame won't fit.
94 QUIC_BUG << "Failed to ConsumeCryptoData at level " << level;
95 return 0;
96 }
97 total_bytes_consumed += frame.crypto_frame->data_length;
98
99 // TODO(ianswett): Move to having the creator flush itself when it's full.
100 packet_creator_.Flush();
101 }
102
103 // Don't allow the handshake to be bundled with other retransmittable frames.
104 SendQueuedFrames(/*flush=*/true);
105
106 return total_bytes_consumed;
107}
108
109QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
110 size_t write_length,
111 QuicStreamOffset offset,
112 StreamSendingState state) {
113 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
114 "generator tries to write stream data.";
115 bool has_handshake =
nharper46833c32019-05-15 21:33:05 -0700116 QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id);
fayanga4b37b22019-06-18 13:37:47 -0700117 MaybeBundleAckOpportunistically();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500118 bool fin = state != NO_FIN;
119 QUIC_BUG_IF(has_handshake && fin)
120 << "Handshake packets should never send a fin";
121 // To make reasoning about crypto frames easier, we don't combine them with
122 // other retransmittable frames in a single packet.
123 const bool flush =
124 has_handshake && packet_creator_.HasPendingRetransmittableFrames();
125 SendQueuedFrames(flush);
126
127 size_t total_bytes_consumed = 0;
128 bool fin_consumed = false;
129
130 if (!packet_creator_.HasRoomForStreamFrame(id, offset, write_length)) {
131 packet_creator_.Flush();
132 }
133
134 if (!fin && (write_length == 0)) {
135 QUIC_BUG << "Attempt to consume empty data without FIN.";
136 return QuicConsumedData(0, false);
137 }
138 // We determine if we can enter the fast path before executing
139 // the slow path loop.
dschinazi66dea072019-04-09 11:41:06 -0700140 bool run_fast_path =
141 !has_handshake && state != FIN_AND_PADDING && !HasQueuedFrames() &&
142 write_length - total_bytes_consumed > kMaxOutgoingPacketSize;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143
144 while (!run_fast_path && delegate_->ShouldGeneratePacket(
145 HAS_RETRANSMITTABLE_DATA,
146 has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
147 QuicFrame frame;
148 bool needs_full_padding =
149 has_handshake && fully_pad_crypto_handshake_packets_;
150
ianswette28f0222019-04-04 13:31:22 -0700151 if (!packet_creator_.ConsumeData(id, write_length - total_bytes_consumed,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500152 offset + total_bytes_consumed, fin,
153 needs_full_padding,
154 next_transmission_type_, &frame)) {
155 // The creator is always flushed if there's not enough room for a new
156 // stream frame before ConsumeData, so ConsumeData should always succeed.
157 QUIC_BUG << "Failed to ConsumeData, stream:" << id;
158 return QuicConsumedData(0, false);
159 }
160
161 // A stream frame is created and added.
162 size_t bytes_consumed = frame.stream_frame.data_length;
163 total_bytes_consumed += bytes_consumed;
164 fin_consumed = fin && total_bytes_consumed == write_length;
165 if (fin_consumed && state == FIN_AND_PADDING) {
166 AddRandomPadding();
167 }
168 DCHECK(total_bytes_consumed == write_length ||
169 (bytes_consumed > 0 && packet_creator_.HasPendingFrames()));
170
171 if (total_bytes_consumed == write_length) {
172 // We're done writing the data. Exit the loop.
173 // We don't make this a precondition because we could have 0 bytes of data
174 // if we're simply writing a fin.
175 break;
176 }
177 // TODO(ianswett): Move to having the creator flush itself when it's full.
178 packet_creator_.Flush();
179
dschinazi66dea072019-04-09 11:41:06 -0700180 run_fast_path =
181 !has_handshake && state != FIN_AND_PADDING && !HasQueuedFrames() &&
182 write_length - total_bytes_consumed > kMaxOutgoingPacketSize;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500183 }
184
185 if (run_fast_path) {
186 return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
187 total_bytes_consumed);
188 }
189
190 // Don't allow the handshake to be bundled with other retransmittable frames.
191 if (has_handshake) {
192 SendQueuedFrames(/*flush=*/true);
193 }
194
195 return QuicConsumedData(total_bytes_consumed, fin_consumed);
196}
197
198QuicConsumedData QuicPacketGenerator::ConsumeDataFastPath(
199 QuicStreamId id,
200 size_t write_length,
201 QuicStreamOffset offset,
202 bool fin,
203 size_t total_bytes_consumed) {
nharper46833c32019-05-15 21:33:05 -0700204 DCHECK(!QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500205
206 while (total_bytes_consumed < write_length &&
207 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
208 NOT_HANDSHAKE)) {
209 // Serialize and encrypt the packet.
210 size_t bytes_consumed = 0;
211 packet_creator_.CreateAndSerializeStreamFrame(
212 id, write_length, total_bytes_consumed, offset + total_bytes_consumed,
213 fin, next_transmission_type_, &bytes_consumed);
214 total_bytes_consumed += bytes_consumed;
215 }
216
217 return QuicConsumedData(total_bytes_consumed,
218 fin && (total_bytes_consumed == write_length));
219}
220
221void QuicPacketGenerator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
222 // MTU discovery frames must be sent by themselves.
223 if (!packet_creator_.CanSetMaxPacketLength()) {
224 QUIC_BUG << "MTU discovery packets should only be sent when no other "
225 << "frames needs to be sent.";
226 return;
227 }
228 const QuicByteCount current_mtu = GetCurrentMaxPacketLength();
229
230 // The MTU discovery frame is allocated on the stack, since it is going to be
231 // serialized within this function.
232 QuicMtuDiscoveryFrame mtu_discovery_frame;
233 QuicFrame frame(mtu_discovery_frame);
234
235 // Send the probe packet with the new length.
236 SetMaxPacketLength(target_mtu);
237 const bool success =
238 packet_creator_.AddPaddedSavedFrame(frame, next_transmission_type_);
239 packet_creator_.Flush();
240 // The only reason AddFrame can fail is that the packet is too full to fit in
241 // a ping. This is not possible for any sane MTU.
242 DCHECK(success);
243
244 // Reset the packet length back.
245 SetMaxPacketLength(current_mtu);
246}
247
248bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
249 DCHECK(HasPendingFrames() || packet_creator_.pending_padding_bytes() > 0);
250 HasRetransmittableData retransmittable =
fayanga4b37b22019-06-18 13:37:47 -0700251 packet_creator_.pending_padding_bytes() > 0 ? NO_RETRANSMITTABLE_DATA
252 : HAS_RETRANSMITTABLE_DATA;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500253 if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
254 DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
255 }
256 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE);
257}
258
259void QuicPacketGenerator::SendQueuedFrames(bool flush) {
260 // Only add pending frames if we are SURE we can then send the whole packet.
261 while (HasPendingFrames() &&
262 (flush || CanSendWithNextPendingFrameAddition())) {
263 bool first_frame = packet_creator_.CanSetMaxPacketLength();
264 if (!AddNextPendingFrame() && first_frame) {
265 // A single frame cannot fit into the packet, tear down the connection.
266 QUIC_BUG << "A single frame cannot fit into packet."
QUICHE teama6ef0a62019-03-07 20:34:33 -0500267 << " number of queued_control_frames: "
268 << queued_control_frames_.size();
269 if (!queued_control_frames_.empty()) {
270 QUIC_LOG(INFO) << queued_control_frames_[0];
271 }
272 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
fkastenholz85f18902019-05-28 12:47:00 -0700273 "Single frame cannot fit into a packet");
QUICHE teama6ef0a62019-03-07 20:34:33 -0500274 return;
275 }
276 }
277 if (flush) {
278 packet_creator_.Flush();
279 }
280}
281
282bool QuicPacketGenerator::PacketFlusherAttached() const {
283 return flusher_attached_;
284}
285
286void QuicPacketGenerator::AttachPacketFlusher() {
287 flusher_attached_ = true;
fayang354c9422019-05-21 08:10:35 -0700288 if (!write_start_packet_number_.IsInitialized()) {
289 write_start_packet_number_ = packet_creator_.NextSendingPacketNumber();
290 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500291}
292
293void QuicPacketGenerator::Flush() {
294 SendQueuedFrames(/*flush=*/false);
295 packet_creator_.Flush();
296 SendRemainingPendingPadding();
297 flusher_attached_ = false;
fayang354c9422019-05-21 08:10:35 -0700298 if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
299 if (!write_start_packet_number_.IsInitialized()) {
300 QUIC_BUG << "write_start_packet_number is not initialized";
301 return;
302 }
303 QUIC_SERVER_HISTOGRAM_COUNTS(
304 "quic_server_num_written_packets_per_write",
305 packet_creator_.NextSendingPacketNumber() - write_start_packet_number_,
306 1, 200, 50, "Number of QUIC packets written per write operation");
307 }
308 write_start_packet_number_.Clear();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500309}
310
311void QuicPacketGenerator::FlushAllQueuedFrames() {
312 SendQueuedFrames(/*flush=*/true);
313}
314
315bool QuicPacketGenerator::HasQueuedFrames() const {
316 return packet_creator_.HasPendingFrames() || HasPendingFrames();
317}
318
319bool QuicPacketGenerator::IsPendingPacketEmpty() const {
320 return !packet_creator_.HasPendingFrames();
321}
322
323bool QuicPacketGenerator::HasPendingFrames() const {
fayanga4b37b22019-06-18 13:37:47 -0700324 return !queued_control_frames_.empty();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500325}
326
327bool QuicPacketGenerator::AddNextPendingFrame() {
328 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
329 "generator tries to write control frames.";
QUICHE teama6ef0a62019-03-07 20:34:33 -0500330 QUIC_BUG_IF(queued_control_frames_.empty())
331 << "AddNextPendingFrame called with no queued control frames.";
332
333 if (!packet_creator_.AddSavedFrame(queued_control_frames_.back(),
334 next_transmission_type_)) {
335 // Packet was full.
336 return false;
337 }
338 queued_control_frames_.pop_back();
339 return true;
340}
341
342void QuicPacketGenerator::StopSendingVersion() {
343 packet_creator_.StopSendingVersion();
344}
345
346void QuicPacketGenerator::SetDiversificationNonce(
347 const DiversificationNonce& nonce) {
348 packet_creator_.SetDiversificationNonce(nonce);
349}
350
351QuicPacketNumber QuicPacketGenerator::packet_number() const {
352 return packet_creator_.packet_number();
353}
354
355QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const {
356 return packet_creator_.max_packet_length();
357}
358
359void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) {
360 DCHECK(packet_creator_.CanSetMaxPacketLength());
361 packet_creator_.SetMaxPacketLength(length);
362}
363
364std::unique_ptr<QuicEncryptedPacket>
365QuicPacketGenerator::SerializeVersionNegotiationPacket(
366 bool ietf_quic,
367 const ParsedQuicVersionVector& supported_versions) {
368 return packet_creator_.SerializeVersionNegotiationPacket(ietf_quic,
369 supported_versions);
370}
371
372OwningSerializedPacketPointer
373QuicPacketGenerator::SerializeConnectivityProbingPacket() {
374 return packet_creator_.SerializeConnectivityProbingPacket();
375}
376
377OwningSerializedPacketPointer
378QuicPacketGenerator::SerializePathChallengeConnectivityProbingPacket(
379 QuicPathFrameBuffer* payload) {
380 return packet_creator_.SerializePathChallengeConnectivityProbingPacket(
381 payload);
382}
383
384OwningSerializedPacketPointer
385QuicPacketGenerator::SerializePathResponseConnectivityProbingPacket(
386 const QuicDeque<QuicPathFrameBuffer>& payloads,
387 const bool is_padded) {
388 return packet_creator_.SerializePathResponseConnectivityProbingPacket(
389 payloads, is_padded);
390}
391
392void QuicPacketGenerator::ReserializeAllFrames(
393 const QuicPendingRetransmission& retransmission,
394 char* buffer,
395 size_t buffer_len) {
396 packet_creator_.ReserializeAllFrames(retransmission, buffer, buffer_len);
397}
398
399void QuicPacketGenerator::UpdatePacketNumberLength(
400 QuicPacketNumber least_packet_awaited_by_peer,
401 QuicPacketCount max_packets_in_flight) {
402 return packet_creator_.UpdatePacketNumberLength(least_packet_awaited_by_peer,
403 max_packets_in_flight);
404}
405
dschinazi7b9278c2019-05-20 07:36:21 -0700406void QuicPacketGenerator::SetServerConnectionIdLength(uint32_t length) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500407 if (length == 0) {
dschinazi7b9278c2019-05-20 07:36:21 -0700408 packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500409 } else {
dschinazi7b9278c2019-05-20 07:36:21 -0700410 packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500411 }
412}
413
414void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
415 packet_creator_.set_encryption_level(level);
416}
417
418void QuicPacketGenerator::SetEncrypter(
419 EncryptionLevel level,
420 std::unique_ptr<QuicEncrypter> encrypter) {
421 packet_creator_.SetEncrypter(level, std::move(encrypter));
422}
423
424void QuicPacketGenerator::AddRandomPadding() {
425 packet_creator_.AddPendingPadding(
426 random_generator_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
427}
428
429void QuicPacketGenerator::SendRemainingPendingPadding() {
430 while (packet_creator_.pending_padding_bytes() > 0 && !HasQueuedFrames() &&
431 CanSendWithNextPendingFrameAddition()) {
432 packet_creator_.Flush();
433 }
434}
435
436bool QuicPacketGenerator::HasRetransmittableFrames() const {
437 return !queued_control_frames_.empty() ||
438 packet_creator_.HasPendingRetransmittableFrames();
439}
440
441bool QuicPacketGenerator::HasPendingStreamFramesOfStream(
442 QuicStreamId id) const {
443 return packet_creator_.HasPendingStreamFramesOfStream(id);
444}
445
446void QuicPacketGenerator::SetTransmissionType(TransmissionType type) {
447 packet_creator_.SetTransmissionType(type);
wub98669f52019-04-18 10:49:18 -0700448 if (packet_creator_.can_set_transmission_type()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500449 next_transmission_type_ = type;
450 }
451}
452
dschinazi244f6dc2019-05-06 15:45:16 -0700453void QuicPacketGenerator::SetRetryToken(QuicStringPiece retry_token) {
454 packet_creator_.SetRetryToken(retry_token);
455}
456
QUICHE teama6ef0a62019-03-07 20:34:33 -0500457void QuicPacketGenerator::SetCanSetTransmissionType(
458 bool can_set_transmission_type) {
459 packet_creator_.set_can_set_transmission_type(can_set_transmission_type);
460}
461
462MessageStatus QuicPacketGenerator::AddMessageFrame(QuicMessageId message_id,
463 QuicMemSliceSpan message) {
464 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
465 "generator tries to add message frame.";
fayanga4b37b22019-06-18 13:37:47 -0700466 MaybeBundleAckOpportunistically();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500467 const QuicByteCount message_length = message.total_length();
ianswettb239f862019-04-05 09:15:06 -0700468 if (message_length > GetCurrentLargestMessagePayload()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500469 return MESSAGE_STATUS_TOO_LARGE;
470 }
471 SendQueuedFrames(/*flush=*/false);
472 if (!packet_creator_.HasRoomForMessageFrame(message_length)) {
473 packet_creator_.Flush();
474 }
wub553a9662019-03-28 20:13:23 -0700475 QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500476 const bool success =
477 packet_creator_.AddSavedFrame(QuicFrame(frame), next_transmission_type_);
478 if (!success) {
479 QUIC_BUG << "Failed to send message " << message_id;
480 delete frame;
481 return MESSAGE_STATUS_INTERNAL_ERROR;
482 }
483 return MESSAGE_STATUS_SUCCESS;
484}
485
486void QuicPacketGenerator::MaybeBundleAckOpportunistically() {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500487 if (packet_creator_.has_ack()) {
488 // Ack already queued, nothing to do.
489 return;
490 }
491 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
492 NOT_HANDSHAKE)) {
493 return;
494 }
495 const bool flushed =
496 FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
497 DCHECK(flushed);
498}
499
500bool QuicPacketGenerator::FlushAckFrame(const QuicFrames& frames) {
501 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
502 "generator tries to send ACK frame.";
503 for (const auto& frame : frames) {
504 DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME);
505 if (packet_creator_.HasPendingFrames()) {
506 if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) {
507 // There is pending frames and current frame fits.
508 continue;
509 }
510 }
511 DCHECK(!packet_creator_.HasPendingFrames());
512 // There is no pending frames, consult the delegate whether a packet can be
513 // generated.
514 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
515 NOT_HANDSHAKE)) {
516 return false;
517 }
518 const bool success =
519 packet_creator_.AddSavedFrame(frame, next_transmission_type_);
520 QUIC_BUG_IF(!success) << "Failed to flush " << frame;
521 }
522 return true;
523}
524
ianswettb239f862019-04-05 09:15:06 -0700525QuicPacketLength QuicPacketGenerator::GetCurrentLargestMessagePayload() const {
526 return packet_creator_.GetCurrentLargestMessagePayload();
527}
528
529QuicPacketLength QuicPacketGenerator::GetGuaranteedLargestMessagePayload()
530 const {
531 return packet_creator_.GetGuaranteedLargestMessagePayload();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500532}
533
dschinazi7b9278c2019-05-20 07:36:21 -0700534void QuicPacketGenerator::SetServerConnectionId(
535 QuicConnectionId server_connection_id) {
536 packet_creator_.SetServerConnectionId(server_connection_id);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700537}
538
dschinazi346b7ce2019-06-05 01:38:18 -0700539void QuicPacketGenerator::SetClientConnectionId(
540 QuicConnectionId client_connection_id) {
541 packet_creator_.SetClientConnectionId(client_connection_id);
542}
543
QUICHE teama6ef0a62019-03-07 20:34:33 -0500544} // namespace quic