| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_config.h" | 5 #include "net/quic/quic_config.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "net/quic/crypto/crypto_handshake_message.h" | 10 #include "net/quic/crypto/crypto_handshake_message.h" |
| 11 #include "net/quic/crypto/crypto_protocol.h" | 11 #include "net/quic/crypto/crypto_protocol.h" |
| 12 #include "net/quic/quic_sent_packet_manager.h" | 12 #include "net/quic/quic_sent_packet_manager.h" |
| 13 #include "net/quic/quic_utils.h" | 13 #include "net/quic/quic_utils.h" |
| 14 | 14 |
| 15 using std::string; | 15 using std::string; |
| 16 | 16 |
| 17 namespace net { | 17 namespace net { |
| 18 | 18 |
| 19 QuicNegotiableValue::QuicNegotiableValue(QuicTag tag, Presence presence) | 19 // Reads the value corresponding to |name_| from |msg| into |out|. If the |
| 20 // |name_| is absent in |msg| and |presence| is set to OPTIONAL |out| is set |
| 21 // to |default_value|. |
| 22 QuicErrorCode ReadUint32(const CryptoHandshakeMessage& msg, |
| 23 QuicTag tag, |
| 24 QuicConfigPresence presence, |
| 25 uint32 default_value, |
| 26 uint32* out, |
| 27 string* error_details) { |
| 28 DCHECK(error_details != NULL); |
| 29 QuicErrorCode error = msg.GetUint32(tag, out); |
| 30 switch (error) { |
| 31 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: |
| 32 if (presence == PRESENCE_REQUIRED) { |
| 33 *error_details = "Missing " + QuicUtils::TagToString(tag); |
| 34 break; |
| 35 } |
| 36 error = QUIC_NO_ERROR; |
| 37 *out = default_value; |
| 38 break; |
| 39 case QUIC_NO_ERROR: |
| 40 break; |
| 41 default: |
| 42 *error_details = "Bad " + QuicUtils::TagToString(tag); |
| 43 break; |
| 44 } |
| 45 return error; |
| 46 } |
| 47 |
| 48 |
| 49 QuicConfigValue::QuicConfigValue(QuicTag tag, |
| 50 QuicConfigPresence presence) |
| 20 : tag_(tag), | 51 : tag_(tag), |
| 21 presence_(presence), | 52 presence_(presence) { |
| 53 } |
| 54 QuicConfigValue::~QuicConfigValue() {} |
| 55 |
| 56 QuicNegotiableValue::QuicNegotiableValue(QuicTag tag, |
| 57 QuicConfigPresence presence) |
| 58 : QuicConfigValue(tag, presence), |
| 22 negotiated_(false) { | 59 negotiated_(false) { |
| 23 } | 60 } |
| 61 QuicNegotiableValue::~QuicNegotiableValue() {} |
| 24 | 62 |
| 25 QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag, Presence presence) | 63 QuicNegotiableUint32::QuicNegotiableUint32(QuicTag tag, |
| 64 QuicConfigPresence presence) |
| 26 : QuicNegotiableValue(tag, presence), | 65 : QuicNegotiableValue(tag, presence), |
| 27 max_value_(0), | 66 max_value_(0), |
| 28 default_value_(0) { | 67 default_value_(0) { |
| 29 } | 68 } |
| 69 QuicNegotiableUint32::~QuicNegotiableUint32() {} |
| 30 | 70 |
| 31 void QuicNegotiableUint32::set(uint32 max, uint32 default_value) { | 71 void QuicNegotiableUint32::set(uint32 max, uint32 default_value) { |
| 32 DCHECK_LE(default_value, max); | 72 DCHECK_LE(default_value, max); |
| 33 max_value_ = max; | 73 max_value_ = max; |
| 34 default_value_ = default_value; | 74 default_value_ = default_value; |
| 35 } | 75 } |
| 36 | 76 |
| 37 uint32 QuicNegotiableUint32::GetUint32() const { | 77 uint32 QuicNegotiableUint32::GetUint32() const { |
| 38 if (negotiated_) { | 78 if (negotiated_) { |
| 39 return negotiated_value_; | 79 return negotiated_value_; |
| 40 } | 80 } |
| 41 return default_value_; | 81 return default_value_; |
| 42 } | 82 } |
| 43 | 83 |
| 44 void QuicNegotiableUint32::ToHandshakeMessage( | 84 void QuicNegotiableUint32::ToHandshakeMessage( |
| 45 CryptoHandshakeMessage* out) const { | 85 CryptoHandshakeMessage* out) const { |
| 46 if (negotiated_) { | 86 if (negotiated_) { |
| 47 out->SetValue(tag_, negotiated_value_); | 87 out->SetValue(tag_, negotiated_value_); |
| 48 } else { | 88 } else { |
| 49 out->SetValue(tag_, max_value_); | 89 out->SetValue(tag_, max_value_); |
| 50 } | 90 } |
| 51 } | 91 } |
| 52 | 92 |
| 53 QuicErrorCode QuicNegotiableUint32::ReadUint32( | |
| 54 const CryptoHandshakeMessage& msg, | |
| 55 uint32* out, | |
| 56 string* error_details) const { | |
| 57 DCHECK(error_details != NULL); | |
| 58 QuicErrorCode error = msg.GetUint32(tag_, out); | |
| 59 switch (error) { | |
| 60 case QUIC_CRYPTO_MESSAGE_PARAMETER_NOT_FOUND: | |
| 61 if (presence_ == QuicNegotiableValue::PRESENCE_REQUIRED) { | |
| 62 *error_details = "Missing " + QuicUtils::TagToString(tag_); | |
| 63 break; | |
| 64 } | |
| 65 error = QUIC_NO_ERROR; | |
| 66 *out = default_value_; | |
| 67 | |
| 68 case QUIC_NO_ERROR: | |
| 69 break; | |
| 70 default: | |
| 71 *error_details = "Bad " + QuicUtils::TagToString(tag_); | |
| 72 break; | |
| 73 } | |
| 74 return error; | |
| 75 } | |
| 76 | |
| 77 QuicErrorCode QuicNegotiableUint32::ProcessClientHello( | 93 QuicErrorCode QuicNegotiableUint32::ProcessClientHello( |
| 78 const CryptoHandshakeMessage& client_hello, | 94 const CryptoHandshakeMessage& client_hello, |
| 79 string* error_details) { | 95 string* error_details) { |
| 80 DCHECK(!negotiated_); | 96 DCHECK(!negotiated_); |
| 81 DCHECK(error_details != NULL); | 97 DCHECK(error_details != NULL); |
| 82 uint32 value; | 98 uint32 value; |
| 83 QuicErrorCode error = ReadUint32(client_hello, &value, error_details); | 99 QuicErrorCode error = ReadUint32(client_hello, |
| 100 tag_, |
| 101 presence_, |
| 102 default_value_, |
| 103 &value, |
| 104 error_details); |
| 84 if (error != QUIC_NO_ERROR) { | 105 if (error != QUIC_NO_ERROR) { |
| 85 return error; | 106 return error; |
| 86 } | 107 } |
| 87 | |
| 88 negotiated_ = true; | 108 negotiated_ = true; |
| 89 negotiated_value_ = std::min(value, max_value_); | 109 negotiated_value_ = std::min(value, max_value_); |
| 90 | 110 |
| 91 return QUIC_NO_ERROR; | 111 return QUIC_NO_ERROR; |
| 92 } | 112 } |
| 93 | 113 |
| 94 QuicErrorCode QuicNegotiableUint32::ProcessServerHello( | 114 QuicErrorCode QuicNegotiableUint32::ProcessServerHello( |
| 95 const CryptoHandshakeMessage& server_hello, | 115 const CryptoHandshakeMessage& server_hello, |
| 96 string* error_details) { | 116 string* error_details) { |
| 97 DCHECK(!negotiated_); | 117 DCHECK(!negotiated_); |
| 98 DCHECK(error_details != NULL); | 118 DCHECK(error_details != NULL); |
| 99 uint32 value; | 119 uint32 value; |
| 100 QuicErrorCode error = ReadUint32(server_hello, &value, error_details); | 120 QuicErrorCode error = ReadUint32(server_hello, |
| 121 tag_, |
| 122 presence_, |
| 123 max_value_, |
| 124 &value, |
| 125 error_details); |
| 101 if (error != QUIC_NO_ERROR) { | 126 if (error != QUIC_NO_ERROR) { |
| 102 return error; | 127 return error; |
| 103 } | 128 } |
| 104 | 129 |
| 105 if (value > max_value_) { | 130 if (value > max_value_) { |
| 106 *error_details = "Invalid value received for " + | 131 *error_details = "Invalid value received for " + |
| 107 QuicUtils::TagToString(tag_); | 132 QuicUtils::TagToString(tag_); |
| 108 return QUIC_INVALID_NEGOTIATED_VALUE; | 133 return QUIC_INVALID_NEGOTIATED_VALUE; |
| 109 } | 134 } |
| 110 | 135 |
| 111 negotiated_ = true; | 136 negotiated_ = true; |
| 112 negotiated_value_ = value; | 137 negotiated_value_ = value; |
| 113 return QUIC_NO_ERROR; | 138 return QUIC_NO_ERROR; |
| 114 } | 139 } |
| 115 | 140 |
| 116 QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, Presence presence) | 141 QuicNegotiableTag::QuicNegotiableTag(QuicTag tag, QuicConfigPresence presence) |
| 117 : QuicNegotiableValue(tag, presence), | 142 : QuicNegotiableValue(tag, presence), |
| 118 negotiated_tag_(0), | 143 negotiated_tag_(0), |
| 119 default_value_(0) { | 144 default_value_(0) { |
| 120 } | 145 } |
| 121 | 146 |
| 122 QuicNegotiableTag::~QuicNegotiableTag() {} | 147 QuicNegotiableTag::~QuicNegotiableTag() {} |
| 123 | 148 |
| 124 void QuicNegotiableTag::set(const QuicTagVector& possible, | 149 void QuicNegotiableTag::set(const QuicTagVector& possible, |
| 125 QuicTag default_value) { | 150 QuicTag default_value) { |
| 126 DCHECK(std::find(possible.begin(), possible.end(), default_value) != | 151 DCHECK(std::find(possible.begin(), possible.end(), default_value) != |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 *received_tags) == possible_values_.end()) { | 244 *received_tags) == possible_values_.end()) { |
| 220 *error_details = "Invalid " + QuicUtils::TagToString(tag_); | 245 *error_details = "Invalid " + QuicUtils::TagToString(tag_); |
| 221 return QUIC_INVALID_NEGOTIATED_VALUE; | 246 return QUIC_INVALID_NEGOTIATED_VALUE; |
| 222 } | 247 } |
| 223 | 248 |
| 224 negotiated_ = true; | 249 negotiated_ = true; |
| 225 negotiated_tag_ = *received_tags; | 250 negotiated_tag_ = *received_tags; |
| 226 return QUIC_NO_ERROR; | 251 return QUIC_NO_ERROR; |
| 227 } | 252 } |
| 228 | 253 |
| 229 QuicConfig::QuicConfig() : | 254 QuicFixedUint32::QuicFixedUint32(QuicTag tag, |
| 230 congestion_control_(kCGST, QuicNegotiableValue::PRESENCE_REQUIRED), | 255 QuicConfigPresence presence, |
| 231 idle_connection_state_lifetime_seconds_( | 256 uint32 default_value) |
| 232 kICSL, QuicNegotiableValue::PRESENCE_REQUIRED), | 257 : QuicConfigValue(tag, presence), |
| 233 keepalive_timeout_seconds_(kKATO, QuicNegotiableValue::PRESENCE_OPTIONAL), | 258 value_(default_value) { |
| 234 max_streams_per_connection_(kMSPC, QuicNegotiableValue::PRESENCE_REQUIRED), | 259 } |
| 235 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()), | 260 QuicFixedUint32::~QuicFixedUint32() {} |
| 236 server_initial_congestion_window_( | 261 |
| 237 kSWND, QuicNegotiableValue::PRESENCE_OPTIONAL), | 262 uint32 QuicFixedUint32::GetUint32() const { |
| 238 initial_round_trip_time_us_(kIRTT, QuicNegotiableValue::PRESENCE_OPTIONAL) { | 263 return value_; |
| 264 } |
| 265 |
| 266 void QuicFixedUint32::ToHandshakeMessage( |
| 267 CryptoHandshakeMessage* out) const { |
| 268 out->SetValue(tag_, value_); |
| 269 } |
| 270 |
| 271 QuicErrorCode QuicFixedUint32::ProcessClientHello( |
| 272 const CryptoHandshakeMessage& client_hello, |
| 273 string* error_details) { |
| 274 DCHECK(error_details != NULL); |
| 275 QuicErrorCode error = |
| 276 ReadUint32(client_hello, tag_, presence_, value_, &value_, error_details); |
| 277 if (error != QUIC_NO_ERROR) { |
| 278 return error; |
| 279 } |
| 280 return QUIC_NO_ERROR; |
| 281 } |
| 282 |
| 283 QuicErrorCode QuicFixedUint32::ProcessServerHello( |
| 284 const CryptoHandshakeMessage& server_hello, |
| 285 string* error_details) { |
| 286 DCHECK(error_details != NULL); |
| 287 QuicErrorCode error = |
| 288 ReadUint32(server_hello, tag_, presence_, value_, &value_, error_details); |
| 289 if (error != QUIC_NO_ERROR) { |
| 290 return error; |
| 291 } |
| 292 return QUIC_NO_ERROR; |
| 293 } |
| 294 |
| 295 QuicConfig::QuicConfig() |
| 296 : congestion_control_(kCGST, PRESENCE_REQUIRED), |
| 297 idle_connection_state_lifetime_seconds_(kICSL, PRESENCE_REQUIRED), |
| 298 keepalive_timeout_seconds_(kKATO, PRESENCE_OPTIONAL), |
| 299 max_streams_per_connection_(kMSPC, PRESENCE_REQUIRED), |
| 300 max_time_before_crypto_handshake_(QuicTime::Delta::Zero()), |
| 301 server_initial_congestion_window_(kSWND, PRESENCE_OPTIONAL), |
| 302 initial_round_trip_time_us_(kIRTT, PRESENCE_OPTIONAL), |
| 303 // TODO(rjshade): Make this PRESENCE_REQUIRED when retiring |
| 304 // QUIC_VERSION_17. |
| 305 peer_initial_flow_control_window_bytes_(kIFCW, PRESENCE_OPTIONAL, 0) { |
| 239 // All optional non-zero parameters should be initialized here. | 306 // All optional non-zero parameters should be initialized here. |
| 240 server_initial_congestion_window_.set(kMaxInitialWindow, | 307 server_initial_congestion_window_.set(kMaxInitialWindow, |
| 241 kDefaultInitialWindow); | 308 kDefaultInitialWindow); |
| 242 } | 309 } |
| 243 | 310 |
| 244 QuicConfig::~QuicConfig() {} | 311 QuicConfig::~QuicConfig() {} |
| 245 | 312 |
| 246 void QuicConfig::set_congestion_control( | 313 void QuicConfig::set_congestion_control( |
| 247 const QuicTagVector& congestion_control, | 314 const QuicTagVector& congestion_control, |
| 248 QuicTag default_congestion_control) { | 315 QuicTag default_congestion_control) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 | 368 |
| 302 void QuicConfig::set_initial_round_trip_time_us(size_t max_rtt, | 369 void QuicConfig::set_initial_round_trip_time_us(size_t max_rtt, |
| 303 size_t default_rtt) { | 370 size_t default_rtt) { |
| 304 initial_round_trip_time_us_.set(max_rtt, default_rtt); | 371 initial_round_trip_time_us_.set(max_rtt, default_rtt); |
| 305 } | 372 } |
| 306 | 373 |
| 307 uint32 QuicConfig::initial_round_trip_time_us() const { | 374 uint32 QuicConfig::initial_round_trip_time_us() const { |
| 308 return initial_round_trip_time_us_.GetUint32(); | 375 return initial_round_trip_time_us_.GetUint32(); |
| 309 } | 376 } |
| 310 | 377 |
| 378 void QuicConfig::set_peer_initial_flow_control_window_bytes(uint32 window) { |
| 379 peer_initial_flow_control_window_bytes_.set_value(window); |
| 380 } |
| 381 |
| 382 uint32 QuicConfig::peer_initial_flow_control_window_bytes() const { |
| 383 return peer_initial_flow_control_window_bytes_.GetUint32(); |
| 384 } |
| 385 |
| 311 bool QuicConfig::negotiated() { | 386 bool QuicConfig::negotiated() { |
| 312 // TODO(ianswett): Add the negotiated parameters once and iterate over all | 387 // TODO(ianswett): Add the negotiated parameters once and iterate over all |
| 313 // of them in negotiated, ToHandshakeMessage, ProcessClientHello, and | 388 // of them in negotiated, ToHandshakeMessage, ProcessClientHello, and |
| 314 // ProcessServerHello. | 389 // ProcessServerHello. |
| 315 return congestion_control_.negotiated() && | 390 return congestion_control_.negotiated() && |
| 316 idle_connection_state_lifetime_seconds_.negotiated() && | 391 idle_connection_state_lifetime_seconds_.negotiated() && |
| 317 keepalive_timeout_seconds_.negotiated() && | 392 keepalive_timeout_seconds_.negotiated() && |
| 318 max_streams_per_connection_.negotiated() && | 393 max_streams_per_connection_.negotiated() && |
| 319 server_initial_congestion_window_.negotiated() && | 394 server_initial_congestion_window_.negotiated() && |
| 320 initial_round_trip_time_us_.negotiated(); | 395 initial_round_trip_time_us_.negotiated(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 349 } | 424 } |
| 350 | 425 |
| 351 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const { | 426 void QuicConfig::ToHandshakeMessage(CryptoHandshakeMessage* out) const { |
| 352 congestion_control_.ToHandshakeMessage(out); | 427 congestion_control_.ToHandshakeMessage(out); |
| 353 idle_connection_state_lifetime_seconds_.ToHandshakeMessage(out); | 428 idle_connection_state_lifetime_seconds_.ToHandshakeMessage(out); |
| 354 keepalive_timeout_seconds_.ToHandshakeMessage(out); | 429 keepalive_timeout_seconds_.ToHandshakeMessage(out); |
| 355 max_streams_per_connection_.ToHandshakeMessage(out); | 430 max_streams_per_connection_.ToHandshakeMessage(out); |
| 356 server_initial_congestion_window_.ToHandshakeMessage(out); | 431 server_initial_congestion_window_.ToHandshakeMessage(out); |
| 357 // TODO(ianswett): Don't transmit parameters which are optional and not set. | 432 // TODO(ianswett): Don't transmit parameters which are optional and not set. |
| 358 initial_round_trip_time_us_.ToHandshakeMessage(out); | 433 initial_round_trip_time_us_.ToHandshakeMessage(out); |
| 434 peer_initial_flow_control_window_bytes_.ToHandshakeMessage(out); |
| 359 } | 435 } |
| 360 | 436 |
| 361 QuicErrorCode QuicConfig::ProcessClientHello( | 437 QuicErrorCode QuicConfig::ProcessClientHello( |
| 362 const CryptoHandshakeMessage& client_hello, | 438 const CryptoHandshakeMessage& client_hello, |
| 363 string* error_details) { | 439 string* error_details) { |
| 364 DCHECK(error_details != NULL); | 440 DCHECK(error_details != NULL); |
| 365 | 441 |
| 366 QuicErrorCode error = QUIC_NO_ERROR; | 442 QuicErrorCode error = QUIC_NO_ERROR; |
| 367 if (error == QUIC_NO_ERROR) { | 443 if (error == QUIC_NO_ERROR) { |
| 368 error = congestion_control_.ProcessClientHello(client_hello, error_details); | 444 error = congestion_control_.ProcessClientHello(client_hello, error_details); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 380 client_hello, error_details); | 456 client_hello, error_details); |
| 381 } | 457 } |
| 382 if (error == QUIC_NO_ERROR) { | 458 if (error == QUIC_NO_ERROR) { |
| 383 error = server_initial_congestion_window_.ProcessClientHello( | 459 error = server_initial_congestion_window_.ProcessClientHello( |
| 384 client_hello, error_details); | 460 client_hello, error_details); |
| 385 } | 461 } |
| 386 if (error == QUIC_NO_ERROR) { | 462 if (error == QUIC_NO_ERROR) { |
| 387 error = initial_round_trip_time_us_.ProcessClientHello( | 463 error = initial_round_trip_time_us_.ProcessClientHello( |
| 388 client_hello, error_details); | 464 client_hello, error_details); |
| 389 } | 465 } |
| 466 if (error == QUIC_NO_ERROR) { |
| 467 error = peer_initial_flow_control_window_bytes_.ProcessClientHello( |
| 468 client_hello, error_details); |
| 469 } |
| 390 return error; | 470 return error; |
| 391 } | 471 } |
| 392 | 472 |
| 393 QuicErrorCode QuicConfig::ProcessServerHello( | 473 QuicErrorCode QuicConfig::ProcessServerHello( |
| 394 const CryptoHandshakeMessage& server_hello, | 474 const CryptoHandshakeMessage& server_hello, |
| 395 string* error_details) { | 475 string* error_details) { |
| 396 DCHECK(error_details != NULL); | 476 DCHECK(error_details != NULL); |
| 397 | 477 |
| 398 QuicErrorCode error = QUIC_NO_ERROR; | 478 QuicErrorCode error = QUIC_NO_ERROR; |
| 399 if (error == QUIC_NO_ERROR) { | 479 if (error == QUIC_NO_ERROR) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 412 server_hello, error_details); | 492 server_hello, error_details); |
| 413 } | 493 } |
| 414 if (error == QUIC_NO_ERROR) { | 494 if (error == QUIC_NO_ERROR) { |
| 415 error = server_initial_congestion_window_.ProcessServerHello( | 495 error = server_initial_congestion_window_.ProcessServerHello( |
| 416 server_hello, error_details); | 496 server_hello, error_details); |
| 417 } | 497 } |
| 418 if (error == QUIC_NO_ERROR) { | 498 if (error == QUIC_NO_ERROR) { |
| 419 error = initial_round_trip_time_us_.ProcessServerHello( | 499 error = initial_round_trip_time_us_.ProcessServerHello( |
| 420 server_hello, error_details); | 500 server_hello, error_details); |
| 421 } | 501 } |
| 502 if (error == QUIC_NO_ERROR) { |
| 503 error = peer_initial_flow_control_window_bytes_.ProcessServerHello( |
| 504 server_hello, error_details); |
| 505 } |
| 422 return error; | 506 return error; |
| 423 } | 507 } |
| 424 | 508 |
| 425 } // namespace net | 509 } // namespace net |
| OLD | NEW |