xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_crypto_stream.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 #include "quiche/quic/core/quic_crypto_stream.h"
6 
7 #include <optional>
8 #include <string>
9 
10 #include "absl/strings/str_cat.h"
11 #include "absl/strings/string_view.h"
12 #include "quiche/quic/core/crypto/crypto_handshake.h"
13 #include "quiche/quic/core/frames/quic_crypto_frame.h"
14 #include "quiche/quic/core/quic_connection.h"
15 #include "quiche/quic/core/quic_error_codes.h"
16 #include "quiche/quic/core/quic_session.h"
17 #include "quiche/quic/core/quic_types.h"
18 #include "quiche/quic/core/quic_utils.h"
19 #include "quiche/quic/platform/api/quic_flag_utils.h"
20 #include "quiche/quic/platform/api/quic_flags.h"
21 #include "quiche/quic/platform/api/quic_logging.h"
22 
23 namespace quic {
24 
25 #define ENDPOINT                                                   \
26   (session()->perspective() == Perspective::IS_SERVER ? "Server: " \
27                                                       : "Client:"  \
28                                                         " ")
29 
QuicCryptoStream(QuicSession * session)30 QuicCryptoStream::QuicCryptoStream(QuicSession* session)
31     : QuicStream(
32           QuicVersionUsesCryptoFrames(session->transport_version())
33               ? QuicUtils::GetInvalidStreamId(session->transport_version())
34               : QuicUtils::GetCryptoStreamId(session->transport_version()),
35           session,
36           /*is_static=*/true,
37           QuicVersionUsesCryptoFrames(session->transport_version())
38               ? CRYPTO
39               : BIDIRECTIONAL),
40       substreams_{{{this}, {this}, {this}}} {
41   // The crypto stream is exempt from connection level flow control.
42   DisableConnectionFlowControlForThisStream();
43 }
44 
~QuicCryptoStream()45 QuicCryptoStream::~QuicCryptoStream() {}
46 
47 // static
CryptoMessageFramingOverhead(QuicTransportVersion version,QuicConnectionId connection_id)48 QuicByteCount QuicCryptoStream::CryptoMessageFramingOverhead(
49     QuicTransportVersion version, QuicConnectionId connection_id) {
50   QUICHE_DCHECK(
51       QuicUtils::IsConnectionIdValidForVersion(connection_id, version));
52   quiche::QuicheVariableLengthIntegerLength retry_token_length_length =
53       quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
54   quiche::QuicheVariableLengthIntegerLength length_length =
55       quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
56   if (!QuicVersionHasLongHeaderLengths(version)) {
57     retry_token_length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
58     length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_0;
59   }
60   return QuicPacketCreator::StreamFramePacketOverhead(
61       version, connection_id.length(), 0, /*include_version=*/true,
62       /*include_diversification_nonce=*/true, PACKET_4BYTE_PACKET_NUMBER,
63       retry_token_length_length, length_length,
64       /*offset=*/0);
65 }
66 
OnCryptoFrame(const QuicCryptoFrame & frame)67 void QuicCryptoStream::OnCryptoFrame(const QuicCryptoFrame& frame) {
68   QUIC_BUG_IF(quic_bug_12573_1,
69               !QuicVersionUsesCryptoFrames(session()->transport_version()))
70       << "Versions less than 47 shouldn't receive CRYPTO frames";
71   EncryptionLevel level = session()->connection()->last_decrypted_level();
72   if (!IsCryptoFrameExpectedForEncryptionLevel(level)) {
73     OnUnrecoverableError(
74         IETF_QUIC_PROTOCOL_VIOLATION,
75         absl::StrCat("CRYPTO_FRAME is unexpectedly received at level ", level));
76     return;
77   }
78   CryptoSubstream& substream =
79       substreams_[QuicUtils::GetPacketNumberSpace(level)];
80   substream.sequencer.OnCryptoFrame(frame);
81   EncryptionLevel frame_level = level;
82   if (substream.sequencer.NumBytesBuffered() >
83       BufferSizeLimitForLevel(frame_level)) {
84     OnUnrecoverableError(QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
85                          "Too much crypto data received");
86   }
87 }
88 
OnStreamFrame(const QuicStreamFrame & frame)89 void QuicCryptoStream::OnStreamFrame(const QuicStreamFrame& frame) {
90   if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
91     QUIC_PEER_BUG(quic_peer_bug_12573_2)
92         << "Crypto data received in stream frame instead of crypto frame";
93     OnUnrecoverableError(QUIC_INVALID_STREAM_DATA, "Unexpected stream frame");
94   }
95   QuicStream::OnStreamFrame(frame);
96 }
97 
OnDataAvailable()98 void QuicCryptoStream::OnDataAvailable() {
99   EncryptionLevel level = session()->connection()->last_decrypted_level();
100   if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
101     // Versions less than 47 only support QUIC crypto, which ignores the
102     // EncryptionLevel passed into CryptoMessageParser::ProcessInput (and
103     // OnDataAvailableInSequencer).
104     OnDataAvailableInSequencer(sequencer(), level);
105     return;
106   }
107   OnDataAvailableInSequencer(
108       &substreams_[QuicUtils::GetPacketNumberSpace(level)].sequencer, level);
109 }
110 
OnDataAvailableInSequencer(QuicStreamSequencer * sequencer,EncryptionLevel level)111 void QuicCryptoStream::OnDataAvailableInSequencer(
112     QuicStreamSequencer* sequencer, EncryptionLevel level) {
113   struct iovec iov;
114   while (sequencer->GetReadableRegion(&iov)) {
115     absl::string_view data(static_cast<char*>(iov.iov_base), iov.iov_len);
116     if (!crypto_message_parser()->ProcessInput(data, level)) {
117       OnUnrecoverableError(crypto_message_parser()->error(),
118                            crypto_message_parser()->error_detail());
119       return;
120     }
121     sequencer->MarkConsumed(iov.iov_len);
122     if (one_rtt_keys_available() &&
123         crypto_message_parser()->InputBytesRemaining() == 0) {
124       // If the handshake is complete and the current message has been fully
125       // processed then no more handshake messages are likely to arrive soon
126       // so release the memory in the stream sequencer.
127       sequencer->ReleaseBufferIfEmpty();
128     }
129   }
130 }
131 
WriteCryptoData(EncryptionLevel level,absl::string_view data)132 void QuicCryptoStream::WriteCryptoData(EncryptionLevel level,
133                                        absl::string_view data) {
134   if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
135     WriteOrBufferDataAtLevel(data, /*fin=*/false, level,
136                              /*ack_listener=*/nullptr);
137     return;
138   }
139   if (data.empty()) {
140     QUIC_BUG(quic_bug_10322_1) << "Empty crypto data being written";
141     return;
142   }
143   const bool had_buffered_data = HasBufferedCryptoFrames();
144   QuicStreamSendBuffer* send_buffer =
145       &substreams_[QuicUtils::GetPacketNumberSpace(level)].send_buffer;
146   QuicStreamOffset offset = send_buffer->stream_offset();
147 
148   // Ensure this data does not cause the send buffer for this encryption level
149   // to exceed its size limit.
150   if (GetQuicFlag(quic_bounded_crypto_send_buffer)) {
151     QUIC_BUG_IF(quic_crypto_stream_offset_lt_bytes_written,
152                 offset < send_buffer->stream_bytes_written());
153     uint64_t current_buffer_size =
154         offset - std::min(offset, send_buffer->stream_bytes_written());
155     if (current_buffer_size > 0) {
156       QUIC_CODE_COUNT(quic_received_crypto_data_with_non_empty_send_buffer);
157       if (BufferSizeLimitForLevel(level) <
158           (current_buffer_size + data.length())) {
159         QUIC_BUG(quic_crypto_send_buffer_overflow)
160             << absl::StrCat("Too much data for crypto send buffer with level: ",
161                             EncryptionLevelToString(level),
162                             ", current_buffer_size: ", current_buffer_size,
163                             ", data length: ", data.length(),
164                             ", SNI: ", crypto_negotiated_params().sni);
165         OnUnrecoverableError(QUIC_INTERNAL_ERROR,
166                              "Too much data for crypto send buffer");
167         return;
168       }
169     }
170   }
171 
172   // Append |data| to the send buffer for this encryption level.
173   send_buffer->SaveStreamData(data);
174   if (kMaxStreamLength - offset < data.length()) {
175     QUIC_BUG(quic_bug_10322_2) << "Writing too much crypto handshake data";
176     OnUnrecoverableError(QUIC_INTERNAL_ERROR,
177                          "Writing too much crypto handshake data");
178     return;
179   }
180   if (had_buffered_data) {
181     // Do not try to write if there is buffered data.
182     return;
183   }
184 
185   size_t bytes_consumed = stream_delegate()->SendCryptoData(
186       level, data.length(), offset, NOT_RETRANSMISSION);
187   send_buffer->OnStreamDataConsumed(bytes_consumed);
188 }
189 
BufferSizeLimitForLevel(EncryptionLevel) const190 size_t QuicCryptoStream::BufferSizeLimitForLevel(EncryptionLevel) const {
191   return GetQuicFlag(quic_max_buffered_crypto_bytes);
192 }
193 
OnCryptoFrameAcked(const QuicCryptoFrame & frame,QuicTime::Delta)194 bool QuicCryptoStream::OnCryptoFrameAcked(const QuicCryptoFrame& frame,
195                                           QuicTime::Delta /*ack_delay_time*/) {
196   QuicByteCount newly_acked_length = 0;
197   if (!substreams_[QuicUtils::GetPacketNumberSpace(frame.level)]
198            .send_buffer.OnStreamDataAcked(frame.offset, frame.data_length,
199                                           &newly_acked_length)) {
200     OnUnrecoverableError(QUIC_INTERNAL_ERROR,
201                          "Trying to ack unsent crypto data.");
202     return false;
203   }
204   return newly_acked_length > 0;
205 }
206 
OnStreamReset(const QuicRstStreamFrame &)207 void QuicCryptoStream::OnStreamReset(const QuicRstStreamFrame& /*frame*/) {
208   stream_delegate()->OnStreamError(QUIC_INVALID_STREAM_ID,
209                                    "Attempt to reset crypto stream");
210 }
211 
NeuterUnencryptedStreamData()212 void QuicCryptoStream::NeuterUnencryptedStreamData() {
213   NeuterStreamDataOfEncryptionLevel(ENCRYPTION_INITIAL);
214 }
215 
NeuterStreamDataOfEncryptionLevel(EncryptionLevel level)216 void QuicCryptoStream::NeuterStreamDataOfEncryptionLevel(
217     EncryptionLevel level) {
218   if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
219     for (const auto& interval : bytes_consumed_[level]) {
220       QuicByteCount newly_acked_length = 0;
221       send_buffer().OnStreamDataAcked(
222           interval.min(), interval.max() - interval.min(), &newly_acked_length);
223     }
224     return;
225   }
226   QuicStreamSendBuffer* send_buffer =
227       &substreams_[QuicUtils::GetPacketNumberSpace(level)].send_buffer;
228   // TODO(nharper): Consider adding a Clear() method to QuicStreamSendBuffer
229   // to replace the following code.
230   QuicIntervalSet<QuicStreamOffset> to_ack = send_buffer->bytes_acked();
231   to_ack.Complement(0, send_buffer->stream_offset());
232   for (const auto& interval : to_ack) {
233     QuicByteCount newly_acked_length = 0;
234     send_buffer->OnStreamDataAcked(
235         interval.min(), interval.max() - interval.min(), &newly_acked_length);
236   }
237 }
238 
OnStreamDataConsumed(QuicByteCount bytes_consumed)239 void QuicCryptoStream::OnStreamDataConsumed(QuicByteCount bytes_consumed) {
240   if (QuicVersionUsesCryptoFrames(session()->transport_version())) {
241     QUIC_BUG(quic_bug_10322_3)
242         << "Stream data consumed when CRYPTO frames should be in use";
243   }
244   if (bytes_consumed > 0) {
245     bytes_consumed_[session()->connection()->encryption_level()].Add(
246         stream_bytes_written(), stream_bytes_written() + bytes_consumed);
247   }
248   QuicStream::OnStreamDataConsumed(bytes_consumed);
249 }
250 
HasPendingCryptoRetransmission() const251 bool QuicCryptoStream::HasPendingCryptoRetransmission() const {
252   if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
253     return false;
254   }
255   for (const auto& substream : substreams_) {
256     if (substream.send_buffer.HasPendingRetransmission()) {
257       return true;
258     }
259   }
260   return false;
261 }
262 
WritePendingCryptoRetransmission()263 void QuicCryptoStream::WritePendingCryptoRetransmission() {
264   QUIC_BUG_IF(quic_bug_12573_3,
265               !QuicVersionUsesCryptoFrames(session()->transport_version()))
266       << "Versions less than 47 don't write CRYPTO frames";
267   for (uint8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
268     auto packet_number_space = static_cast<PacketNumberSpace>(i);
269     QuicStreamSendBuffer* send_buffer =
270         &substreams_[packet_number_space].send_buffer;
271     while (send_buffer->HasPendingRetransmission()) {
272       auto pending = send_buffer->NextPendingRetransmission();
273       size_t bytes_consumed = stream_delegate()->SendCryptoData(
274           GetEncryptionLevelToSendCryptoDataOfSpace(packet_number_space),
275           pending.length, pending.offset, HANDSHAKE_RETRANSMISSION);
276       send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
277       if (bytes_consumed < pending.length) {
278         return;
279       }
280     }
281   }
282 }
283 
WritePendingRetransmission()284 void QuicCryptoStream::WritePendingRetransmission() {
285   while (HasPendingRetransmission()) {
286     StreamPendingRetransmission pending =
287         send_buffer().NextPendingRetransmission();
288     QuicIntervalSet<QuicStreamOffset> retransmission(
289         pending.offset, pending.offset + pending.length);
290     EncryptionLevel retransmission_encryption_level = ENCRYPTION_INITIAL;
291     // Determine the encryption level to write the retransmission
292     // at. The retransmission should be written at the same encryption level
293     // as the original transmission.
294     for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
295       if (retransmission.Intersects(bytes_consumed_[i])) {
296         retransmission_encryption_level = static_cast<EncryptionLevel>(i);
297         retransmission.Intersection(bytes_consumed_[i]);
298         break;
299       }
300     }
301     pending.offset = retransmission.begin()->min();
302     pending.length =
303         retransmission.begin()->max() - retransmission.begin()->min();
304     QuicConsumedData consumed = RetransmitStreamDataAtLevel(
305         pending.offset, pending.length, retransmission_encryption_level,
306         HANDSHAKE_RETRANSMISSION);
307     if (consumed.bytes_consumed < pending.length) {
308       // The connection is write blocked.
309       break;
310     }
311   }
312 }
313 
RetransmitStreamData(QuicStreamOffset offset,QuicByteCount data_length,bool,TransmissionType type)314 bool QuicCryptoStream::RetransmitStreamData(QuicStreamOffset offset,
315                                             QuicByteCount data_length,
316                                             bool /*fin*/,
317                                             TransmissionType type) {
318   QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
319   QuicIntervalSet<QuicStreamOffset> retransmission(offset,
320                                                    offset + data_length);
321   // Determine the encryption level to send data. This only needs to be once as
322   // [offset, offset + data_length) is guaranteed to be in the same packet.
323   EncryptionLevel send_encryption_level = ENCRYPTION_INITIAL;
324   for (size_t i = 0; i < NUM_ENCRYPTION_LEVELS; ++i) {
325     if (retransmission.Intersects(bytes_consumed_[i])) {
326       send_encryption_level = static_cast<EncryptionLevel>(i);
327       break;
328     }
329   }
330   retransmission.Difference(bytes_acked());
331   for (const auto& interval : retransmission) {
332     QuicStreamOffset retransmission_offset = interval.min();
333     QuicByteCount retransmission_length = interval.max() - interval.min();
334     QuicConsumedData consumed = RetransmitStreamDataAtLevel(
335         retransmission_offset, retransmission_length, send_encryption_level,
336         type);
337     if (consumed.bytes_consumed < retransmission_length) {
338       // The connection is write blocked.
339       return false;
340     }
341   }
342 
343   return true;
344 }
345 
RetransmitStreamDataAtLevel(QuicStreamOffset retransmission_offset,QuicByteCount retransmission_length,EncryptionLevel encryption_level,TransmissionType type)346 QuicConsumedData QuicCryptoStream::RetransmitStreamDataAtLevel(
347     QuicStreamOffset retransmission_offset, QuicByteCount retransmission_length,
348     EncryptionLevel encryption_level, TransmissionType type) {
349   QUICHE_DCHECK(type == HANDSHAKE_RETRANSMISSION || type == PTO_RETRANSMISSION);
350   const auto consumed = stream_delegate()->WritevData(
351       id(), retransmission_length, retransmission_offset, NO_FIN, type,
352       encryption_level);
353   QUIC_DVLOG(1) << ENDPOINT << "stream " << id()
354                 << " is forced to retransmit stream data ["
355                 << retransmission_offset << ", "
356                 << retransmission_offset + retransmission_length
357                 << "), with encryption level: " << encryption_level
358                 << ", consumed: " << consumed;
359   OnStreamFrameRetransmitted(retransmission_offset, consumed.bytes_consumed,
360                              consumed.fin_consumed);
361 
362   return consumed;
363 }
364 
crypto_bytes_read() const365 uint64_t QuicCryptoStream::crypto_bytes_read() const {
366   if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
367     return stream_bytes_read();
368   }
369   uint64_t bytes_read = 0;
370   for (const CryptoSubstream& substream : substreams_) {
371     bytes_read += substream.sequencer.NumBytesConsumed();
372   }
373   return bytes_read;
374 }
375 
376 // TODO(haoyuewang) Move this test-only method under
377 // quiche/quic/test_tools.
BytesReadOnLevel(EncryptionLevel level) const378 uint64_t QuicCryptoStream::BytesReadOnLevel(EncryptionLevel level) const {
379   return substreams_[QuicUtils::GetPacketNumberSpace(level)]
380       .sequencer.NumBytesConsumed();
381 }
382 
BytesSentOnLevel(EncryptionLevel level) const383 uint64_t QuicCryptoStream::BytesSentOnLevel(EncryptionLevel level) const {
384   return substreams_[QuicUtils::GetPacketNumberSpace(level)]
385       .send_buffer.stream_bytes_written();
386 }
387 
WriteCryptoFrame(EncryptionLevel level,QuicStreamOffset offset,QuicByteCount data_length,QuicDataWriter * writer)388 bool QuicCryptoStream::WriteCryptoFrame(EncryptionLevel level,
389                                         QuicStreamOffset offset,
390                                         QuicByteCount data_length,
391                                         QuicDataWriter* writer) {
392   QUIC_BUG_IF(quic_bug_12573_4,
393               !QuicVersionUsesCryptoFrames(session()->transport_version()))
394       << "Versions less than 47 don't write CRYPTO frames (2)";
395   return substreams_[QuicUtils::GetPacketNumberSpace(level)]
396       .send_buffer.WriteStreamData(offset, data_length, writer);
397 }
398 
OnCryptoFrameLost(QuicCryptoFrame * crypto_frame)399 void QuicCryptoStream::OnCryptoFrameLost(QuicCryptoFrame* crypto_frame) {
400   QUIC_BUG_IF(quic_bug_12573_5,
401               !QuicVersionUsesCryptoFrames(session()->transport_version()))
402       << "Versions less than 47 don't lose CRYPTO frames";
403   substreams_[QuicUtils::GetPacketNumberSpace(crypto_frame->level)]
404       .send_buffer.OnStreamDataLost(crypto_frame->offset,
405                                     crypto_frame->data_length);
406 }
407 
RetransmitData(QuicCryptoFrame * crypto_frame,TransmissionType type)408 bool QuicCryptoStream::RetransmitData(QuicCryptoFrame* crypto_frame,
409                                       TransmissionType type) {
410   QUIC_BUG_IF(quic_bug_12573_6,
411               !QuicVersionUsesCryptoFrames(session()->transport_version()))
412       << "Versions less than 47 don't retransmit CRYPTO frames";
413   QuicIntervalSet<QuicStreamOffset> retransmission(
414       crypto_frame->offset, crypto_frame->offset + crypto_frame->data_length);
415   QuicStreamSendBuffer* send_buffer =
416       &substreams_[QuicUtils::GetPacketNumberSpace(crypto_frame->level)]
417            .send_buffer;
418   retransmission.Difference(send_buffer->bytes_acked());
419   if (retransmission.Empty()) {
420     return true;
421   }
422   for (const auto& interval : retransmission) {
423     size_t retransmission_offset = interval.min();
424     size_t retransmission_length = interval.max() - interval.min();
425     EncryptionLevel retransmission_encryption_level =
426         GetEncryptionLevelToSendCryptoDataOfSpace(
427             QuicUtils::GetPacketNumberSpace(crypto_frame->level));
428     size_t bytes_consumed = stream_delegate()->SendCryptoData(
429         retransmission_encryption_level, retransmission_length,
430         retransmission_offset, type);
431     send_buffer->OnStreamDataRetransmitted(retransmission_offset,
432                                            bytes_consumed);
433     if (bytes_consumed < retransmission_length) {
434       return false;
435     }
436   }
437   return true;
438 }
439 
WriteBufferedCryptoFrames()440 void QuicCryptoStream::WriteBufferedCryptoFrames() {
441   QUIC_BUG_IF(quic_bug_12573_7,
442               !QuicVersionUsesCryptoFrames(session()->transport_version()))
443       << "Versions less than 47 don't use CRYPTO frames";
444   for (uint8_t i = INITIAL_DATA; i <= APPLICATION_DATA; ++i) {
445     auto packet_number_space = static_cast<PacketNumberSpace>(i);
446     QuicStreamSendBuffer* send_buffer =
447         &substreams_[packet_number_space].send_buffer;
448     const size_t data_length =
449         send_buffer->stream_offset() - send_buffer->stream_bytes_written();
450     if (data_length == 0) {
451       // No buffered data for this encryption level.
452       continue;
453     }
454     size_t bytes_consumed = stream_delegate()->SendCryptoData(
455         GetEncryptionLevelToSendCryptoDataOfSpace(packet_number_space),
456         data_length, send_buffer->stream_bytes_written(), NOT_RETRANSMISSION);
457     send_buffer->OnStreamDataConsumed(bytes_consumed);
458     if (bytes_consumed < data_length) {
459       // Connection is write blocked.
460       break;
461     }
462   }
463 }
464 
HasBufferedCryptoFrames() const465 bool QuicCryptoStream::HasBufferedCryptoFrames() const {
466   QUIC_BUG_IF(quic_bug_12573_8,
467               !QuicVersionUsesCryptoFrames(session()->transport_version()))
468       << "Versions less than 47 don't use CRYPTO frames";
469   for (const CryptoSubstream& substream : substreams_) {
470     const QuicStreamSendBuffer& send_buffer = substream.send_buffer;
471     QUICHE_DCHECK_GE(send_buffer.stream_offset(),
472                      send_buffer.stream_bytes_written());
473     if (send_buffer.stream_offset() > send_buffer.stream_bytes_written()) {
474       return true;
475     }
476   }
477   return false;
478 }
479 
IsFrameOutstanding(EncryptionLevel level,size_t offset,size_t length) const480 bool QuicCryptoStream::IsFrameOutstanding(EncryptionLevel level, size_t offset,
481                                           size_t length) const {
482   if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
483     // This only happens if a client was originally configured for a version
484     // greater than 45, but received a version negotiation packet and is
485     // attempting to retransmit for a version less than 47. Outside of tests,
486     // this is a misconfiguration of the client, and this connection will be
487     // doomed. Return false here to avoid trying to retransmit CRYPTO frames on
488     // the wrong transport version.
489     return false;
490   }
491   return substreams_[QuicUtils::GetPacketNumberSpace(level)]
492       .send_buffer.IsStreamDataOutstanding(offset, length);
493 }
494 
IsWaitingForAcks() const495 bool QuicCryptoStream::IsWaitingForAcks() const {
496   if (!QuicVersionUsesCryptoFrames(session()->transport_version())) {
497     return QuicStream::IsWaitingForAcks();
498   }
499   for (const CryptoSubstream& substream : substreams_) {
500     if (substream.send_buffer.stream_bytes_outstanding()) {
501       return true;
502     }
503   }
504   return false;
505 }
506 
CryptoSubstream(QuicCryptoStream * crypto_stream)507 QuicCryptoStream::CryptoSubstream::CryptoSubstream(
508     QuicCryptoStream* crypto_stream)
509     : sequencer(crypto_stream),
510       send_buffer(crypto_stream->session()
511                       ->connection()
512                       ->helper()
513                       ->GetStreamSendBufferAllocator()) {}
514 
515 #undef ENDPOINT  // undef for jumbo builds
516 }  // namespace quic
517