blob: 6f578f5f36dc66a077f6265a25251f51501caf63 [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),
29 should_send_ack_(false),
30 should_send_stop_waiting_(false),
31 random_generator_(random_generator),
32 fully_pad_crypto_handshake_packets_(true),
33 deprecate_ack_bundling_mode_(
fayang3203f252019-05-03 06:00:03 -070034 GetQuicReloadableFlag(quic_deprecate_ack_bundling_mode)),
35 deprecate_queued_control_frames_(
36 deprecate_ack_bundling_mode_ &&
37 GetQuicReloadableFlag(quic_deprecate_queued_control_frames)) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -050038
39QuicPacketGenerator::~QuicPacketGenerator() {
40 DeleteFrames(&queued_control_frames_);
41}
42
43void QuicPacketGenerator::SetShouldSendAck(bool also_send_stop_waiting) {
44 DCHECK(!deprecate_ack_bundling_mode_);
45 if (packet_creator_.has_ack()) {
46 // Ack already queued, nothing to do.
47 return;
48 }
49
50 if (also_send_stop_waiting && packet_creator_.has_stop_waiting()) {
51 QUIC_BUG << "Should only ever be one pending stop waiting frame.";
52 return;
53 }
54
55 should_send_ack_ = true;
56 should_send_stop_waiting_ = also_send_stop_waiting;
57 SendQueuedFrames(/*flush=*/false);
58}
59
fayang3203f252019-05-03 06:00:03 -070060bool QuicPacketGenerator::ConsumeRetransmittableControlFrame(
61 const QuicFrame& frame) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050062 QUIC_BUG_IF(IsControlFrame(frame.type) && !GetControlFrameId(frame))
63 << "Adding a control frame with no control frame id: " << frame;
fayang3203f252019-05-03 06:00:03 -070064 DCHECK(QuicUtils::IsRetransmittableFrame(frame.type)) << frame;
QUICHE teama6ef0a62019-03-07 20:34:33 -050065 if (deprecate_ack_bundling_mode_) {
66 MaybeBundleAckOpportunistically();
67 }
fayang3203f252019-05-03 06:00:03 -070068 if (deprecate_queued_control_frames_) {
69 QUIC_RELOADABLE_FLAG_COUNT(quic_deprecate_queued_control_frames);
70 if (packet_creator_.HasPendingFrames()) {
71 if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) {
72 // There is pending frames and current frame fits.
73 return true;
74 }
75 }
76 DCHECK(!packet_creator_.HasPendingFrames());
77 if (frame.type != PING_FRAME && frame.type != CONNECTION_CLOSE_FRAME &&
78 !delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
79 NOT_HANDSHAKE)) {
80 // Do not check congestion window for ping or connection close frames.
81 return false;
82 }
83 const bool success =
84 packet_creator_.AddSavedFrame(frame, next_transmission_type_);
85 DCHECK(success);
86 return success;
87 }
QUICHE teama6ef0a62019-03-07 20:34:33 -050088 queued_control_frames_.push_back(frame);
89 SendQueuedFrames(/*flush=*/false);
fayang3203f252019-05-03 06:00:03 -070090 return true;
QUICHE teama6ef0a62019-03-07 20:34:33 -050091}
92
93size_t QuicPacketGenerator::ConsumeCryptoData(EncryptionLevel level,
94 size_t write_length,
95 QuicStreamOffset offset) {
96 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
97 "generator tries to write crypto data.";
98 if (deprecate_ack_bundling_mode_) {
99 MaybeBundleAckOpportunistically();
100 }
101 // To make reasoning about crypto frames easier, we don't combine them with
102 // other retransmittable frames in a single packet.
103 // TODO(nharper): Once we have separate packet number spaces, everything
104 // should be driven by encryption level, and we should stop flushing in this
105 // spot.
106 const bool flush = packet_creator_.HasPendingRetransmittableFrames();
107 SendQueuedFrames(flush);
108
109 size_t total_bytes_consumed = 0;
110
111 while (total_bytes_consumed < write_length) {
112 QuicFrame frame;
113 if (!packet_creator_.ConsumeCryptoData(
114 level, write_length - total_bytes_consumed,
nharper51961cf2019-05-13 13:23:24 -0700115 offset + total_bytes_consumed, fully_pad_crypto_handshake_packets_,
116 next_transmission_type_, &frame)) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500117 // The only pending data in the packet is non-retransmittable frames. I'm
118 // assuming here that they won't occupy so much of the packet that a
119 // CRYPTO frame won't fit.
120 QUIC_BUG << "Failed to ConsumeCryptoData at level " << level;
121 return 0;
122 }
123 total_bytes_consumed += frame.crypto_frame->data_length;
124
125 // TODO(ianswett): Move to having the creator flush itself when it's full.
126 packet_creator_.Flush();
127 }
128
129 // Don't allow the handshake to be bundled with other retransmittable frames.
130 SendQueuedFrames(/*flush=*/true);
131
132 return total_bytes_consumed;
133}
134
135QuicConsumedData QuicPacketGenerator::ConsumeData(QuicStreamId id,
136 size_t write_length,
137 QuicStreamOffset offset,
138 StreamSendingState state) {
139 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
140 "generator tries to write stream data.";
141 bool has_handshake =
nharper46833c32019-05-15 21:33:05 -0700142 QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500143 if (deprecate_ack_bundling_mode_) {
144 MaybeBundleAckOpportunistically();
145 }
146 bool fin = state != NO_FIN;
147 QUIC_BUG_IF(has_handshake && fin)
148 << "Handshake packets should never send a fin";
149 // To make reasoning about crypto frames easier, we don't combine them with
150 // other retransmittable frames in a single packet.
151 const bool flush =
152 has_handshake && packet_creator_.HasPendingRetransmittableFrames();
153 SendQueuedFrames(flush);
154
155 size_t total_bytes_consumed = 0;
156 bool fin_consumed = false;
157
158 if (!packet_creator_.HasRoomForStreamFrame(id, offset, write_length)) {
159 packet_creator_.Flush();
160 }
161
162 if (!fin && (write_length == 0)) {
163 QUIC_BUG << "Attempt to consume empty data without FIN.";
164 return QuicConsumedData(0, false);
165 }
166 // We determine if we can enter the fast path before executing
167 // the slow path loop.
dschinazi66dea072019-04-09 11:41:06 -0700168 bool run_fast_path =
169 !has_handshake && state != FIN_AND_PADDING && !HasQueuedFrames() &&
170 write_length - total_bytes_consumed > kMaxOutgoingPacketSize;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171
172 while (!run_fast_path && delegate_->ShouldGeneratePacket(
173 HAS_RETRANSMITTABLE_DATA,
174 has_handshake ? IS_HANDSHAKE : NOT_HANDSHAKE)) {
175 QuicFrame frame;
176 bool needs_full_padding =
177 has_handshake && fully_pad_crypto_handshake_packets_;
178
ianswette28f0222019-04-04 13:31:22 -0700179 if (!packet_creator_.ConsumeData(id, write_length - total_bytes_consumed,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500180 offset + total_bytes_consumed, fin,
181 needs_full_padding,
182 next_transmission_type_, &frame)) {
183 // The creator is always flushed if there's not enough room for a new
184 // stream frame before ConsumeData, so ConsumeData should always succeed.
185 QUIC_BUG << "Failed to ConsumeData, stream:" << id;
186 return QuicConsumedData(0, false);
187 }
188
189 // A stream frame is created and added.
190 size_t bytes_consumed = frame.stream_frame.data_length;
191 total_bytes_consumed += bytes_consumed;
192 fin_consumed = fin && total_bytes_consumed == write_length;
193 if (fin_consumed && state == FIN_AND_PADDING) {
194 AddRandomPadding();
195 }
196 DCHECK(total_bytes_consumed == write_length ||
197 (bytes_consumed > 0 && packet_creator_.HasPendingFrames()));
198
199 if (total_bytes_consumed == write_length) {
200 // We're done writing the data. Exit the loop.
201 // We don't make this a precondition because we could have 0 bytes of data
202 // if we're simply writing a fin.
203 break;
204 }
205 // TODO(ianswett): Move to having the creator flush itself when it's full.
206 packet_creator_.Flush();
207
dschinazi66dea072019-04-09 11:41:06 -0700208 run_fast_path =
209 !has_handshake && state != FIN_AND_PADDING && !HasQueuedFrames() &&
210 write_length - total_bytes_consumed > kMaxOutgoingPacketSize;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500211 }
212
213 if (run_fast_path) {
214 return ConsumeDataFastPath(id, write_length, offset, state != NO_FIN,
215 total_bytes_consumed);
216 }
217
218 // Don't allow the handshake to be bundled with other retransmittable frames.
219 if (has_handshake) {
220 SendQueuedFrames(/*flush=*/true);
221 }
222
223 return QuicConsumedData(total_bytes_consumed, fin_consumed);
224}
225
226QuicConsumedData QuicPacketGenerator::ConsumeDataFastPath(
227 QuicStreamId id,
228 size_t write_length,
229 QuicStreamOffset offset,
230 bool fin,
231 size_t total_bytes_consumed) {
nharper46833c32019-05-15 21:33:05 -0700232 DCHECK(!QuicUtils::IsCryptoStreamId(packet_creator_.transport_version(), id));
QUICHE teama6ef0a62019-03-07 20:34:33 -0500233
234 while (total_bytes_consumed < write_length &&
235 delegate_->ShouldGeneratePacket(HAS_RETRANSMITTABLE_DATA,
236 NOT_HANDSHAKE)) {
237 // Serialize and encrypt the packet.
238 size_t bytes_consumed = 0;
239 packet_creator_.CreateAndSerializeStreamFrame(
240 id, write_length, total_bytes_consumed, offset + total_bytes_consumed,
241 fin, next_transmission_type_, &bytes_consumed);
242 total_bytes_consumed += bytes_consumed;
243 }
244
245 return QuicConsumedData(total_bytes_consumed,
246 fin && (total_bytes_consumed == write_length));
247}
248
249void QuicPacketGenerator::GenerateMtuDiscoveryPacket(QuicByteCount target_mtu) {
250 // MTU discovery frames must be sent by themselves.
251 if (!packet_creator_.CanSetMaxPacketLength()) {
252 QUIC_BUG << "MTU discovery packets should only be sent when no other "
253 << "frames needs to be sent.";
254 return;
255 }
256 const QuicByteCount current_mtu = GetCurrentMaxPacketLength();
257
258 // The MTU discovery frame is allocated on the stack, since it is going to be
259 // serialized within this function.
260 QuicMtuDiscoveryFrame mtu_discovery_frame;
261 QuicFrame frame(mtu_discovery_frame);
262
263 // Send the probe packet with the new length.
264 SetMaxPacketLength(target_mtu);
265 const bool success =
266 packet_creator_.AddPaddedSavedFrame(frame, next_transmission_type_);
267 packet_creator_.Flush();
268 // The only reason AddFrame can fail is that the packet is too full to fit in
269 // a ping. This is not possible for any sane MTU.
270 DCHECK(success);
271
272 // Reset the packet length back.
273 SetMaxPacketLength(current_mtu);
274}
275
276bool QuicPacketGenerator::CanSendWithNextPendingFrameAddition() const {
277 DCHECK(HasPendingFrames() || packet_creator_.pending_padding_bytes() > 0);
278 HasRetransmittableData retransmittable =
279 (should_send_ack_ || should_send_stop_waiting_ ||
280 packet_creator_.pending_padding_bytes() > 0)
281 ? NO_RETRANSMITTABLE_DATA
282 : HAS_RETRANSMITTABLE_DATA;
283 if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
284 DCHECK(!queued_control_frames_.empty()); // These are retransmittable.
285 }
286 return delegate_->ShouldGeneratePacket(retransmittable, NOT_HANDSHAKE);
287}
288
289void QuicPacketGenerator::SendQueuedFrames(bool flush) {
290 // Only add pending frames if we are SURE we can then send the whole packet.
291 while (HasPendingFrames() &&
292 (flush || CanSendWithNextPendingFrameAddition())) {
293 bool first_frame = packet_creator_.CanSetMaxPacketLength();
294 if (!AddNextPendingFrame() && first_frame) {
295 // A single frame cannot fit into the packet, tear down the connection.
296 QUIC_BUG << "A single frame cannot fit into packet."
297 << " should_send_ack: " << should_send_ack_
298 << " should_send_stop_waiting: " << should_send_stop_waiting_
299 << " number of queued_control_frames: "
300 << queued_control_frames_.size();
301 if (!queued_control_frames_.empty()) {
302 QUIC_LOG(INFO) << queued_control_frames_[0];
303 }
304 delegate_->OnUnrecoverableError(QUIC_FAILED_TO_SERIALIZE_PACKET,
305 "Single frame cannot fit into a packet",
306 ConnectionCloseSource::FROM_SELF);
307 return;
308 }
309 }
310 if (flush) {
311 packet_creator_.Flush();
312 }
313}
314
315bool QuicPacketGenerator::PacketFlusherAttached() const {
316 return flusher_attached_;
317}
318
319void QuicPacketGenerator::AttachPacketFlusher() {
320 flusher_attached_ = true;
fayang354c9422019-05-21 08:10:35 -0700321 if (!write_start_packet_number_.IsInitialized()) {
322 write_start_packet_number_ = packet_creator_.NextSendingPacketNumber();
323 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500324}
325
326void QuicPacketGenerator::Flush() {
327 SendQueuedFrames(/*flush=*/false);
328 packet_creator_.Flush();
329 SendRemainingPendingPadding();
330 flusher_attached_ = false;
fayang354c9422019-05-21 08:10:35 -0700331 if (GetQuicFlag(FLAGS_quic_export_server_num_packets_per_write_histogram)) {
332 if (!write_start_packet_number_.IsInitialized()) {
333 QUIC_BUG << "write_start_packet_number is not initialized";
334 return;
335 }
336 QUIC_SERVER_HISTOGRAM_COUNTS(
337 "quic_server_num_written_packets_per_write",
338 packet_creator_.NextSendingPacketNumber() - write_start_packet_number_,
339 1, 200, 50, "Number of QUIC packets written per write operation");
340 }
341 write_start_packet_number_.Clear();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500342}
343
344void QuicPacketGenerator::FlushAllQueuedFrames() {
345 SendQueuedFrames(/*flush=*/true);
346}
347
348bool QuicPacketGenerator::HasQueuedFrames() const {
349 return packet_creator_.HasPendingFrames() || HasPendingFrames();
350}
351
352bool QuicPacketGenerator::IsPendingPacketEmpty() const {
353 return !packet_creator_.HasPendingFrames();
354}
355
356bool QuicPacketGenerator::HasPendingFrames() const {
357 return should_send_ack_ || should_send_stop_waiting_ ||
358 !queued_control_frames_.empty();
359}
360
361bool QuicPacketGenerator::AddNextPendingFrame() {
362 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
363 "generator tries to write control frames.";
364 if (should_send_ack_) {
365 should_send_ack_ = !packet_creator_.AddSavedFrame(
366 delegate_->GetUpdatedAckFrame(), next_transmission_type_);
367 return !should_send_ack_;
368 }
369
370 if (should_send_stop_waiting_) {
371 delegate_->PopulateStopWaitingFrame(&pending_stop_waiting_frame_);
372 // If we can't this add the frame now, then we still need to do so later.
373 should_send_stop_waiting_ = !packet_creator_.AddSavedFrame(
374 QuicFrame(pending_stop_waiting_frame_), next_transmission_type_);
375 // Return success if we have cleared out this flag (i.e., added the frame).
376 // If we still need to send, then the frame is full, and we have failed.
377 return !should_send_stop_waiting_;
378 }
379
380 QUIC_BUG_IF(queued_control_frames_.empty())
381 << "AddNextPendingFrame called with no queued control frames.";
382
383 if (!packet_creator_.AddSavedFrame(queued_control_frames_.back(),
384 next_transmission_type_)) {
385 // Packet was full.
386 return false;
387 }
388 queued_control_frames_.pop_back();
389 return true;
390}
391
392void QuicPacketGenerator::StopSendingVersion() {
393 packet_creator_.StopSendingVersion();
394}
395
396void QuicPacketGenerator::SetDiversificationNonce(
397 const DiversificationNonce& nonce) {
398 packet_creator_.SetDiversificationNonce(nonce);
399}
400
401QuicPacketNumber QuicPacketGenerator::packet_number() const {
402 return packet_creator_.packet_number();
403}
404
405QuicByteCount QuicPacketGenerator::GetCurrentMaxPacketLength() const {
406 return packet_creator_.max_packet_length();
407}
408
409void QuicPacketGenerator::SetMaxPacketLength(QuicByteCount length) {
410 DCHECK(packet_creator_.CanSetMaxPacketLength());
411 packet_creator_.SetMaxPacketLength(length);
412}
413
414std::unique_ptr<QuicEncryptedPacket>
415QuicPacketGenerator::SerializeVersionNegotiationPacket(
416 bool ietf_quic,
417 const ParsedQuicVersionVector& supported_versions) {
418 return packet_creator_.SerializeVersionNegotiationPacket(ietf_quic,
419 supported_versions);
420}
421
422OwningSerializedPacketPointer
423QuicPacketGenerator::SerializeConnectivityProbingPacket() {
424 return packet_creator_.SerializeConnectivityProbingPacket();
425}
426
427OwningSerializedPacketPointer
428QuicPacketGenerator::SerializePathChallengeConnectivityProbingPacket(
429 QuicPathFrameBuffer* payload) {
430 return packet_creator_.SerializePathChallengeConnectivityProbingPacket(
431 payload);
432}
433
434OwningSerializedPacketPointer
435QuicPacketGenerator::SerializePathResponseConnectivityProbingPacket(
436 const QuicDeque<QuicPathFrameBuffer>& payloads,
437 const bool is_padded) {
438 return packet_creator_.SerializePathResponseConnectivityProbingPacket(
439 payloads, is_padded);
440}
441
442void QuicPacketGenerator::ReserializeAllFrames(
443 const QuicPendingRetransmission& retransmission,
444 char* buffer,
445 size_t buffer_len) {
446 packet_creator_.ReserializeAllFrames(retransmission, buffer, buffer_len);
447}
448
449void QuicPacketGenerator::UpdatePacketNumberLength(
450 QuicPacketNumber least_packet_awaited_by_peer,
451 QuicPacketCount max_packets_in_flight) {
452 return packet_creator_.UpdatePacketNumberLength(least_packet_awaited_by_peer,
453 max_packets_in_flight);
454}
455
dschinazi7b9278c2019-05-20 07:36:21 -0700456void QuicPacketGenerator::SetServerConnectionIdLength(uint32_t length) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500457 if (length == 0) {
dschinazi7b9278c2019-05-20 07:36:21 -0700458 packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_ABSENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500459 } else {
dschinazi7b9278c2019-05-20 07:36:21 -0700460 packet_creator_.SetServerConnectionIdIncluded(CONNECTION_ID_PRESENT);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500461 }
462}
463
464void QuicPacketGenerator::set_encryption_level(EncryptionLevel level) {
465 packet_creator_.set_encryption_level(level);
466}
467
468void QuicPacketGenerator::SetEncrypter(
469 EncryptionLevel level,
470 std::unique_ptr<QuicEncrypter> encrypter) {
471 packet_creator_.SetEncrypter(level, std::move(encrypter));
472}
473
474void QuicPacketGenerator::AddRandomPadding() {
475 packet_creator_.AddPendingPadding(
476 random_generator_->RandUint64() % kMaxNumRandomPaddingBytes + 1);
477}
478
479void QuicPacketGenerator::SendRemainingPendingPadding() {
480 while (packet_creator_.pending_padding_bytes() > 0 && !HasQueuedFrames() &&
481 CanSendWithNextPendingFrameAddition()) {
482 packet_creator_.Flush();
483 }
484}
485
486bool QuicPacketGenerator::HasRetransmittableFrames() const {
487 return !queued_control_frames_.empty() ||
488 packet_creator_.HasPendingRetransmittableFrames();
489}
490
491bool QuicPacketGenerator::HasPendingStreamFramesOfStream(
492 QuicStreamId id) const {
493 return packet_creator_.HasPendingStreamFramesOfStream(id);
494}
495
496void QuicPacketGenerator::SetTransmissionType(TransmissionType type) {
497 packet_creator_.SetTransmissionType(type);
wub98669f52019-04-18 10:49:18 -0700498 if (packet_creator_.can_set_transmission_type()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500499 next_transmission_type_ = type;
500 }
501}
502
dschinazi244f6dc2019-05-06 15:45:16 -0700503void QuicPacketGenerator::SetRetryToken(QuicStringPiece retry_token) {
504 packet_creator_.SetRetryToken(retry_token);
505}
506
QUICHE teama6ef0a62019-03-07 20:34:33 -0500507void QuicPacketGenerator::SetCanSetTransmissionType(
508 bool can_set_transmission_type) {
509 packet_creator_.set_can_set_transmission_type(can_set_transmission_type);
510}
511
512MessageStatus QuicPacketGenerator::AddMessageFrame(QuicMessageId message_id,
513 QuicMemSliceSpan message) {
514 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
515 "generator tries to add message frame.";
516 if (deprecate_ack_bundling_mode_) {
517 MaybeBundleAckOpportunistically();
518 }
519 const QuicByteCount message_length = message.total_length();
ianswettb239f862019-04-05 09:15:06 -0700520 if (message_length > GetCurrentLargestMessagePayload()) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500521 return MESSAGE_STATUS_TOO_LARGE;
522 }
523 SendQueuedFrames(/*flush=*/false);
524 if (!packet_creator_.HasRoomForMessageFrame(message_length)) {
525 packet_creator_.Flush();
526 }
wub553a9662019-03-28 20:13:23 -0700527 QuicMessageFrame* frame = new QuicMessageFrame(message_id, message);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500528 const bool success =
529 packet_creator_.AddSavedFrame(QuicFrame(frame), next_transmission_type_);
530 if (!success) {
531 QUIC_BUG << "Failed to send message " << message_id;
532 delete frame;
533 return MESSAGE_STATUS_INTERNAL_ERROR;
534 }
535 return MESSAGE_STATUS_SUCCESS;
536}
537
538void QuicPacketGenerator::MaybeBundleAckOpportunistically() {
539 DCHECK(deprecate_ack_bundling_mode_);
540 if (packet_creator_.has_ack()) {
541 // Ack already queued, nothing to do.
542 return;
543 }
544 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
545 NOT_HANDSHAKE)) {
546 return;
547 }
548 const bool flushed =
549 FlushAckFrame(delegate_->MaybeBundleAckOpportunistically());
550 DCHECK(flushed);
551}
552
553bool QuicPacketGenerator::FlushAckFrame(const QuicFrames& frames) {
554 QUIC_BUG_IF(!flusher_attached_) << "Packet flusher is not attached when "
555 "generator tries to send ACK frame.";
556 for (const auto& frame : frames) {
557 DCHECK(frame.type == ACK_FRAME || frame.type == STOP_WAITING_FRAME);
558 if (packet_creator_.HasPendingFrames()) {
559 if (packet_creator_.AddSavedFrame(frame, next_transmission_type_)) {
560 // There is pending frames and current frame fits.
561 continue;
562 }
563 }
564 DCHECK(!packet_creator_.HasPendingFrames());
565 // There is no pending frames, consult the delegate whether a packet can be
566 // generated.
567 if (!delegate_->ShouldGeneratePacket(NO_RETRANSMITTABLE_DATA,
568 NOT_HANDSHAKE)) {
569 return false;
570 }
571 const bool success =
572 packet_creator_.AddSavedFrame(frame, next_transmission_type_);
573 QUIC_BUG_IF(!success) << "Failed to flush " << frame;
574 }
575 return true;
576}
577
ianswettb239f862019-04-05 09:15:06 -0700578QuicPacketLength QuicPacketGenerator::GetCurrentLargestMessagePayload() const {
579 return packet_creator_.GetCurrentLargestMessagePayload();
580}
581
582QuicPacketLength QuicPacketGenerator::GetGuaranteedLargestMessagePayload()
583 const {
584 return packet_creator_.GetGuaranteedLargestMessagePayload();
QUICHE teama6ef0a62019-03-07 20:34:33 -0500585}
586
dschinazi7b9278c2019-05-20 07:36:21 -0700587void QuicPacketGenerator::SetServerConnectionId(
588 QuicConnectionId server_connection_id) {
589 packet_creator_.SetServerConnectionId(server_connection_id);
QUICHE teamc65d1d12019-03-19 20:58:04 -0700590}
591
QUICHE teama6ef0a62019-03-07 20:34:33 -0500592} // namespace quic