• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                 &params.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