blob: 25b549cdafeb8bb0b4539a8688ed447fd0b891df [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 "net/third_party/quiche/src/quic/core/quic_config.h"
6
7#include <algorithm>
vasilvv872e7a32019-03-12 16:42:44 -07008#include <string>
QUICHE teama6ef0a62019-03-07 20:34:33 -05009
10#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake_message.h"
11#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
12#include "net/third_party/quiche/src/quic/core/quic_socket_address_coder.h"
13#include "net/third_party/quiche/src/quic/core/quic_utils.h"
14#include "net/third_party/quiche/src/quic/platform/api/quic_bug_tracker.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
16#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
17#include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
18#include "net/third_party/quiche/src/quic/platform/api/quic_macros.h"
19#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050020#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
21
22namespace quic {
23
24// Reads the value corresponding to |name_| from |msg| into |out|. If the
25// |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set
26// to |default_value|.
27QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg,
28 QuicTag tag,
29 QuicConfigPresence presence,
30 uint32_t default_value,
31 uint32_t* out,
vasilvvc48c8712019-03-11 13:38:16 -070032 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -050033 DCHECK(error_details != nullptr);
34 QuicErrorCode error = msg.GetUint32(tag, out);
35 switch (error) {
36 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
37 if (presence == PRESENCE_REQUIRED) {
38 *error_details = "Missing " + QuicTagToString(tag);
39 break;
40 }
41 error = QUIC_NO_ERROR;
42 *out = default_value;
43 break;
44 case QUIC_NO_ERROR:
45 break;
46 default:
47 *error_details = "Bad " + QuicTagToString(tag);
48 break;
49 }
50 return error;
51}
52
53QuicConfigValue::QuicConfigValue(QuicTag tag, QuicConfigPresence presence)
54 : tag_(tag), presence_(presence) {}
55QuicConfigValue::~QuicConfigValue() {}
56
57QuicNegotiableValue::QuicNegotiableValue(QuicTag tag,
58 QuicConfigPresence presence)
59 : QuicConfigValue(tag, presence), negotiated_(false) {}
60QuicNegotiableValue::~QuicNegotiableValue() {}
61
62QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag,
63 QuicConfigPresence presence)
64 : QuicNegotiableValue(tag, presence),
65 max_value_(0),
66 default_value_(0),
67 negotiated_value_(0) {}
68QuicNegotiableUint32::~QuicNegotiableUint32() {}
69
70void QuicNegotiableUint32::set(uint32_t max, uint32_t default_value) {
71 DCHECK_LE(default_value, max);
72 max_value_ = max;
73 default_value_ = default_value;
74}
75
76uint32_t QuicNegotiableUint32::GetUint32() const {
77 if (negotiated()) {
78 return negotiated_value_;
79 }
80 return default_value_;
81}
82
83// Returns the maximum value negotiable.
84uint32_t QuicNegotiableUint32::GetMax() const {
85 return max_value_;
86}
87
88void QuicNegotiableUint32::ToHandshakeMessage(
89 CryptoHandshakeMessage* out) const {
90 if (negotiated()) {
91 out->SetValue(tag_, negotiated_value_);
92 } else {
93 out->SetValue(tag_, max_value_);
94 }
95}
96
97QuicErrorCode QuicNegotiableUint32::ProcessPeerHello(
98 const CryptoHandshakeMessage& peer_hello,
99 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700100 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101 DCHECK(!negotiated());
102 DCHECK(error_details != nullptr);
103 uint32_t value;
104 QuicErrorCode error = ReadUint32(peer_hello, tag_, presence_, default_value_,
105 &value, error_details);
106 if (error != QUIC_NO_ERROR) {
107 return error;
108 }
109 return ReceiveValue(value, hello_type, error_details);
110}
111
112QuicErrorCode QuicNegotiableUint32::ReceiveValue(uint32_t value,
113 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700114 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500115 if (hello_type == SERVER && value > max_value_) {
116 *error_details = "Invalid value received for " + QuicTagToString(tag_);
117 return QUIC_INVALID_NEGOTIATED_VALUE;
118 }
119
120 set_negotiated(true);
121 negotiated_value_ = std::min(value, max_value_);
122 return QUIC_NO_ERROR;
123}
124
125QuicFixedUint32::QuicFixedUint32(QuicTag tag, QuicConfigPresence presence)
126 : QuicConfigValue(tag, presence),
127 has_send_value_(false),
128 has_receive_value_(false) {}
129QuicFixedUint32::~QuicFixedUint32() {}
130
131bool QuicFixedUint32::HasSendValue() const {
132 return has_send_value_;
133}
134
135uint32_t QuicFixedUint32::GetSendValue() const {
136 QUIC_BUG_IF(!has_send_value_)
137 << "No send value to get for tag:" << QuicTagToString(tag_);
138 return send_value_;
139}
140
141void QuicFixedUint32::SetSendValue(uint32_t value) {
142 has_send_value_ = true;
143 send_value_ = value;
144}
145
146bool QuicFixedUint32::HasReceivedValue() const {
147 return has_receive_value_;
148}
149
150uint32_t QuicFixedUint32::GetReceivedValue() const {
151 QUIC_BUG_IF(!has_receive_value_)
152 << "No receive value to get for tag:" << QuicTagToString(tag_);
153 return receive_value_;
154}
155
156void QuicFixedUint32::SetReceivedValue(uint32_t value) {
157 has_receive_value_ = true;
158 receive_value_ = value;
159}
160
161void QuicFixedUint32::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
162 if (has_send_value_) {
163 out->SetValue(tag_, send_value_);
164 }
165}
166
167QuicErrorCode QuicFixedUint32::ProcessPeerHello(
168 const CryptoHandshakeMessage& peer_hello,
169 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700170 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500171 DCHECK(error_details != nullptr);
172 QuicErrorCode error = peer_hello.GetUint32(tag_, &receive_value_);
173 switch (error) {
174 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
175 if (presence_ == PRESENCE_OPTIONAL) {
176 return QUIC_NO_ERROR;
177 }
178 *error_details = "Missing " + QuicTagToString(tag_);
179 break;
180 case QUIC_NO_ERROR:
181 has_receive_value_ = true;
182 break;
183 default:
184 *error_details = "Bad " + QuicTagToString(tag_);
185 break;
186 }
187 return error;
188}
189
190QuicFixedUint128::QuicFixedUint128(QuicTag tag, QuicConfigPresence presence)
191 : QuicConfigValue(tag, presence),
192 has_send_value_(false),
193 has_receive_value_(false) {}
194QuicFixedUint128::~QuicFixedUint128() {}
195
196bool QuicFixedUint128::HasSendValue() const {
197 return has_send_value_;
198}
199
200QuicUint128 QuicFixedUint128::GetSendValue() const {
201 QUIC_BUG_IF(!has_send_value_)
202 << "No send value to get for tag:" << QuicTagToString(tag_);
203 return send_value_;
204}
205
206void QuicFixedUint128::SetSendValue(QuicUint128 value) {
207 has_send_value_ = true;
208 send_value_ = value;
209}
210
211bool QuicFixedUint128::HasReceivedValue() const {
212 return has_receive_value_;
213}
214
215QuicUint128 QuicFixedUint128::GetReceivedValue() const {
216 QUIC_BUG_IF(!has_receive_value_)
217 << "No receive value to get for tag:" << QuicTagToString(tag_);
218 return receive_value_;
219}
220
221void QuicFixedUint128::SetReceivedValue(QuicUint128 value) {
222 has_receive_value_ = true;
223 receive_value_ = value;
224}
225
226void QuicFixedUint128::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
227 if (has_send_value_) {
228 out->SetValue(tag_, send_value_);
229 }
230}
231
232QuicErrorCode QuicFixedUint128::ProcessPeerHello(
233 const CryptoHandshakeMessage& peer_hello,
234 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700235 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 DCHECK(error_details != nullptr);
237 QuicErrorCode error = peer_hello.GetUint128(tag_, &receive_value_);
238 switch (error) {
239 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
240 if (presence_ == PRESENCE_OPTIONAL) {
241 return QUIC_NO_ERROR;
242 }
243 *error_details = "Missing " + QuicTagToString(tag_);
244 break;
245 case QUIC_NO_ERROR:
246 has_receive_value_ = true;
247 break;
248 default:
249 *error_details = "Bad " + QuicTagToString(tag_);
250 break;
251 }
252 return error;
253}
254
255QuicFixedTagVector::QuicFixedTagVector(QuicTag name,
256 QuicConfigPresence presence)
257 : QuicConfigValue(name, presence),
258 has_send_values_(false),
259 has_receive_values_(false) {}
260
261QuicFixedTagVector::QuicFixedTagVector(const QuicFixedTagVector& other) =
262 default;
263
264QuicFixedTagVector::~QuicFixedTagVector() {}
265
266bool QuicFixedTagVector::HasSendValues() const {
267 return has_send_values_;
268}
269
270QuicTagVector QuicFixedTagVector::GetSendValues() const {
271 QUIC_BUG_IF(!has_send_values_)
272 << "No send values to get for tag:" << QuicTagToString(tag_);
273 return send_values_;
274}
275
276void QuicFixedTagVector::SetSendValues(const QuicTagVector& values) {
277 has_send_values_ = true;
278 send_values_ = values;
279}
280
281bool QuicFixedTagVector::HasReceivedValues() const {
282 return has_receive_values_;
283}
284
285QuicTagVector QuicFixedTagVector::GetReceivedValues() const {
286 QUIC_BUG_IF(!has_receive_values_)
287 << "No receive value to get for tag:" << QuicTagToString(tag_);
288 return receive_values_;
289}
290
291void QuicFixedTagVector::SetReceivedValues(const QuicTagVector& values) {
292 has_receive_values_ = true;
293 receive_values_ = values;
294}
295
296void QuicFixedTagVector::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
297 if (has_send_values_) {
298 out->SetVector(tag_, send_values_);
299 }
300}
301
302QuicErrorCode QuicFixedTagVector::ProcessPeerHello(
303 const CryptoHandshakeMessage& peer_hello,
304 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700305 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500306 DCHECK(error_details != nullptr);
307 QuicTagVector values;
308 QuicErrorCode error = peer_hello.GetTaglist(tag_, &values);
309 switch (error) {
310 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND:
311 if (presence_ == PRESENCE_OPTIONAL) {
312 return QUIC_NO_ERROR;
313 }
314 *error_details = "Missing " + QuicTagToString(tag_);
315 break;
316 case QUIC_NO_ERROR:
317 QUIC_DVLOG(1) << "Received Connection Option tags from receiver.";
318 has_receive_values_ = true;
319 receive_values_.insert(receive_values_.end(), values.begin(),
320 values.end());
321 break;
322 default:
323 *error_details = "Bad " + QuicTagToString(tag_);
324 break;
325 }
326 return error;
327}
328
329QuicFixedSocketAddress::QuicFixedSocketAddress(QuicTag tag,
330 QuicConfigPresence presence)
331 : QuicConfigValue(tag, presence),
332 has_send_value_(false),
333 has_receive_value_(false) {}
334
335QuicFixedSocketAddress::~QuicFixedSocketAddress() {}
336
337bool QuicFixedSocketAddress::HasSendValue() const {
338 return has_send_value_;
339}
340
341const QuicSocketAddress& QuicFixedSocketAddress::GetSendValue() const {
342 QUIC_BUG_IF(!has_send_value_)
343 << "No send value to get for tag:" << QuicTagToString(tag_);
344 return send_value_;
345}
346
347void QuicFixedSocketAddress::SetSendValue(const QuicSocketAddress& value) {
348 has_send_value_ = true;
349 send_value_ = value;
350}
351
352bool QuicFixedSocketAddress::HasReceivedValue() const {
353 return has_receive_value_;
354}
355
356const QuicSocketAddress& QuicFixedSocketAddress::GetReceivedValue() const {
357 QUIC_BUG_IF(!has_receive_value_)
358 << "No receive value to get for tag:" << QuicTagToString(tag_);
359 return receive_value_;
360}
361
362void QuicFixedSocketAddress::SetReceivedValue(const QuicSocketAddress& value) {
363 has_receive_value_ = true;
364 receive_value_ = value;
365}
366
367void QuicFixedSocketAddress::ToHandshakeMessage(
368 CryptoHandshakeMessage* out) const {
369 if (has_send_value_) {
370 QuicSocketAddressCoder address_coder(send_value_);
371 out->SetStringPiece(tag_, address_coder.Encode());
372 }
373}
374
375QuicErrorCode QuicFixedSocketAddress::ProcessPeerHello(
376 const CryptoHandshakeMessage& peer_hello,
377 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700378 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500379 QuicStringPiece address;
380 if (!peer_hello.GetStringPiece(tag_, &address)) {
381 if (presence_ == PRESENCE_REQUIRED) {
382 *error_details = "Missing " + QuicTagToString(tag_);
383 return QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND;
384 }
385 } else {
386 QuicSocketAddressCoder address_coder;
387 if (address_coder.Decode(address.data(), address.length())) {
388 SetReceivedValue(
389 QuicSocketAddress(address_coder.ip(), address_coder.port()));
390 }
391 }
392 return QUIC_NO_ERROR;
393}
394
395QuicConfig::QuicConfig()
396 : max_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
397 max_idle_time_before_crypto_handshake_(QuicTime::Delta::Zero()),
398 max_undecryptable_packets_(0),
399 connection_options_(kCOPT, PRESENCE_OPTIONAL),
400 client_connection_options_(kCLOP, PRESENCE_OPTIONAL),
401 idle_network_timeout_seconds_(kICSL, PRESENCE_REQUIRED),
402 silent_close_(kSCLS, PRESENCE_OPTIONAL),
403 max_incoming_dynamic_streams_(kMIDS, PRESENCE_REQUIRED),
404 bytes_for_connection_id_(kTCID, PRESENCE_OPTIONAL),
405 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL),
406 initial_stream_flow_control_window_bytes_(kSFCW, PRESENCE_OPTIONAL),
407 initial_session_flow_control_window_bytes_(kCFCW, PRESENCE_OPTIONAL),
408 connection_migration_disabled_(kNCMR, PRESENCE_OPTIONAL),
409 alternate_server_address_(kASAD, PRESENCE_OPTIONAL),
410 support_max_header_list_size_(kSMHL, PRESENCE_OPTIONAL),
411 stateless_reset_token_(kSRST, PRESENCE_OPTIONAL) {
412 SetDefaults();
413}
414
415QuicConfig::QuicConfig(const QuicConfig& other) = default;
416
417QuicConfig::~QuicConfig() {}
418
419bool QuicConfig::SetInitialReceivedConnectionOptions(
420 const QuicTagVector& tags) {
421 if (HasReceivedConnectionOptions()) {
422 // If we have already received connection options (via handshake or due to
423 // a previous call), don't re-initialize.
424 return false;
425 }
426 connection_options_.SetReceivedValues(tags);
427 return true;
428}
429
430void QuicConfig::SetConnectionOptionsToSend(
431 const QuicTagVector& connection_options) {
432 connection_options_.SetSendValues(connection_options);
433}
434
435bool QuicConfig::HasReceivedConnectionOptions() const {
436 return connection_options_.HasReceivedValues();
437}
438
439QuicTagVector QuicConfig::ReceivedConnectionOptions() const {
440 return connection_options_.GetReceivedValues();
441}
442
443bool QuicConfig::HasSendConnectionOptions() const {
444 return connection_options_.HasSendValues();
445}
446
447QuicTagVector QuicConfig::SendConnectionOptions() const {
448 return connection_options_.GetSendValues();
449}
450
451bool QuicConfig::HasClientSentConnectionOption(QuicTag tag,
452 Perspective perspective) const {
453 if (perspective == Perspective::IS_SERVER) {
454 if (HasReceivedConnectionOptions() &&
455 ContainsQuicTag(ReceivedConnectionOptions(), tag)) {
456 return true;
457 }
458 } else if (HasSendConnectionOptions() &&
459 ContainsQuicTag(SendConnectionOptions(), tag)) {
460 return true;
461 }
462 return false;
463}
464
465void QuicConfig::SetClientConnectionOptions(
466 const QuicTagVector& client_connection_options) {
467 client_connection_options_.SetSendValues(client_connection_options);
468}
469
470bool QuicConfig::HasClientRequestedIndependentOption(
471 QuicTag tag,
472 Perspective perspective) const {
473 if (perspective == Perspective::IS_SERVER) {
474 return (HasReceivedConnectionOptions() &&
475 ContainsQuicTag(ReceivedConnectionOptions(), tag));
476 }
477
478 return (client_connection_options_.HasSendValues() &&
479 ContainsQuicTag(client_connection_options_.GetSendValues(), tag));
480}
481
482void QuicConfig::SetIdleNetworkTimeout(
483 QuicTime::Delta max_idle_network_timeout,
484 QuicTime::Delta default_idle_network_timeout) {
485 idle_network_timeout_seconds_.set(
486 static_cast<uint32_t>(max_idle_network_timeout.ToSeconds()),
487 static_cast<uint32_t>(default_idle_network_timeout.ToSeconds()));
488}
489
490QuicTime::Delta QuicConfig::IdleNetworkTimeout() const {
491 return QuicTime::Delta::FromSeconds(
492 idle_network_timeout_seconds_.GetUint32());
493}
494
495// TODO(ianswett) Use this for silent close on mobile, or delete.
496QUIC_UNUSED void QuicConfig::SetSilentClose(bool silent_close) {
497 silent_close_.set(silent_close ? 1 : 0, silent_close ? 1 : 0);
498}
499
500bool QuicConfig::SilentClose() const {
501 return silent_close_.GetUint32() > 0;
502}
503
504void QuicConfig::SetMaxIncomingDynamicStreamsToSend(
505 uint32_t max_incoming_dynamic_streams) {
506 max_incoming_dynamic_streams_.SetSendValue(max_incoming_dynamic_streams);
507}
508
509uint32_t QuicConfig::GetMaxIncomingDynamicStreamsToSend() {
510 return max_incoming_dynamic_streams_.GetSendValue();
511}
512
513bool QuicConfig::HasReceivedMaxIncomingDynamicStreams() {
514 return max_incoming_dynamic_streams_.HasReceivedValue();
515}
516
517uint32_t QuicConfig::ReceivedMaxIncomingDynamicStreams() {
518 return max_incoming_dynamic_streams_.GetReceivedValue();
519}
520
521bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
522 return bytes_for_connection_id_.HasSendValue();
523}
524
525void QuicConfig::SetBytesForConnectionIdToSend(uint32_t bytes) {
526 bytes_for_connection_id_.SetSendValue(bytes);
527}
528
529bool QuicConfig::HasReceivedBytesForConnectionId() const {
530 return bytes_for_connection_id_.HasReceivedValue();
531}
532
533uint32_t QuicConfig::ReceivedBytesForConnectionId() const {
534 return bytes_for_connection_id_.GetReceivedValue();
535}
536
537void QuicConfig::SetInitialRoundTripTimeUsToSend(uint32_t rtt) {
538 initial_round_trip_time_us_.SetSendValue(rtt);
539}
540
541bool QuicConfig::HasReceivedInitialRoundTripTimeUs() const {
542 return initial_round_trip_time_us_.HasReceivedValue();
543}
544
545uint32_t QuicConfig::ReceivedInitialRoundTripTimeUs() const {
546 return initial_round_trip_time_us_.GetReceivedValue();
547}
548
549bool QuicConfig::HasInitialRoundTripTimeUsToSend() const {
550 return initial_round_trip_time_us_.HasSendValue();
551}
552
553uint32_t QuicConfig::GetInitialRoundTripTimeUsToSend() const {
554 return initial_round_trip_time_us_.GetSendValue();
555}
556
557void QuicConfig::SetInitialStreamFlowControlWindowToSend(
558 uint32_t window_bytes) {
559 if (window_bytes < kMinimumFlowControlSendWindow) {
560 QUIC_BUG << "Initial stream flow control receive window (" << window_bytes
561 << ") cannot be set lower than default ("
562 << kMinimumFlowControlSendWindow << ").";
563 window_bytes = kMinimumFlowControlSendWindow;
564 }
565 initial_stream_flow_control_window_bytes_.SetSendValue(window_bytes);
566}
567
568uint32_t QuicConfig::GetInitialStreamFlowControlWindowToSend() const {
569 return initial_stream_flow_control_window_bytes_.GetSendValue();
570}
571
572bool QuicConfig::HasReceivedInitialStreamFlowControlWindowBytes() const {
573 return initial_stream_flow_control_window_bytes_.HasReceivedValue();
574}
575
576uint32_t QuicConfig::ReceivedInitialStreamFlowControlWindowBytes() const {
577 return initial_stream_flow_control_window_bytes_.GetReceivedValue();
578}
579
580void QuicConfig::SetInitialSessionFlowControlWindowToSend(
581 uint32_t window_bytes) {
582 if (window_bytes < kMinimumFlowControlSendWindow) {
583 QUIC_BUG << "Initial session flow control receive window (" << window_bytes
584 << ") cannot be set lower than default ("
585 << kMinimumFlowControlSendWindow << ").";
586 window_bytes = kMinimumFlowControlSendWindow;
587 }
588 initial_session_flow_control_window_bytes_.SetSendValue(window_bytes);
589}
590
591uint32_t QuicConfig::GetInitialSessionFlowControlWindowToSend() const {
592 return initial_session_flow_control_window_bytes_.GetSendValue();
593}
594
595bool QuicConfig::HasReceivedInitialSessionFlowControlWindowBytes() const {
596 return initial_session_flow_control_window_bytes_.HasReceivedValue();
597}
598
599uint32_t QuicConfig::ReceivedInitialSessionFlowControlWindowBytes() const {
600 return initial_session_flow_control_window_bytes_.GetReceivedValue();
601}
602
603void QuicConfig::SetDisableConnectionMigration() {
604 connection_migration_disabled_.SetSendValue(1);
605}
606
607bool QuicConfig::DisableConnectionMigration() const {
608 return connection_migration_disabled_.HasReceivedValue();
609}
610
611void QuicConfig::SetAlternateServerAddressToSend(
612 const QuicSocketAddress& alternate_server_address) {
613 alternate_server_address_.SetSendValue(alternate_server_address);
614}
615
616bool QuicConfig::HasReceivedAlternateServerAddress() const {
617 return alternate_server_address_.HasReceivedValue();
618}
619
620const QuicSocketAddress& QuicConfig::ReceivedAlternateServerAddress() const {
621 return alternate_server_address_.GetReceivedValue();
622}
623
624void QuicConfig::SetSupportMaxHeaderListSize() {
625 support_max_header_list_size_.SetSendValue(1);
626}
627
628bool QuicConfig::SupportMaxHeaderListSize() const {
629 return support_max_header_list_size_.HasReceivedValue();
630}
631
632void QuicConfig::SetStatelessResetTokenToSend(
633 QuicUint128 stateless_reset_token) {
634 stateless_reset_token_.SetSendValue(stateless_reset_token);
635}
636
637bool QuicConfig::HasReceivedStatelessResetToken() const {
638 return stateless_reset_token_.HasReceivedValue();
639}
640
641QuicUint128 QuicConfig::ReceivedStatelessResetToken() const {
642 return stateless_reset_token_.GetReceivedValue();
643}
644
645bool QuicConfig::negotiated() const {
646 // TODO(ianswett): Add the negotiated parameters once and iterate over all
647 // of them in negotiated, ToHandshakeMessage, and ProcessPeerHello.
648 return idle_network_timeout_seconds_.negotiated();
649}
650
651void QuicConfig::SetCreateSessionTagIndicators(QuicTagVector tags) {
652 create_session_tag_indicators_ = std::move(tags);
653}
654
655const QuicTagVector& QuicConfig::create_session_tag_indicators() const {
656 return create_session_tag_indicators_;
657}
658
659void QuicConfig::SetDefaults() {
660 idle_network_timeout_seconds_.set(kMaximumIdleTimeoutSecs,
661 kDefaultIdleTimeoutSecs);
662 silent_close_.set(1, 0);
663 SetMaxIncomingDynamicStreamsToSend(kDefaultMaxStreamsPerConnection);
664 max_time_before_crypto_handshake_ =
665 QuicTime::Delta::FromSeconds(kMaxTimeForCryptoHandshakeSecs);
666 max_idle_time_before_crypto_handshake_ =
667 QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs);
668 max_undecryptable_packets_ = kDefaultMaxUndecryptablePackets;
669
670 SetInitialStreamFlowControlWindowToSend(kMinimumFlowControlSendWindow);
671 SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
672 SetSupportMaxHeaderListSize();
673}
674
675void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const {
676 idle_network_timeout_seconds_.ToHandshakeMessage(out);
677 silent_close_.ToHandshakeMessage(out);
678 max_incoming_dynamic_streams_.ToHandshakeMessage(out);
679 bytes_for_connection_id_.ToHandshakeMessage(out);
680 initial_round_trip_time_us_.ToHandshakeMessage(out);
681 initial_stream_flow_control_window_bytes_.ToHandshakeMessage(out);
682 initial_session_flow_control_window_bytes_.ToHandshakeMessage(out);
683 connection_migration_disabled_.ToHandshakeMessage(out);
684 connection_options_.ToHandshakeMessage(out);
685 alternate_server_address_.ToHandshakeMessage(out);
686 support_max_header_list_size_.ToHandshakeMessage(out);
687 stateless_reset_token_.ToHandshakeMessage(out);
688}
689
690QuicErrorCode QuicConfig::ProcessPeerHello(
691 const CryptoHandshakeMessage& peer_hello,
692 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700693 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500694 DCHECK(error_details != nullptr);
695
696 QuicErrorCode error = QUIC_NO_ERROR;
697 if (error == QUIC_NO_ERROR) {
698 error = idle_network_timeout_seconds_.ProcessPeerHello(
699 peer_hello, hello_type, error_details);
700 }
701 if (error == QUIC_NO_ERROR) {
702 error =
703 silent_close_.ProcessPeerHello(peer_hello, hello_type, error_details);
704 }
705 if (error == QUIC_NO_ERROR) {
706 error = max_incoming_dynamic_streams_.ProcessPeerHello(
707 peer_hello, hello_type, error_details);
708 }
709 if (error == QUIC_NO_ERROR) {
710 error = bytes_for_connection_id_.ProcessPeerHello(peer_hello, hello_type,
711 error_details);
712 }
713 if (error == QUIC_NO_ERROR) {
714 error = initial_round_trip_time_us_.ProcessPeerHello(peer_hello, hello_type,
715 error_details);
716 }
717 if (error == QUIC_NO_ERROR) {
718 error = initial_stream_flow_control_window_bytes_.ProcessPeerHello(
719 peer_hello, hello_type, error_details);
720 }
721 if (error == QUIC_NO_ERROR) {
722 error = initial_session_flow_control_window_bytes_.ProcessPeerHello(
723 peer_hello, hello_type, error_details);
724 }
725 if (error == QUIC_NO_ERROR) {
726 error = connection_migration_disabled_.ProcessPeerHello(
727 peer_hello, hello_type, error_details);
728 }
729 if (error == QUIC_NO_ERROR) {
730 error = connection_options_.ProcessPeerHello(peer_hello, hello_type,
731 error_details);
732 }
733 if (error == QUIC_NO_ERROR) {
734 error = alternate_server_address_.ProcessPeerHello(peer_hello, hello_type,
735 error_details);
736 }
737 if (error == QUIC_NO_ERROR) {
738 error = support_max_header_list_size_.ProcessPeerHello(
739 peer_hello, hello_type, error_details);
740 }
741 if (error == QUIC_NO_ERROR) {
742 error = stateless_reset_token_.ProcessPeerHello(peer_hello, hello_type,
743 error_details);
744 }
745 return error;
746}
747
748bool QuicConfig::FillTransportParameters(TransportParameters* params) const {
749 params->initial_max_stream_data =
750 initial_stream_flow_control_window_bytes_.GetSendValue();
751 params->initial_max_data =
752 initial_session_flow_control_window_bytes_.GetSendValue();
753
754 uint32_t idle_timeout = idle_network_timeout_seconds_.GetUint32();
755 if (idle_timeout > std::numeric_limits<uint16_t>::max()) {
756 QUIC_BUG << "idle network timeout set too large";
757 return false;
758 }
759 params->idle_timeout = idle_timeout;
760
761 uint32_t initial_max_streams = max_incoming_dynamic_streams_.GetSendValue();
762 if (initial_max_streams > std::numeric_limits<uint16_t>::max()) {
763 QUIC_BUG << "max incoming streams set too large";
764 return false;
765 }
766 params->initial_max_bidi_streams.present = true;
767 params->initial_max_bidi_streams.value = initial_max_streams;
768
769 if (!params->google_quic_params) {
770 params->google_quic_params = QuicMakeUnique<CryptoHandshakeMessage>();
771 }
772 silent_close_.ToHandshakeMessage(params->google_quic_params.get());
773 initial_round_trip_time_us_.ToHandshakeMessage(
774 params->google_quic_params.get());
775 connection_options_.ToHandshakeMessage(params->google_quic_params.get());
776 return true;
777}
778
779QuicErrorCode QuicConfig::ProcessTransportParameters(
780 const TransportParameters& params,
781 HelloType hello_type,
vasilvvc48c8712019-03-11 13:38:16 -0700782 std::string* error_details) {
QUICHE teama6ef0a62019-03-07 20:34:33 -0500783 QuicErrorCode error = idle_network_timeout_seconds_.ReceiveValue(
784 params.idle_timeout, hello_type, error_details);
785 if (error != QUIC_NO_ERROR) {
dschinazid1967a22019-04-03 16:11:32 -0700786 DCHECK(!error_details->empty());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500787 return error;
788 }
789 const CryptoHandshakeMessage* peer_params = params.google_quic_params.get();
dschinazid1967a22019-04-03 16:11:32 -0700790 if (peer_params != nullptr) {
791 error =
792 silent_close_.ProcessPeerHello(*peer_params, hello_type, error_details);
793 if (error != QUIC_NO_ERROR) {
794 DCHECK(!error_details->empty());
795 return error;
796 }
797 error = initial_round_trip_time_us_.ProcessPeerHello(
798 *peer_params, hello_type, error_details);
799 if (error != QUIC_NO_ERROR) {
800 DCHECK(!error_details->empty());
801 return error;
802 }
803 error = connection_options_.ProcessPeerHello(*peer_params, hello_type,
804 error_details);
805 if (error != QUIC_NO_ERROR) {
806 DCHECK(!error_details->empty());
807 return error;
808 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500809 }
810
811 initial_stream_flow_control_window_bytes_.SetReceivedValue(
812 params.initial_max_stream_data);
813 initial_session_flow_control_window_bytes_.SetReceivedValue(
814 params.initial_max_data);
815 if (params.initial_max_bidi_streams.present) {
816 max_incoming_dynamic_streams_.SetReceivedValue(
817 params.initial_max_bidi_streams.value);
818 } else {
819 // An absent value for initial_max_bidi_streams is treated as a value of 0.
820 max_incoming_dynamic_streams_.SetReceivedValue(0);
821 }
822
823 return QUIC_NO_ERROR;
824}
825
826} // namespace quic