1 // Copyright (c) 2013 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_config.h"
6
7 #include <algorithm>
8 #include <cstring>
9 #include <limits>
10 #include <string>
11 #include <utility>
12
13 #include "absl/base/attributes.h"
14 #include "absl/strings/string_view.h"
15 #include "quiche/quic/core/crypto/crypto_handshake_message.h"
16 #include "quiche/quic/core/crypto/crypto_protocol.h"
17 #include "quiche/quic/core/quic_connection_id.h"
18 #include "quiche/quic/core/quic_constants.h"
19 #include "quiche/quic/core/quic_socket_address_coder.h"
20 #include "quiche/quic/core/quic_types.h"
21 #include "quiche/quic/core/quic_utils.h"
22 #include "quiche/quic/platform/api/quic_bug_tracker.h"
23 #include "quiche/quic/platform/api/quic_flag_utils.h"
24 #include "quiche/quic/platform/api/quic_flags.h"
25 #include "quiche/quic/platform/api/quic_logging.h"
26 #include "quiche/quic/platform/api/quic_socket_address.h"
27
28 namespace quic {
29
30 // Reads the value corresponding to |name_| from |msg| into |out|. If the
31 // |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
32 // to |default_value|.
ReadUint32(const CryptoHandshakeMessage & msg,QuicTag tag,QuicConfigPresence presence,uint32_t default_value,uint32_t * out,std::string * error_details)33 QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg, QuicTag tag,
34 QuicConfigPresence presence, uint32_t default_value,
35 uint32_t* out, std::string* error_details) {
36 QUICHE_DCHECK(error_details != nullptr);
37 QuicErrorCode error = msg.GetUint32(tag, out);
38 switch (error) {
39 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
40 if (presence == PRESENCE_REQUIRED) {
41 *error_details = "Missing " + QuicTagToString(tag);
42 break;
43 }
44 error = QUIC_NO_ERROR;
45 *out = default_value;
46 break;
47 case QUIC_NO_ERROR:
48 break;
49 default:
50 *error_details = "Bad " + QuicTagToString(tag);
51 break;
52 }
53 return error;
54 }
55
QuicConfigValue(QuicTag tag,QuicConfigPresence presence)56 QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
57 : tag_(tag), presence_(presence) {}
~QuicConfigValue()58 QuicConfigValue::~QuicConfigValue() {}
59
QuicFixedUint32(QuicTag tag,QuicConfigPresence presence)60 QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
61 : QuicConfigValue(tag, presence),
62 has_send_value_(false),
63 has_receive_value_(false) {}
~QuicFixedUint32()64 QuicFixedUint32::~QuicFixedUint32() {}
65
HasSendValue() const66 bool QuicFixedUint32::HasSendValue() const { return has_send_value_; }
67
GetSendValue() const68 uint32_t QuicFixedUint32::GetSendValue() const {
69 QUIC_BUG_IF(quic_bug_12743_1, !has_send_value_)
70 << "No send value to get for tag:" << QuicTagToString(tag_);
71 return send_value_;
72 }
73
SetSendValue(uint32_t value)74 void QuicFixedUint32::SetSendValue(uint32_t value) {
75 has_send_value_ = true;
76 send_value_ = value;
77 }
78
HasReceivedValue() const79 bool QuicFixedUint32::HasReceivedValue() const { return has_receive_value_; }
80
GetReceivedValue() const81 uint32_t QuicFixedUint32::GetReceivedValue() const {
82 QUIC_BUG_IF(quic_bug_12743_2, !has_receive_value_)
83 << "No receive value to get for tag:" << QuicTagToString(tag_);
84 return receive_value_;
85 }
86
SetReceivedValue(uint32_t value)87 void QuicFixedUint32::SetReceivedValue(uint32_t value) {
88 has_receive_value_ = true;
89 receive_value_ = value;
90 }
91
ToHandshakeMessage(CryptoHandshakeMessage * out) const92 void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
93 if (tag_ == 0) {
94 QUIC_BUG(quic_bug_12743_3)
95 << "This parameter does not support writing to CryptoHandshakeMessage";
96 return;
97 }
98 if (has_send_value_) {
99 out->SetValue(tag_, send_value_);
100 }
101 }
102
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)103 QuicErrorCode QuicFixedUint32::ProcessPeerHello(
104 const CryptoHandshakeMessage& peer_hello, HelloType /*hello_type*/,
105 std::string* error_details) {
106 QUICHE_DCHECK(error_details != nullptr);
107 if (tag_ == 0) {
108 *error_details =
109 "This parameter does not support reading from CryptoHandshakeMessage";
110 QUIC_BUG(quic_bug_10575_1) << *error_details;
111 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
112 }
113 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
114 switch (error) {
115 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
116 if (presence_ == PRESENCE_OPTIONAL) {
117 return QUIC_NO_ERROR;
118 }
119 *error_details = "Missing " + QuicTagToString(tag_);
120 break;
121 case QUIC_NO_ERROR:
122 has_receive_value_ = true;
123 break;
124 default:
125 *error_details = "Bad " + QuicTagToString(tag_);
126 break;
127 }
128 return error;
129 }
130
QuicFixedUint62(QuicTag name,QuicConfigPresence presence)131 QuicFixedUint62::QuicFixedUint62(QuicTag name, QuicConfigPresence presence)
132 : QuicConfigValue(name, presence),
133 has_send_value_(false),
134 has_receive_value_(false) {}
135
~QuicFixedUint62()136 QuicFixedUint62::~QuicFixedUint62() {}
137
HasSendValue() const138 bool QuicFixedUint62::HasSendValue() const { return has_send_value_; }
139
GetSendValue() const140 uint64_t QuicFixedUint62::GetSendValue() const {
141 if (!has_send_value_) {
142 QUIC_BUG(quic_bug_10575_2)
143 << "No send value to get for tag:" << QuicTagToString(tag_);
144 return 0;
145 }
146 return send_value_;
147 }
148
SetSendValue(uint64_t value)149 void QuicFixedUint62::SetSendValue(uint64_t value) {
150 if (value > quiche::kVarInt62MaxValue) {
151 QUIC_BUG(quic_bug_10575_3) << "QuicFixedUint62 invalid value " << value;
152 value = quiche::kVarInt62MaxValue;
153 }
154 has_send_value_ = true;
155 send_value_ = value;
156 }
157
HasReceivedValue() const158 bool QuicFixedUint62::HasReceivedValue() const { return has_receive_value_; }
159
GetReceivedValue() const160 uint64_t QuicFixedUint62::GetReceivedValue() const {
161 if (!has_receive_value_) {
162 QUIC_BUG(quic_bug_10575_4)
163 << "No receive value to get for tag:" << QuicTagToString(tag_);
164 return 0;
165 }
166 return receive_value_;
167 }
168
SetReceivedValue(uint64_t value)169 void QuicFixedUint62::SetReceivedValue(uint64_t value) {
170 has_receive_value_ = true;
171 receive_value_ = value;
172 }
173
ToHandshakeMessage(CryptoHandshakeMessage * out) const174 void QuicFixedUint62::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
175 if (!has_send_value_) {
176 return;
177 }
178 uint32_t send_value32;
179 if (send_value_ > std::numeric_limits<uint32_t>::max()) {
180 QUIC_BUG(quic_bug_10575_5) << "Attempting to send " << send_value_
181 << " for tag:" << QuicTagToString(tag_);
182 send_value32 = std::numeric_limits<uint32_t>::max();
183 } else {
184 send_value32 = static_cast<uint32_t>(send_value_);
185 }
186 out->SetValue(tag_, send_value32);
187 }
188
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)189 QuicErrorCode QuicFixedUint62::ProcessPeerHello(
190 const CryptoHandshakeMessage& peer_hello, HelloType /*hello_type*/,
191 std::string* error_details) {
192 QUICHE_DCHECK(error_details != nullptr);
193 uint32_t receive_value32;
194 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value32);
195 // GetUint32 is guaranteed to always initialize receive_value32.
196 receive_value_ = receive_value32;
197 switch (error) {
198 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
199 if (presence_ == PRESENCE_OPTIONAL) {
200 return QUIC_NO_ERROR;
201 }
202 *error_details = "Missing " + QuicTagToString(tag_);
203 break;
204 case QUIC_NO_ERROR:
205 has_receive_value_ = true;
206 break;
207 default:
208 *error_details = "Bad " + QuicTagToString(tag_);
209 break;
210 }
211 return error;
212 }
213
QuicFixedStatelessResetToken(QuicTag tag,QuicConfigPresence presence)214 QuicFixedStatelessResetToken::QuicFixedStatelessResetToken(
215 QuicTag tag, QuicConfigPresence presence)
216 : QuicConfigValue(tag, presence),
217 has_send_value_(false),
218 has_receive_value_(false) {}
~QuicFixedStatelessResetToken()219 QuicFixedStatelessResetToken::~QuicFixedStatelessResetToken() {}
220
HasSendValue() const221 bool QuicFixedStatelessResetToken::HasSendValue() const {
222 return has_send_value_;
223 }
224
GetSendValue() const225 const StatelessResetToken& QuicFixedStatelessResetToken::GetSendValue() const {
226 QUIC_BUG_IF(quic_bug_12743_4, !has_send_value_)
227 << "No send value to get for tag:" << QuicTagToString(tag_);
228 return send_value_;
229 }
230
SetSendValue(const StatelessResetToken & value)231 void QuicFixedStatelessResetToken::SetSendValue(
232 const StatelessResetToken& value) {
233 has_send_value_ = true;
234 send_value_ = value;
235 }
236
HasReceivedValue() const237 bool QuicFixedStatelessResetToken::HasReceivedValue() const {
238 return has_receive_value_;
239 }
240
GetReceivedValue() const241 const StatelessResetToken& QuicFixedStatelessResetToken::GetReceivedValue()
242 const {
243 QUIC_BUG_IF(quic_bug_12743_5, !has_receive_value_)
244 << "No receive value to get for tag:" << QuicTagToString(tag_);
245 return receive_value_;
246 }
247
SetReceivedValue(const StatelessResetToken & value)248 void QuicFixedStatelessResetToken::SetReceivedValue(
249 const StatelessResetToken& value) {
250 has_receive_value_ = true;
251 receive_value_ = value;
252 }
253
ToHandshakeMessage(CryptoHandshakeMessage * out) const254 void QuicFixedStatelessResetToken::ToHandshakeMessage(
255 CryptoHandshakeMessage* out) const {
256 if (has_send_value_) {
257 out->SetValue(tag_, send_value_);
258 }
259 }
260
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)261 QuicErrorCode QuicFixedStatelessResetToken::ProcessPeerHello(
262 const CryptoHandshakeMessage& peer_hello, HelloType /*hello_type*/,
263 std::string* error_details) {
264 QUICHE_DCHECK(error_details != nullptr);
265 QuicErrorCode error =
266 peer_hello.GetStatelessResetToken(tag_, &receive_value_);
267 switch (error) {
268 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
269 if (presence_ == PRESENCE_OPTIONAL) {
270 return QUIC_NO_ERROR;
271 }
272 *error_details = "Missing " + QuicTagToString(tag_);
273 break;
274 case QUIC_NO_ERROR:
275 has_receive_value_ = true;
276 break;
277 default:
278 *error_details = "Bad " + QuicTagToString(tag_);
279 break;
280 }
281 return error;
282 }
283
QuicFixedTagVector(QuicTag name,QuicConfigPresence presence)284 QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
285 QuicConfigPresence presence)
286 : QuicConfigValue(name, presence),
287 has_send_values_(false),
288 has_receive_values_(false) {}
289
290 QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
291 default;
292
~QuicFixedTagVector()293 QuicFixedTagVector::~QuicFixedTagVector() {}
294
HasSendValues() const295 bool QuicFixedTagVector::HasSendValues() const { return has_send_values_; }
296
GetSendValues() const297 const QuicTagVector& QuicFixedTagVector::GetSendValues() const {
298 QUIC_BUG_IF(quic_bug_12743_6, !has_send_values_)
299 << "No send values to get for tag:" << QuicTagToString(tag_);
300 return send_values_;
301 }
302
SetSendValues(const QuicTagVector & values)303 void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
304 has_send_values_ = true;
305 send_values_ = values;
306 }
307
HasReceivedValues() const308 bool QuicFixedTagVector::HasReceivedValues() const {
309 return has_receive_values_;
310 }
311
GetReceivedValues() const312 const QuicTagVector& QuicFixedTagVector::GetReceivedValues() const {
313 QUIC_BUG_IF(quic_bug_12743_7, !has_receive_values_)
314 << "No receive value to get for tag:" << QuicTagToString(tag_);
315 return receive_values_;
316 }
317
SetReceivedValues(const QuicTagVector & values)318 void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
319 has_receive_values_ = true;
320 receive_values_ = values;
321 }
322
ToHandshakeMessage(CryptoHandshakeMessage * out) const323 void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
324 if (has_send_values_) {
325 out->SetVector(tag_, send_values_);
326 }
327 }
328
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)329 QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
330 const CryptoHandshakeMessage& peer_hello, HelloType /*hello_type*/,
331 std::string* error_details) {
332 QUICHE_DCHECK(error_details != nullptr);
333 QuicTagVector values;
334 QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
335 switch (error) {
336 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
337 if (presence_ == PRESENCE_OPTIONAL) {
338 return QUIC_NO_ERROR;
339 }
340 *error_details = "Missing " + QuicTagToString(tag_);
341 break;
342 case QUIC_NO_ERROR:
343 QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
344 has_receive_values_ = true;
345 receive_values_.insert(receive_values_.end(), values.begin(),
346 values.end());
347 break;
348 default:
349 *error_details = "Bad " + QuicTagToString(tag_);
350 break;
351 }
352 return error;
353 }
354
QuicFixedSocketAddress(QuicTag tag,QuicConfigPresence presence)355 QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
356 QuicConfigPresence presence)
357 : QuicConfigValue(tag, presence),
358 has_send_value_(false),
359 has_receive_value_(false) {}
360
~QuicFixedSocketAddress()361 QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
362
HasSendValue() const363 bool QuicFixedSocketAddress::HasSendValue() const { return has_send_value_; }
364
GetSendValue() const365 const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
366 QUIC_BUG_IF(quic_bug_12743_8, !has_send_value_)
367 << "No send value to get for tag:" << QuicTagToString(tag_);
368 return send_value_;
369 }
370
SetSendValue(const QuicSocketAddress & value)371 void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
372 has_send_value_ = true;
373 send_value_ = value;
374 }
375
ClearSendValue()376 void QuicFixedSocketAddress::ClearSendValue() {
377 has_send_value_ = false;
378 send_value_ = QuicSocketAddress();
379 }
380
HasReceivedValue() const381 bool QuicFixedSocketAddress::HasReceivedValue() const {
382 return has_receive_value_;
383 }
384
GetReceivedValue() const385 const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
386 QUIC_BUG_IF(quic_bug_12743_9, !has_receive_value_)
387 << "No receive value to get for tag:" << QuicTagToString(tag_);
388 return receive_value_;
389 }
390
SetReceivedValue(const QuicSocketAddress & value)391 void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
392 has_receive_value_ = true;
393 receive_value_ = value;
394 }
395
ToHandshakeMessage(CryptoHandshakeMessage * out) const396 void QuicFixedSocketAddress::ToHandshakeMessage(
397 CryptoHandshakeMessage* out) const {
398 if (has_send_value_) {
399 QuicSocketAddressCoder address_coder(send_value_);
400 out->SetStringPiece(tag_, address_coder.Encode());
401 }
402 }
403
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType,std::string * error_details)404 QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
405 const CryptoHandshakeMessage& peer_hello, HelloType /*hello_type*/,
406 std::string* error_details) {
407 absl::string_view address;
408 if (!peer_hello.GetStringPiece(tag_, &address)) {
409 if (presence_ == PRESENCE_REQUIRED) {
410 *error_details = "Missing " + QuicTagToString(tag_);
411 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
412 }
413 } else {
414 QuicSocketAddressCoder address_coder;
415 if (address_coder.Decode(address.data(), address.length())) {
416 SetReceivedValue(
417 QuicSocketAddress(address_coder.ip(), address_coder.port()));
418 }
419 }
420 return QUIC_NO_ERROR;
421 }
422
QuicConfig()423 QuicConfig::QuicConfig()
424 : negotiated_(false),
425 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
426 max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
427 max_undecryptable_packets_(0),
428 connection_options_(kCOPT, PRESENCE_OPTIONAL),
429 client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
430 max_idle_timeout_to_send_(QuicTime::Delta::Infinite()),
431 max_bidirectional_streams_(kMIBS, PRESENCE_REQUIRED),
432 max_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
433 bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
434 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
435 initial_max_stream_data_bytes_incoming_bidirectional_(0,
436 PRESENCE_OPTIONAL),
437 initial_max_stream_data_bytes_outgoing_bidirectional_(0,
438 PRESENCE_OPTIONAL),
439 initial_max_stream_data_bytes_unidirectional_(0, PRESENCE_OPTIONAL),
440 initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
441 initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
442 connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
443 alternate_server_address_ipv6_(kASAD, PRESENCE_OPTIONAL),
444 alternate_server_address_ipv4_(kASAD, PRESENCE_OPTIONAL),
445 stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
446 max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
447 min_ack_delay_ms_(0, PRESENCE_OPTIONAL),
448 ack_delay_exponent_(kADE, PRESENCE_OPTIONAL),
449 max_udp_payload_size_(0, PRESENCE_OPTIONAL),
450 max_datagram_frame_size_(0, PRESENCE_OPTIONAL),
451 active_connection_id_limit_(0, PRESENCE_OPTIONAL) {
452 SetDefaults();
453 }
454
455 QuicConfig::QuicConfig(const QuicConfig& other) = default;
456
~QuicConfig()457 QuicConfig::~QuicConfig() {}
458
SetInitialReceivedConnectionOptions(const QuicTagVector & tags)459 bool QuicConfig::SetInitialReceivedConnectionOptions(
460 const QuicTagVector& tags) {
461 if (HasReceivedConnectionOptions()) {
462 // If we have already received connection options (via handshake or due to
463 // a previous call), don't re-initialize.
464 return false;
465 }
466 connection_options_.SetReceivedValues(tags);
467 return true;
468 }
469
SetConnectionOptionsToSend(const QuicTagVector & connection_options)470 void QuicConfig::SetConnectionOptionsToSend(
471 const QuicTagVector& connection_options) {
472 connection_options_.SetSendValues(connection_options);
473 }
474
SetGoogleHandshakeMessageToSend(std::string message)475 void QuicConfig::SetGoogleHandshakeMessageToSend(std::string message) {
476 google_handshake_message_to_send_ = std::move(message);
477 }
478
479 const absl::optional<std::string>&
GetReceivedGoogleHandshakeMessage() const480 QuicConfig::GetReceivedGoogleHandshakeMessage() const {
481 return received_google_handshake_message_;
482 }
483
HasReceivedConnectionOptions() const484 bool QuicConfig::HasReceivedConnectionOptions() const {
485 return connection_options_.HasReceivedValues();
486 }
487
ReceivedConnectionOptions() const488 const QuicTagVector& QuicConfig::ReceivedConnectionOptions() const {
489 return connection_options_.GetReceivedValues();
490 }
491
HasSendConnectionOptions() const492 bool QuicConfig::HasSendConnectionOptions() const {
493 return connection_options_.HasSendValues();
494 }
495
SendConnectionOptions() const496 const QuicTagVector& QuicConfig::SendConnectionOptions() const {
497 return connection_options_.GetSendValues();
498 }
499
HasClientSentConnectionOption(QuicTag tag,Perspective perspective) const500 bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
501 Perspective perspective) const {
502 if (perspective == Perspective::IS_SERVER) {
503 if (HasReceivedConnectionOptions() &&
504 ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
505 return true;
506 }
507 } else if (HasSendConnectionOptions() &&
508 ContainsQuicTag(SendConnectionOptions(), tag)) {
509 return true;
510 }
511 return false;
512 }
513
SetClientConnectionOptions(const QuicTagVector & client_connection_options)514 void QuicConfig::SetClientConnectionOptions(
515 const QuicTagVector& client_connection_options) {
516 client_connection_options_.SetSendValues(client_connection_options);
517 }
518
HasClientRequestedIndependentOption(QuicTag tag,Perspective perspective) const519 bool QuicConfig::HasClientRequestedIndependentOption(
520 QuicTag tag, Perspective perspective) const {
521 if (perspective == Perspective::IS_SERVER) {
522 return (HasReceivedConnectionOptions() &&
523 ContainsQuicTag(ReceivedConnectionOptions(), tag));
524 }
525
526 return (client_connection_options_.HasSendValues() &&
527 ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
528 }
529
ClientRequestedIndependentOptions(Perspective perspective) const530 const QuicTagVector& QuicConfig::ClientRequestedIndependentOptions(
531 Perspective perspective) const {
532 static const QuicTagVector* no_options = new QuicTagVector;
533 if (perspective == Perspective::IS_SERVER) {
534 return HasReceivedConnectionOptions() ? ReceivedConnectionOptions()
535 : *no_options;
536 }
537
538 return client_connection_options_.HasSendValues()
539 ? client_connection_options_.GetSendValues()
540 : *no_options;
541 }
542
SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout)543 void QuicConfig::SetIdleNetworkTimeout(QuicTime::Delta idle_network_timeout) {
544 if (idle_network_timeout.ToMicroseconds() <= 0) {
545 QUIC_BUG(quic_bug_10575_6)
546 << "Invalid idle network timeout " << idle_network_timeout;
547 return;
548 }
549 max_idle_timeout_to_send_ = idle_network_timeout;
550 }
551
IdleNetworkTimeout() const552 QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
553 // TODO(b/152032210) add a QUIC_BUG to ensure that is not called before we've
554 // received the peer's values. This is true in production code but not in all
555 // of our tests that use a fake QuicConfig.
556 if (!received_max_idle_timeout_.has_value()) {
557 return max_idle_timeout_to_send_;
558 }
559 return received_max_idle_timeout_.value();
560 }
561
SetMaxBidirectionalStreamsToSend(uint32_t max_streams)562 void QuicConfig::SetMaxBidirectionalStreamsToSend(uint32_t max_streams) {
563 max_bidirectional_streams_.SetSendValue(max_streams);
564 }
565
GetMaxBidirectionalStreamsToSend() const566 uint32_t QuicConfig::GetMaxBidirectionalStreamsToSend() const {
567 return max_bidirectional_streams_.GetSendValue();
568 }
569
HasReceivedMaxBidirectionalStreams() const570 bool QuicConfig::HasReceivedMaxBidirectionalStreams() const {
571 return max_bidirectional_streams_.HasReceivedValue();
572 }
573
ReceivedMaxBidirectionalStreams() const574 uint32_t QuicConfig::ReceivedMaxBidirectionalStreams() const {
575 return max_bidirectional_streams_.GetReceivedValue();
576 }
577
SetMaxUnidirectionalStreamsToSend(uint32_t max_streams)578 void QuicConfig::SetMaxUnidirectionalStreamsToSend(uint32_t max_streams) {
579 max_unidirectional_streams_.SetSendValue(max_streams);
580 }
581
GetMaxUnidirectionalStreamsToSend() const582 uint32_t QuicConfig::GetMaxUnidirectionalStreamsToSend() const {
583 return max_unidirectional_streams_.GetSendValue();
584 }
585
HasReceivedMaxUnidirectionalStreams() const586 bool QuicConfig::HasReceivedMaxUnidirectionalStreams() const {
587 return max_unidirectional_streams_.HasReceivedValue();
588 }
589
ReceivedMaxUnidirectionalStreams() const590 uint32_t QuicConfig::ReceivedMaxUnidirectionalStreams() const {
591 return max_unidirectional_streams_.GetReceivedValue();
592 }
593
SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms)594 void QuicConfig::SetMaxAckDelayToSendMs(uint32_t max_ack_delay_ms) {
595 max_ack_delay_ms_.SetSendValue(max_ack_delay_ms);
596 }
597
GetMaxAckDelayToSendMs() const598 uint32_t QuicConfig::GetMaxAckDelayToSendMs() const {
599 return max_ack_delay_ms_.GetSendValue();
600 }
601
HasReceivedMaxAckDelayMs() const602 bool QuicConfig::HasReceivedMaxAckDelayMs() const {
603 return max_ack_delay_ms_.HasReceivedValue();
604 }
605
ReceivedMaxAckDelayMs() const606 uint32_t QuicConfig::ReceivedMaxAckDelayMs() const {
607 return max_ack_delay_ms_.GetReceivedValue();
608 }
609
SetMinAckDelayMs(uint32_t min_ack_delay_ms)610 void QuicConfig::SetMinAckDelayMs(uint32_t min_ack_delay_ms) {
611 min_ack_delay_ms_.SetSendValue(min_ack_delay_ms);
612 }
613
GetMinAckDelayToSendMs() const614 uint32_t QuicConfig::GetMinAckDelayToSendMs() const {
615 return min_ack_delay_ms_.GetSendValue();
616 }
617
HasReceivedMinAckDelayMs() const618 bool QuicConfig::HasReceivedMinAckDelayMs() const {
619 return min_ack_delay_ms_.HasReceivedValue();
620 }
621
ReceivedMinAckDelayMs() const622 uint32_t QuicConfig::ReceivedMinAckDelayMs() const {
623 return min_ack_delay_ms_.GetReceivedValue();
624 }
625
SetAckDelayExponentToSend(uint32_t exponent)626 void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
627 ack_delay_exponent_.SetSendValue(exponent);
628 }
629
GetAckDelayExponentToSend() const630 uint32_t QuicConfig::GetAckDelayExponentToSend() const {
631 return ack_delay_exponent_.GetSendValue();
632 }
633
HasReceivedAckDelayExponent() const634 bool QuicConfig::HasReceivedAckDelayExponent() const {
635 return ack_delay_exponent_.HasReceivedValue();
636 }
637
ReceivedAckDelayExponent() const638 uint32_t QuicConfig::ReceivedAckDelayExponent() const {
639 return ack_delay_exponent_.GetReceivedValue();
640 }
641
SetMaxPacketSizeToSend(uint64_t max_udp_payload_size)642 void QuicConfig::SetMaxPacketSizeToSend(uint64_t max_udp_payload_size) {
643 max_udp_payload_size_.SetSendValue(max_udp_payload_size);
644 }
645
GetMaxPacketSizeToSend() const646 uint64_t QuicConfig::GetMaxPacketSizeToSend() const {
647 return max_udp_payload_size_.GetSendValue();
648 }
649
HasReceivedMaxPacketSize() const650 bool QuicConfig::HasReceivedMaxPacketSize() const {
651 return max_udp_payload_size_.HasReceivedValue();
652 }
653
ReceivedMaxPacketSize() const654 uint64_t QuicConfig::ReceivedMaxPacketSize() const {
655 return max_udp_payload_size_.GetReceivedValue();
656 }
657
SetMaxDatagramFrameSizeToSend(uint64_t max_datagram_frame_size)658 void QuicConfig::SetMaxDatagramFrameSizeToSend(
659 uint64_t max_datagram_frame_size) {
660 max_datagram_frame_size_.SetSendValue(max_datagram_frame_size);
661 }
662
GetMaxDatagramFrameSizeToSend() const663 uint64_t QuicConfig::GetMaxDatagramFrameSizeToSend() const {
664 return max_datagram_frame_size_.GetSendValue();
665 }
666
HasReceivedMaxDatagramFrameSize() const667 bool QuicConfig::HasReceivedMaxDatagramFrameSize() const {
668 return max_datagram_frame_size_.HasReceivedValue();
669 }
670
ReceivedMaxDatagramFrameSize() const671 uint64_t QuicConfig::ReceivedMaxDatagramFrameSize() const {
672 return max_datagram_frame_size_.GetReceivedValue();
673 }
674
SetActiveConnectionIdLimitToSend(uint64_t active_connection_id_limit)675 void QuicConfig::SetActiveConnectionIdLimitToSend(
676 uint64_t active_connection_id_limit) {
677 active_connection_id_limit_.SetSendValue(active_connection_id_limit);
678 }
679
GetActiveConnectionIdLimitToSend() const680 uint64_t QuicConfig::GetActiveConnectionIdLimitToSend() const {
681 return active_connection_id_limit_.GetSendValue();
682 }
683
HasReceivedActiveConnectionIdLimit() const684 bool QuicConfig::HasReceivedActiveConnectionIdLimit() const {
685 return active_connection_id_limit_.HasReceivedValue();
686 }
687
ReceivedActiveConnectionIdLimit() const688 uint64_t QuicConfig::ReceivedActiveConnectionIdLimit() const {
689 return active_connection_id_limit_.GetReceivedValue();
690 }
691
HasSetBytesForConnectionIdToSend() const692 bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
693 return bytes_for_connection_id_.HasSendValue();
694 }
695
SetBytesForConnectionIdToSend(uint32_t bytes)696 void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
697 bytes_for_connection_id_.SetSendValue(bytes);
698 }
699
HasReceivedBytesForConnectionId() const700 bool QuicConfig::HasReceivedBytesForConnectionId() const {
701 return bytes_for_connection_id_.HasReceivedValue();
702 }
703
ReceivedBytesForConnectionId() const704 uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
705 return bytes_for_connection_id_.GetReceivedValue();
706 }
707
SetInitialRoundTripTimeUsToSend(uint64_t rtt)708 void QuicConfig::SetInitialRoundTripTimeUsToSend(uint64_t rtt) {
709 initial_round_trip_time_us_.SetSendValue(rtt);
710 }
711
HasReceivedInitialRoundTripTimeUs() const712 bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
713 return initial_round_trip_time_us_.HasReceivedValue();
714 }
715
ReceivedInitialRoundTripTimeUs() const716 uint64_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
717 return initial_round_trip_time_us_.GetReceivedValue();
718 }
719
HasInitialRoundTripTimeUsToSend() const720 bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
721 return initial_round_trip_time_us_.HasSendValue();
722 }
723
GetInitialRoundTripTimeUsToSend() const724 uint64_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
725 return initial_round_trip_time_us_.GetSendValue();
726 }
727
SetInitialStreamFlowControlWindowToSend(uint64_t window_bytes)728 void QuicConfig::SetInitialStreamFlowControlWindowToSend(
729 uint64_t window_bytes) {
730 if (window_bytes < kMinimumFlowControlSendWindow) {
731 QUIC_BUG(quic_bug_10575_7)
732 << "Initial stream flow control receive window (" << window_bytes
733 << ") cannot be set lower than minimum ("
734 << kMinimumFlowControlSendWindow << ").";
735 window_bytes = kMinimumFlowControlSendWindow;
736 }
737 initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
738 }
739
GetInitialStreamFlowControlWindowToSend() const740 uint64_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
741 return initial_stream_flow_control_window_bytes_.GetSendValue();
742 }
743
HasReceivedInitialStreamFlowControlWindowBytes() const744 bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
745 return initial_stream_flow_control_window_bytes_.HasReceivedValue();
746 }
747
ReceivedInitialStreamFlowControlWindowBytes() const748 uint64_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
749 return initial_stream_flow_control_window_bytes_.GetReceivedValue();
750 }
751
SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(uint64_t window_bytes)752 void QuicConfig::SetInitialMaxStreamDataBytesIncomingBidirectionalToSend(
753 uint64_t window_bytes) {
754 initial_max_stream_data_bytes_incoming_bidirectional_.SetSendValue(
755 window_bytes);
756 }
757
GetInitialMaxStreamDataBytesIncomingBidirectionalToSend() const758 uint64_t QuicConfig::GetInitialMaxStreamDataBytesIncomingBidirectionalToSend()
759 const {
760 if (initial_max_stream_data_bytes_incoming_bidirectional_.HasSendValue()) {
761 return initial_max_stream_data_bytes_incoming_bidirectional_.GetSendValue();
762 }
763 return initial_stream_flow_control_window_bytes_.GetSendValue();
764 }
765
HasReceivedInitialMaxStreamDataBytesIncomingBidirectional() const766 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesIncomingBidirectional()
767 const {
768 return initial_max_stream_data_bytes_incoming_bidirectional_
769 .HasReceivedValue();
770 }
771
ReceivedInitialMaxStreamDataBytesIncomingBidirectional() const772 uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesIncomingBidirectional()
773 const {
774 return initial_max_stream_data_bytes_incoming_bidirectional_
775 .GetReceivedValue();
776 }
777
SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(uint64_t window_bytes)778 void QuicConfig::SetInitialMaxStreamDataBytesOutgoingBidirectionalToSend(
779 uint64_t window_bytes) {
780 initial_max_stream_data_bytes_outgoing_bidirectional_.SetSendValue(
781 window_bytes);
782 }
783
GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend() const784 uint64_t QuicConfig::GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend()
785 const {
786 if (initial_max_stream_data_bytes_outgoing_bidirectional_.HasSendValue()) {
787 return initial_max_stream_data_bytes_outgoing_bidirectional_.GetSendValue();
788 }
789 return initial_stream_flow_control_window_bytes_.GetSendValue();
790 }
791
HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const792 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
793 const {
794 return initial_max_stream_data_bytes_outgoing_bidirectional_
795 .HasReceivedValue();
796 }
797
ReceivedInitialMaxStreamDataBytesOutgoingBidirectional() const798 uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesOutgoingBidirectional()
799 const {
800 return initial_max_stream_data_bytes_outgoing_bidirectional_
801 .GetReceivedValue();
802 }
803
SetInitialMaxStreamDataBytesUnidirectionalToSend(uint64_t window_bytes)804 void QuicConfig::SetInitialMaxStreamDataBytesUnidirectionalToSend(
805 uint64_t window_bytes) {
806 initial_max_stream_data_bytes_unidirectional_.SetSendValue(window_bytes);
807 }
808
GetInitialMaxStreamDataBytesUnidirectionalToSend() const809 uint64_t QuicConfig::GetInitialMaxStreamDataBytesUnidirectionalToSend() const {
810 if (initial_max_stream_data_bytes_unidirectional_.HasSendValue()) {
811 return initial_max_stream_data_bytes_unidirectional_.GetSendValue();
812 }
813 return initial_stream_flow_control_window_bytes_.GetSendValue();
814 }
815
HasReceivedInitialMaxStreamDataBytesUnidirectional() const816 bool QuicConfig::HasReceivedInitialMaxStreamDataBytesUnidirectional() const {
817 return initial_max_stream_data_bytes_unidirectional_.HasReceivedValue();
818 }
819
ReceivedInitialMaxStreamDataBytesUnidirectional() const820 uint64_t QuicConfig::ReceivedInitialMaxStreamDataBytesUnidirectional() const {
821 return initial_max_stream_data_bytes_unidirectional_.GetReceivedValue();
822 }
823
SetInitialSessionFlowControlWindowToSend(uint64_t window_bytes)824 void QuicConfig::SetInitialSessionFlowControlWindowToSend(
825 uint64_t window_bytes) {
826 if (window_bytes < kMinimumFlowControlSendWindow) {
827 QUIC_BUG(quic_bug_10575_8)
828 << "Initial session flow control receive window (" << window_bytes
829 << ") cannot be set lower than default ("
830 << kMinimumFlowControlSendWindow << ").";
831 window_bytes = kMinimumFlowControlSendWindow;
832 }
833 initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
834 }
835
GetInitialSessionFlowControlWindowToSend() const836 uint64_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
837 return initial_session_flow_control_window_bytes_.GetSendValue();
838 }
839
HasReceivedInitialSessionFlowControlWindowBytes() const840 bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
841 return initial_session_flow_control_window_bytes_.HasReceivedValue();
842 }
843
ReceivedInitialSessionFlowControlWindowBytes() const844 uint64_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
845 return initial_session_flow_control_window_bytes_.GetReceivedValue();
846 }
847
SetDisableConnectionMigration()848 void QuicConfig::SetDisableConnectionMigration() {
849 connection_migration_disabled_.SetSendValue(1);
850 }
851
DisableConnectionMigration() const852 bool QuicConfig::DisableConnectionMigration() const {
853 return connection_migration_disabled_.HasReceivedValue();
854 }
855
SetIPv6AlternateServerAddressToSend(const QuicSocketAddress & alternate_server_address_ipv6)856 void QuicConfig::SetIPv6AlternateServerAddressToSend(
857 const QuicSocketAddress& alternate_server_address_ipv6) {
858 if (!alternate_server_address_ipv6.Normalized().host().IsIPv6()) {
859 QUIC_BUG(quic_bug_10575_9)
860 << "Cannot use SetIPv6AlternateServerAddressToSend with "
861 << alternate_server_address_ipv6;
862 return;
863 }
864 alternate_server_address_ipv6_.SetSendValue(alternate_server_address_ipv6);
865 }
866
HasReceivedIPv6AlternateServerAddress() const867 bool QuicConfig::HasReceivedIPv6AlternateServerAddress() const {
868 return alternate_server_address_ipv6_.HasReceivedValue();
869 }
870
ReceivedIPv6AlternateServerAddress() const871 const QuicSocketAddress& QuicConfig::ReceivedIPv6AlternateServerAddress()
872 const {
873 return alternate_server_address_ipv6_.GetReceivedValue();
874 }
875
SetIPv4AlternateServerAddressToSend(const QuicSocketAddress & alternate_server_address_ipv4)876 void QuicConfig::SetIPv4AlternateServerAddressToSend(
877 const QuicSocketAddress& alternate_server_address_ipv4) {
878 if (!alternate_server_address_ipv4.host().IsIPv4()) {
879 QUIC_BUG(quic_bug_10575_11)
880 << "Cannot use SetIPv4AlternateServerAddressToSend with "
881 << alternate_server_address_ipv4;
882 return;
883 }
884 alternate_server_address_ipv4_.SetSendValue(alternate_server_address_ipv4);
885 }
886
HasReceivedIPv4AlternateServerAddress() const887 bool QuicConfig::HasReceivedIPv4AlternateServerAddress() const {
888 return alternate_server_address_ipv4_.HasReceivedValue();
889 }
890
ReceivedIPv4AlternateServerAddress() const891 const QuicSocketAddress& QuicConfig::ReceivedIPv4AlternateServerAddress()
892 const {
893 return alternate_server_address_ipv4_.GetReceivedValue();
894 }
895
SetPreferredAddressConnectionIdAndTokenToSend(const QuicConnectionId & connection_id,const StatelessResetToken & stateless_reset_token)896 void QuicConfig::SetPreferredAddressConnectionIdAndTokenToSend(
897 const QuicConnectionId& connection_id,
898 const StatelessResetToken& stateless_reset_token) {
899 if ((!alternate_server_address_ipv4_.HasSendValue() &&
900 !alternate_server_address_ipv6_.HasSendValue()) ||
901 preferred_address_connection_id_and_token_.has_value()) {
902 QUIC_BUG(quic_bug_10575_17)
903 << "Can not send connection ID and token for preferred address";
904 return;
905 }
906 preferred_address_connection_id_and_token_ =
907 std::make_pair(connection_id, stateless_reset_token);
908 }
909
HasReceivedPreferredAddressConnectionIdAndToken() const910 bool QuicConfig::HasReceivedPreferredAddressConnectionIdAndToken() const {
911 return (HasReceivedIPv6AlternateServerAddress() ||
912 HasReceivedIPv4AlternateServerAddress()) &&
913 preferred_address_connection_id_and_token_.has_value();
914 }
915
916 const std::pair<QuicConnectionId, StatelessResetToken>&
ReceivedPreferredAddressConnectionIdAndToken() const917 QuicConfig::ReceivedPreferredAddressConnectionIdAndToken() const {
918 QUICHE_DCHECK(HasReceivedPreferredAddressConnectionIdAndToken());
919 return *preferred_address_connection_id_and_token_;
920 }
921
SetOriginalConnectionIdToSend(const QuicConnectionId & original_destination_connection_id)922 void QuicConfig::SetOriginalConnectionIdToSend(
923 const QuicConnectionId& original_destination_connection_id) {
924 original_destination_connection_id_to_send_ =
925 original_destination_connection_id;
926 }
927
HasReceivedOriginalConnectionId() const928 bool QuicConfig::HasReceivedOriginalConnectionId() const {
929 return received_original_destination_connection_id_.has_value();
930 }
931
ReceivedOriginalConnectionId() const932 QuicConnectionId QuicConfig::ReceivedOriginalConnectionId() const {
933 if (!HasReceivedOriginalConnectionId()) {
934 QUIC_BUG(quic_bug_10575_13) << "No received original connection ID";
935 return EmptyQuicConnectionId();
936 }
937 return received_original_destination_connection_id_.value();
938 }
939
SetInitialSourceConnectionIdToSend(const QuicConnectionId & initial_source_connection_id)940 void QuicConfig::SetInitialSourceConnectionIdToSend(
941 const QuicConnectionId& initial_source_connection_id) {
942 initial_source_connection_id_to_send_ = initial_source_connection_id;
943 }
944
HasReceivedInitialSourceConnectionId() const945 bool QuicConfig::HasReceivedInitialSourceConnectionId() const {
946 return received_initial_source_connection_id_.has_value();
947 }
948
ReceivedInitialSourceConnectionId() const949 QuicConnectionId QuicConfig::ReceivedInitialSourceConnectionId() const {
950 if (!HasReceivedInitialSourceConnectionId()) {
951 QUIC_BUG(quic_bug_10575_14) << "No received initial source connection ID";
952 return EmptyQuicConnectionId();
953 }
954 return received_initial_source_connection_id_.value();
955 }
956
SetRetrySourceConnectionIdToSend(const QuicConnectionId & retry_source_connection_id)957 void QuicConfig::SetRetrySourceConnectionIdToSend(
958 const QuicConnectionId& retry_source_connection_id) {
959 retry_source_connection_id_to_send_ = retry_source_connection_id;
960 }
961
HasReceivedRetrySourceConnectionId() const962 bool QuicConfig::HasReceivedRetrySourceConnectionId() const {
963 return received_retry_source_connection_id_.has_value();
964 }
965
ReceivedRetrySourceConnectionId() const966 QuicConnectionId QuicConfig::ReceivedRetrySourceConnectionId() const {
967 if (!HasReceivedRetrySourceConnectionId()) {
968 QUIC_BUG(quic_bug_10575_15) << "No received retry source connection ID";
969 return EmptyQuicConnectionId();
970 }
971 return received_retry_source_connection_id_.value();
972 }
973
SetStatelessResetTokenToSend(const StatelessResetToken & stateless_reset_token)974 void QuicConfig::SetStatelessResetTokenToSend(
975 const StatelessResetToken& stateless_reset_token) {
976 stateless_reset_token_.SetSendValue(stateless_reset_token);
977 }
978
HasStatelessResetTokenToSend() const979 bool QuicConfig::HasStatelessResetTokenToSend() const {
980 return stateless_reset_token_.HasSendValue();
981 }
982
HasReceivedStatelessResetToken() const983 bool QuicConfig::HasReceivedStatelessResetToken() const {
984 return stateless_reset_token_.HasReceivedValue();
985 }
986
ReceivedStatelessResetToken() const987 const StatelessResetToken& QuicConfig::ReceivedStatelessResetToken() const {
988 return stateless_reset_token_.GetReceivedValue();
989 }
990
negotiated() const991 bool QuicConfig::negotiated() const { return negotiated_; }
992
SetCreateSessionTagIndicators(QuicTagVector tags)993 void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
994 create_session_tag_indicators_ = std::move(tags);
995 }
996
create_session_tag_indicators() const997 const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
998 return create_session_tag_indicators_;
999 }
1000
SetDefaults()1001 void QuicConfig::SetDefaults() {
1002 SetIdleNetworkTimeout(QuicTime::Delta::FromSeconds(kMaximumIdleTimeoutSecs));
1003 SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
1004 SetMaxUnidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
1005 max_time_before_crypto_handshake_ =
1006 QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
1007 max_idle_time_before_crypto_handshake_ =
1008 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
1009 max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
1010
1011 SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
1012 SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
1013 SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
1014 SetAckDelayExponentToSend(kDefaultAckDelayExponent);
1015 SetMaxPacketSizeToSend(kMaxIncomingPacketSize);
1016 SetMaxDatagramFrameSizeToSend(kMaxAcceptedDatagramFrameSize);
1017 }
1018
ToHandshakeMessage(CryptoHandshakeMessage * out,QuicTransportVersion transport_version) const1019 void QuicConfig::ToHandshakeMessage(
1020 CryptoHandshakeMessage* out, QuicTransportVersion transport_version) const {
1021 // Idle timeout has custom rules that are different from other values.
1022 // We configure ourselves with the minumum value between the one sent and
1023 // the one received. Additionally, when QUIC_CRYPTO is used, the server
1024 // MUST send an idle timeout no greater than the idle timeout it received
1025 // from the client. We therefore send the received value if it is lower.
1026 QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
1027 uint32_t max_idle_timeout_to_send_seconds =
1028 max_idle_timeout_to_send_.ToSeconds();
1029 if (received_max_idle_timeout_.has_value() &&
1030 received_max_idle_timeout_->ToSeconds() <
1031 max_idle_timeout_to_send_seconds) {
1032 max_idle_timeout_to_send_seconds = received_max_idle_timeout_->ToSeconds();
1033 }
1034 max_idle_timeout_seconds.SetSendValue(max_idle_timeout_to_send_seconds);
1035 max_idle_timeout_seconds.ToHandshakeMessage(out);
1036
1037 // Do not need a version check here, max...bi... will encode
1038 // as "MIDS" -- the max initial dynamic streams tag -- if
1039 // doing some version other than IETF QUIC.
1040 max_bidirectional_streams_.ToHandshakeMessage(out);
1041 if (VersionHasIetfQuicFrames(transport_version)) {
1042 max_unidirectional_streams_.ToHandshakeMessage(out);
1043 ack_delay_exponent_.ToHandshakeMessage(out);
1044 }
1045 if (max_ack_delay_ms_.GetSendValue() != kDefaultDelayedAckTimeMs) {
1046 // Only send max ack delay if it is using a non-default value, because
1047 // the default value is used by QuicSentPacketManager if it is not
1048 // sent during the handshake, and we want to save bytes.
1049 max_ack_delay_ms_.ToHandshakeMessage(out);
1050 }
1051 bytes_for_connection_id_.ToHandshakeMessage(out);
1052 initial_round_trip_time_us_.ToHandshakeMessage(out);
1053 initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
1054 initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
1055 connection_migration_disabled_.ToHandshakeMessage(out);
1056 connection_options_.ToHandshakeMessage(out);
1057 if (alternate_server_address_ipv6_.HasSendValue()) {
1058 alternate_server_address_ipv6_.ToHandshakeMessage(out);
1059 } else {
1060 alternate_server_address_ipv4_.ToHandshakeMessage(out);
1061 }
1062 stateless_reset_token_.ToHandshakeMessage(out);
1063 }
1064
ProcessPeerHello(const CryptoHandshakeMessage & peer_hello,HelloType hello_type,std::string * error_details)1065 QuicErrorCode QuicConfig::ProcessPeerHello(
1066 const CryptoHandshakeMessage& peer_hello, HelloType hello_type,
1067 std::string* error_details) {
1068 QUICHE_DCHECK(error_details != nullptr);
1069
1070 QuicErrorCode error = QUIC_NO_ERROR;
1071 if (error == QUIC_NO_ERROR) {
1072 // Idle timeout has custom rules that are different from other values.
1073 // We configure ourselves with the minumum value between the one sent and
1074 // the one received. Additionally, when QUIC_CRYPTO is used, the server
1075 // MUST send an idle timeout no greater than the idle timeout it received
1076 // from the client.
1077 QuicFixedUint32 max_idle_timeout_seconds(kICSL, PRESENCE_REQUIRED);
1078 error = max_idle_timeout_seconds.ProcessPeerHello(peer_hello, hello_type,
1079 error_details);
1080 if (error == QUIC_NO_ERROR) {
1081 if (max_idle_timeout_seconds.GetReceivedValue() >
1082 max_idle_timeout_to_send_.ToSeconds()) {
1083 // The received value is higher than ours, ignore it if from the client
1084 // and raise an error if from the server.
1085 if (hello_type == SERVER) {
1086 error = QUIC_INVALID_NEGOTIATED_VALUE;
1087 *error_details =
1088 "Invalid value received for " + QuicTagToString(kICSL);
1089 }
1090 } else {
1091 received_max_idle_timeout_ = QuicTime::Delta::FromSeconds(
1092 max_idle_timeout_seconds.GetReceivedValue());
1093 }
1094 }
1095 }
1096 if (error == QUIC_NO_ERROR) {
1097 error = max_bidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
1098 error_details);
1099 }
1100 if (error == QUIC_NO_ERROR) {
1101 error = max_unidirectional_streams_.ProcessPeerHello(peer_hello, hello_type,
1102 error_details);
1103 }
1104 if (error == QUIC_NO_ERROR) {
1105 error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
1106 error_details);
1107 }
1108 if (error == QUIC_NO_ERROR) {
1109 error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
1110 error_details);
1111 }
1112 if (error == QUIC_NO_ERROR) {
1113 error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
1114 peer_hello, hello_type, error_details);
1115 }
1116 if (error == QUIC_NO_ERROR) {
1117 error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
1118 peer_hello, hello_type, error_details);
1119 }
1120 if (error == QUIC_NO_ERROR) {
1121 error = connection_migration_disabled_.ProcessPeerHello(
1122 peer_hello, hello_type, error_details);
1123 }
1124 if (error == QUIC_NO_ERROR) {
1125 error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
1126 error_details);
1127 }
1128 if (error == QUIC_NO_ERROR) {
1129 QuicFixedSocketAddress alternate_server_address(kASAD, PRESENCE_OPTIONAL);
1130 error = alternate_server_address.ProcessPeerHello(peer_hello, hello_type,
1131 error_details);
1132 if (error == QUIC_NO_ERROR && alternate_server_address.HasReceivedValue()) {
1133 const QuicSocketAddress& received_address =
1134 alternate_server_address.GetReceivedValue();
1135 if (received_address.host().IsIPv6()) {
1136 alternate_server_address_ipv6_.SetReceivedValue(received_address);
1137 } else if (received_address.host().IsIPv4()) {
1138 alternate_server_address_ipv4_.SetReceivedValue(received_address);
1139 }
1140 }
1141 }
1142 if (error == QUIC_NO_ERROR) {
1143 error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
1144 error_details);
1145 }
1146
1147 if (error == QUIC_NO_ERROR) {
1148 error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
1149 error_details);
1150 }
1151 if (error == QUIC_NO_ERROR) {
1152 error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
1153 error_details);
1154 }
1155 if (error == QUIC_NO_ERROR) {
1156 negotiated_ = true;
1157 }
1158 return error;
1159 }
1160
FillTransportParameters(TransportParameters * params) const1161 bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
1162 if (original_destination_connection_id_to_send_.has_value()) {
1163 params->original_destination_connection_id =
1164 original_destination_connection_id_to_send_.value();
1165 }
1166
1167 params->max_idle_timeout_ms.set_value(
1168 max_idle_timeout_to_send_.ToMilliseconds());
1169
1170 if (stateless_reset_token_.HasSendValue()) {
1171 StatelessResetToken stateless_reset_token =
1172 stateless_reset_token_.GetSendValue();
1173 params->stateless_reset_token.assign(
1174 reinterpret_cast<const char*>(&stateless_reset_token),
1175 reinterpret_cast<const char*>(&stateless_reset_token) +
1176 sizeof(stateless_reset_token));
1177 }
1178
1179 params->max_udp_payload_size.set_value(GetMaxPacketSizeToSend());
1180 params->max_datagram_frame_size.set_value(GetMaxDatagramFrameSizeToSend());
1181 params->initial_max_data.set_value(
1182 GetInitialSessionFlowControlWindowToSend());
1183 // The max stream data bidirectional transport parameters can be either local
1184 // or remote. A stream is local iff it is initiated by the endpoint that sent
1185 // the transport parameter (see the Transport Parameter Definitions section of
1186 // draft-ietf-quic-transport). In this function we are sending transport
1187 // parameters, so a local stream is one we initiated, which means an outgoing
1188 // stream.
1189 params->initial_max_stream_data_bidi_local.set_value(
1190 GetInitialMaxStreamDataBytesOutgoingBidirectionalToSend());
1191 params->initial_max_stream_data_bidi_remote.set_value(
1192 GetInitialMaxStreamDataBytesIncomingBidirectionalToSend());
1193 params->initial_max_stream_data_uni.set_value(
1194 GetInitialMaxStreamDataBytesUnidirectionalToSend());
1195 params->initial_max_streams_bidi.set_value(
1196 GetMaxBidirectionalStreamsToSend());
1197 params->initial_max_streams_uni.set_value(
1198 GetMaxUnidirectionalStreamsToSend());
1199 params->max_ack_delay.set_value(GetMaxAckDelayToSendMs());
1200 if (min_ack_delay_ms_.HasSendValue()) {
1201 params->min_ack_delay_us.set_value(min_ack_delay_ms_.GetSendValue() *
1202 kNumMicrosPerMilli);
1203 }
1204 params->ack_delay_exponent.set_value(GetAckDelayExponentToSend());
1205 params->disable_active_migration =
1206 connection_migration_disabled_.HasSendValue() &&
1207 connection_migration_disabled_.GetSendValue() != 0;
1208
1209 if (alternate_server_address_ipv6_.HasSendValue() ||
1210 alternate_server_address_ipv4_.HasSendValue()) {
1211 TransportParameters::PreferredAddress preferred_address;
1212 if (alternate_server_address_ipv6_.HasSendValue()) {
1213 preferred_address.ipv6_socket_address =
1214 alternate_server_address_ipv6_.GetSendValue();
1215 }
1216 if (alternate_server_address_ipv4_.HasSendValue()) {
1217 preferred_address.ipv4_socket_address =
1218 alternate_server_address_ipv4_.GetSendValue();
1219 }
1220 if (preferred_address_connection_id_and_token_) {
1221 preferred_address.connection_id =
1222 preferred_address_connection_id_and_token_->first;
1223 auto* begin = reinterpret_cast<const char*>(
1224 &preferred_address_connection_id_and_token_->second);
1225 auto* end =
1226 begin + sizeof(preferred_address_connection_id_and_token_->second);
1227 preferred_address.stateless_reset_token.assign(begin, end);
1228 }
1229 params->preferred_address =
1230 std::make_unique<TransportParameters::PreferredAddress>(
1231 preferred_address);
1232 }
1233
1234 if (active_connection_id_limit_.HasSendValue()) {
1235 params->active_connection_id_limit.set_value(
1236 active_connection_id_limit_.GetSendValue());
1237 }
1238
1239 if (initial_source_connection_id_to_send_.has_value()) {
1240 params->initial_source_connection_id =
1241 initial_source_connection_id_to_send_.value();
1242 }
1243
1244 if (retry_source_connection_id_to_send_.has_value()) {
1245 params->retry_source_connection_id =
1246 retry_source_connection_id_to_send_.value();
1247 }
1248
1249 if (initial_round_trip_time_us_.HasSendValue()) {
1250 params->initial_round_trip_time_us.set_value(
1251 initial_round_trip_time_us_.GetSendValue());
1252 }
1253 if (connection_options_.HasSendValues() &&
1254 !connection_options_.GetSendValues().empty()) {
1255 params->google_connection_options = connection_options_.GetSendValues();
1256 }
1257
1258 if (google_handshake_message_to_send_.has_value()) {
1259 params->google_handshake_message = google_handshake_message_to_send_;
1260 }
1261
1262 params->custom_parameters = custom_transport_parameters_to_send_;
1263
1264 return true;
1265 }
1266
ProcessTransportParameters(const TransportParameters & params,bool is_resumption,std::string * error_details)1267 QuicErrorCode QuicConfig::ProcessTransportParameters(
1268 const TransportParameters& params, bool is_resumption,
1269 std::string* error_details) {
1270 if (!is_resumption && params.original_destination_connection_id.has_value()) {
1271 received_original_destination_connection_id_ =
1272 params.original_destination_connection_id.value();
1273 }
1274
1275 if (params.max_idle_timeout_ms.value() > 0 &&
1276 params.max_idle_timeout_ms.value() <
1277 static_cast<uint64_t>(max_idle_timeout_to_send_.ToMilliseconds())) {
1278 // An idle timeout of zero indicates it is disabled.
1279 // We also ignore values higher than ours which will cause us to use the
1280 // smallest value between ours and our peer's.
1281 received_max_idle_timeout_ =
1282 QuicTime::Delta::FromMilliseconds(params.max_idle_timeout_ms.value());
1283 }
1284
1285 if (!is_resumption && !params.stateless_reset_token.empty()) {
1286 StatelessResetToken stateless_reset_token;
1287 if (params.stateless_reset_token.size() != sizeof(stateless_reset_token)) {
1288 QUIC_BUG(quic_bug_10575_16) << "Bad stateless reset token length "
1289 << params.stateless_reset_token.size();
1290 *error_details = "Bad stateless reset token length";
1291 return QUIC_INTERNAL_ERROR;
1292 }
1293 memcpy(&stateless_reset_token, params.stateless_reset_token.data(),
1294 params.stateless_reset_token.size());
1295 stateless_reset_token_.SetReceivedValue(stateless_reset_token);
1296 }
1297
1298 if (params.max_udp_payload_size.IsValid()) {
1299 max_udp_payload_size_.SetReceivedValue(params.max_udp_payload_size.value());
1300 }
1301
1302 if (params.max_datagram_frame_size.IsValid()) {
1303 max_datagram_frame_size_.SetReceivedValue(
1304 params.max_datagram_frame_size.value());
1305 }
1306
1307 initial_session_flow_control_window_bytes_.SetReceivedValue(
1308 params.initial_max_data.value());
1309
1310 // IETF QUIC specifies stream IDs and stream counts as 62-bit integers but
1311 // our implementation uses uint32_t to represent them to save memory.
1312 max_bidirectional_streams_.SetReceivedValue(
1313 std::min<uint64_t>(params.initial_max_streams_bidi.value(),
1314 std::numeric_limits<uint32_t>::max()));
1315 max_unidirectional_streams_.SetReceivedValue(
1316 std::min<uint64_t>(params.initial_max_streams_uni.value(),
1317 std::numeric_limits<uint32_t>::max()));
1318
1319 // The max stream data bidirectional transport parameters can be either local
1320 // or remote. A stream is local iff it is initiated by the endpoint that sent
1321 // the transport parameter (see the Transport Parameter Definitions section of
1322 // draft-ietf-quic-transport). However in this function we are processing
1323 // received transport parameters, so a local stream is one initiated by our
1324 // peer, which means an incoming stream.
1325 initial_max_stream_data_bytes_incoming_bidirectional_.SetReceivedValue(
1326 params.initial_max_stream_data_bidi_local.value());
1327 initial_max_stream_data_bytes_outgoing_bidirectional_.SetReceivedValue(
1328 params.initial_max_stream_data_bidi_remote.value());
1329 initial_max_stream_data_bytes_unidirectional_.SetReceivedValue(
1330 params.initial_max_stream_data_uni.value());
1331
1332 if (!is_resumption) {
1333 max_ack_delay_ms_.SetReceivedValue(params.max_ack_delay.value());
1334 if (params.ack_delay_exponent.IsValid()) {
1335 ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
1336 }
1337 if (params.preferred_address != nullptr) {
1338 if (params.preferred_address->ipv6_socket_address.port() != 0) {
1339 alternate_server_address_ipv6_.SetReceivedValue(
1340 params.preferred_address->ipv6_socket_address);
1341 }
1342 if (params.preferred_address->ipv4_socket_address.port() != 0) {
1343 alternate_server_address_ipv4_.SetReceivedValue(
1344 params.preferred_address->ipv4_socket_address);
1345 }
1346 // TODO(haoyuewang) Treat 0 length connection ID sent in preferred_address
1347 // as a connection error of type TRANSPORT_PARAMETER_ERROR when server
1348 // fully supports it.
1349 if (!params.preferred_address->connection_id.IsEmpty()) {
1350 preferred_address_connection_id_and_token_ = std::make_pair(
1351 params.preferred_address->connection_id,
1352 *reinterpret_cast<const StatelessResetToken*>(
1353 ¶ms.preferred_address->stateless_reset_token.front()));
1354 }
1355 }
1356 if (params.min_ack_delay_us.value() != 0) {
1357 if (params.min_ack_delay_us.value() >
1358 params.max_ack_delay.value() * kNumMicrosPerMilli) {
1359 *error_details = "MinAckDelay is greater than MaxAckDelay.";
1360 return IETF_QUIC_PROTOCOL_VIOLATION;
1361 }
1362 min_ack_delay_ms_.SetReceivedValue(params.min_ack_delay_us.value() /
1363 kNumMicrosPerMilli);
1364 }
1365 }
1366
1367 if (params.disable_active_migration) {
1368 connection_migration_disabled_.SetReceivedValue(1u);
1369 }
1370
1371 active_connection_id_limit_.SetReceivedValue(
1372 params.active_connection_id_limit.value());
1373
1374 if (!is_resumption) {
1375 if (params.initial_source_connection_id.has_value()) {
1376 received_initial_source_connection_id_ =
1377 params.initial_source_connection_id.value();
1378 }
1379 if (params.retry_source_connection_id.has_value()) {
1380 received_retry_source_connection_id_ =
1381 params.retry_source_connection_id.value();
1382 }
1383 }
1384
1385 if (params.initial_round_trip_time_us.value() > 0) {
1386 initial_round_trip_time_us_.SetReceivedValue(
1387 params.initial_round_trip_time_us.value());
1388 }
1389 if (params.google_connection_options.has_value()) {
1390 connection_options_.SetReceivedValues(
1391 params.google_connection_options.value());
1392 }
1393 if (params.google_handshake_message.has_value()) {
1394 received_google_handshake_message_ = params.google_handshake_message;
1395 }
1396
1397 received_custom_transport_parameters_ = params.custom_parameters;
1398
1399 if (!is_resumption) {
1400 negotiated_ = true;
1401 }
1402 *error_details = "";
1403 return QUIC_NO_ERROR;
1404 }
1405
ClearGoogleHandshakeMessage()1406 void QuicConfig::ClearGoogleHandshakeMessage() {
1407 google_handshake_message_to_send_.reset();
1408 received_google_handshake_message_.reset();
1409 }
1410
GetPreferredAddressToSend(quiche::IpAddressFamily address_family) const1411 absl::optional<QuicSocketAddress> QuicConfig::GetPreferredAddressToSend(
1412 quiche::IpAddressFamily address_family) const {
1413 if (alternate_server_address_ipv6_.HasSendValue() &&
1414 address_family == quiche::IpAddressFamily::IP_V6) {
1415 return alternate_server_address_ipv6_.GetSendValue();
1416 }
1417
1418 if (alternate_server_address_ipv4_.HasSendValue() &&
1419 address_family == quiche::IpAddressFamily::IP_V4) {
1420 return alternate_server_address_ipv4_.GetSendValue();
1421 }
1422 return absl::nullopt;
1423 }
1424
ClearAlternateServerAddressToSend(quiche::IpAddressFamily address_family)1425 void QuicConfig::ClearAlternateServerAddressToSend(
1426 quiche::IpAddressFamily address_family) {
1427 if (address_family == quiche::IpAddressFamily::IP_V4) {
1428 alternate_server_address_ipv4_.ClearSendValue();
1429 } else if (address_family == quiche::IpAddressFamily::IP_V6) {
1430 alternate_server_address_ipv6_.ClearSendValue();
1431 }
1432 }
1433
1434 } // namespace quic
1435