| OLD | NEW |
| (Empty) |
| 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 #ifndef NET_QUIC_QUIC_CONFIG_H_ | |
| 6 #define NET_QUIC_QUIC_CONFIG_H_ | |
| 7 | |
| 8 #include <stddef.h> | |
| 9 #include <stdint.h> | |
| 10 | |
| 11 #include <string> | |
| 12 | |
| 13 #include "net/quic/quic_protocol.h" | |
| 14 #include "net/quic/quic_time.h" | |
| 15 | |
| 16 namespace net { | |
| 17 | |
| 18 namespace test { | |
| 19 class QuicConfigPeer; | |
| 20 } // namespace test | |
| 21 | |
| 22 class CryptoHandshakeMessage; | |
| 23 | |
| 24 // Describes whether or not a given QuicTag is required or optional in the | |
| 25 // handshake message. | |
| 26 enum QuicConfigPresence { | |
| 27 // This negotiable value can be absent from the handshake message. Default | |
| 28 // value is selected as the negotiated value in such a case. | |
| 29 PRESENCE_OPTIONAL, | |
| 30 // This negotiable value is required in the handshake message otherwise the | |
| 31 // Process*Hello function returns an error. | |
| 32 PRESENCE_REQUIRED, | |
| 33 }; | |
| 34 | |
| 35 // Whether the CryptoHandshakeMessage is from the client or server. | |
| 36 enum HelloType { | |
| 37 CLIENT, | |
| 38 SERVER, | |
| 39 }; | |
| 40 | |
| 41 // An abstract base class that stores a value that can be sent in CHLO/SHLO | |
| 42 // message. These values can be OPTIONAL or REQUIRED, depending on |presence_|. | |
| 43 class NET_EXPORT_PRIVATE QuicConfigValue { | |
| 44 public: | |
| 45 QuicConfigValue(QuicTag tag, QuicConfigPresence presence); | |
| 46 virtual ~QuicConfigValue(); | |
| 47 | |
| 48 // Serialises tag name and value(s) to |out|. | |
| 49 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0; | |
| 50 | |
| 51 // Selects a mutually acceptable value from those offered in |peer_hello| | |
| 52 // and those defined in the subclass. | |
| 53 virtual QuicErrorCode ProcessPeerHello( | |
| 54 const CryptoHandshakeMessage& peer_hello, | |
| 55 HelloType hello_type, | |
| 56 std::string* error_details) = 0; | |
| 57 | |
| 58 protected: | |
| 59 const QuicTag tag_; | |
| 60 const QuicConfigPresence presence_; | |
| 61 }; | |
| 62 | |
| 63 class NET_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue { | |
| 64 public: | |
| 65 QuicNegotiableValue(QuicTag tag, QuicConfigPresence presence); | |
| 66 ~QuicNegotiableValue() override; | |
| 67 | |
| 68 bool negotiated() const { return negotiated_; } | |
| 69 | |
| 70 protected: | |
| 71 void set_negotiated(bool negotiated) { negotiated_ = negotiated; } | |
| 72 | |
| 73 private: | |
| 74 bool negotiated_; | |
| 75 }; | |
| 76 | |
| 77 class NET_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue { | |
| 78 // TODO(fayang): some negotiated values use uint32 as bool (e.g., silent | |
| 79 // close). Consider adding a QuicNegotiableBool type. | |
| 80 public: | |
| 81 // Default and max values default to 0. | |
| 82 QuicNegotiableUint32(QuicTag name, QuicConfigPresence presence); | |
| 83 ~QuicNegotiableUint32() override; | |
| 84 | |
| 85 // Sets the maximum possible value that can be achieved after negotiation and | |
| 86 // also the default values to be assumed if PRESENCE_OPTIONAL and the *HLO msg | |
| 87 // doesn't contain a value corresponding to |name_|. |max| is serialised via | |
| 88 // ToHandshakeMessage call if |negotiated_| is false. | |
| 89 void set(uint32_t max, uint32_t default_value); | |
| 90 | |
| 91 // Returns the value negotiated if |negotiated_| is true, otherwise returns | |
| 92 // default_value_ (used to set default values before negotiation finishes). | |
| 93 uint32_t GetUint32() const; | |
| 94 | |
| 95 // Serialises |name_| and value to |out|. If |negotiated_| is true then | |
| 96 // |negotiated_value_| is serialised, otherwise |max_value_| is serialised. | |
| 97 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
| 98 | |
| 99 // Sets |negotiated_value_| to the minimum of |max_value_| and the | |
| 100 // corresponding value from |peer_hello|. If the corresponding value is | |
| 101 // missing and PRESENCE_OPTIONAL then |negotiated_value_| is set to | |
| 102 // |default_value_|. | |
| 103 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
| 104 HelloType hello_type, | |
| 105 std::string* error_details) override; | |
| 106 | |
| 107 private: | |
| 108 uint32_t max_value_; | |
| 109 uint32_t default_value_; | |
| 110 uint32_t negotiated_value_; | |
| 111 }; | |
| 112 | |
| 113 class NET_EXPORT_PRIVATE QuicNegotiableTag : public QuicNegotiableValue { | |
| 114 public: | |
| 115 QuicNegotiableTag(QuicTag name, QuicConfigPresence presence); | |
| 116 ~QuicNegotiableTag() override; | |
| 117 | |
| 118 // Sets the possible values that |negotiated_tag_| can take after negotiation | |
| 119 // and the default value that |negotiated_tag_| takes if OPTIONAL and *HLO | |
| 120 // msg doesn't contain tag |name_|. | |
| 121 void set(const QuicTagVector& possible_values, QuicTag default_value); | |
| 122 | |
| 123 // Serialises |name_| and vector (either possible or negotiated) to |out|. If | |
| 124 // |negotiated_| is true then |negotiated_tag_| is serialised, otherwise | |
| 125 // |possible_values_| is serialised. | |
| 126 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
| 127 | |
| 128 // Selects the tag common to both tags in |client_hello| for |name_| and | |
| 129 // |possible_values_| with preference to tag in |possible_values_|. The | |
| 130 // selected tag is set as |negotiated_tag_|. | |
| 131 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
| 132 HelloType hello_type, | |
| 133 std::string* error_details) override; | |
| 134 | |
| 135 private: | |
| 136 // Reads the vector corresponding to |name_| from |msg| into |out|. If the | |
| 137 // |name_| is absent in |msg| and |presence_| is set to OPTIONAL |out| is set | |
| 138 // to |possible_values_|. | |
| 139 QuicErrorCode ReadVector(const CryptoHandshakeMessage& msg, | |
| 140 const QuicTag** out, | |
| 141 size_t* out_length, | |
| 142 std::string* error_details) const; | |
| 143 | |
| 144 QuicTag negotiated_tag_; | |
| 145 QuicTagVector possible_values_; | |
| 146 QuicTag default_value_; | |
| 147 }; | |
| 148 | |
| 149 // Stores uint32_t from CHLO or SHLO messages that are not negotiated. | |
| 150 class NET_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue { | |
| 151 public: | |
| 152 QuicFixedUint32(QuicTag name, QuicConfigPresence presence); | |
| 153 ~QuicFixedUint32() override; | |
| 154 | |
| 155 bool HasSendValue() const; | |
| 156 | |
| 157 uint32_t GetSendValue() const; | |
| 158 | |
| 159 void SetSendValue(uint32_t value); | |
| 160 | |
| 161 bool HasReceivedValue() const; | |
| 162 | |
| 163 uint32_t GetReceivedValue() const; | |
| 164 | |
| 165 void SetReceivedValue(uint32_t value); | |
| 166 | |
| 167 // If has_send_value is true, serialises |tag_| and |send_value_| to |out|. | |
| 168 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
| 169 | |
| 170 // Sets |value_| to the corresponding value from |peer_hello_| if it exists. | |
| 171 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
| 172 HelloType hello_type, | |
| 173 std::string* error_details) override; | |
| 174 | |
| 175 private: | |
| 176 uint32_t send_value_; | |
| 177 bool has_send_value_; | |
| 178 uint32_t receive_value_; | |
| 179 bool has_receive_value_; | |
| 180 }; | |
| 181 | |
| 182 // Stores tag from CHLO or SHLO messages that are not negotiated. | |
| 183 class NET_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue { | |
| 184 public: | |
| 185 QuicFixedTagVector(QuicTag name, QuicConfigPresence presence); | |
| 186 QuicFixedTagVector(const QuicFixedTagVector& other); | |
| 187 ~QuicFixedTagVector() override; | |
| 188 | |
| 189 bool HasSendValues() const; | |
| 190 | |
| 191 QuicTagVector GetSendValues() const; | |
| 192 | |
| 193 void SetSendValues(const QuicTagVector& values); | |
| 194 | |
| 195 bool HasReceivedValues() const; | |
| 196 | |
| 197 QuicTagVector GetReceivedValues() const; | |
| 198 | |
| 199 void SetReceivedValues(const QuicTagVector& values); | |
| 200 | |
| 201 // If has_send_value is true, serialises |tag_vector_| and |send_value_| to | |
| 202 // |out|. | |
| 203 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
| 204 | |
| 205 // Sets |receive_values_| to the corresponding value from |client_hello_| if | |
| 206 // it exists. | |
| 207 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
| 208 HelloType hello_type, | |
| 209 std::string* error_details) override; | |
| 210 | |
| 211 private: | |
| 212 QuicTagVector send_values_; | |
| 213 bool has_send_values_; | |
| 214 QuicTagVector receive_values_; | |
| 215 bool has_receive_values_; | |
| 216 }; | |
| 217 | |
| 218 // Stores IPEndPoint from CHLO or SHLO messages that are not negotiated. | |
| 219 class NET_EXPORT_PRIVATE QuicFixedIPEndPoint : public QuicConfigValue { | |
| 220 public: | |
| 221 QuicFixedIPEndPoint(QuicTag tag, QuicConfigPresence presence); | |
| 222 ~QuicFixedIPEndPoint() override; | |
| 223 | |
| 224 bool HasSendValue() const; | |
| 225 | |
| 226 const IPEndPoint& GetSendValue() const; | |
| 227 | |
| 228 void SetSendValue(const IPEndPoint& value); | |
| 229 | |
| 230 bool HasReceivedValue() const; | |
| 231 | |
| 232 const IPEndPoint& GetReceivedValue() const; | |
| 233 | |
| 234 void SetReceivedValue(const IPEndPoint& value); | |
| 235 | |
| 236 void ToHandshakeMessage(CryptoHandshakeMessage* out) const override; | |
| 237 | |
| 238 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
| 239 HelloType hello_type, | |
| 240 std::string* error_details) override; | |
| 241 | |
| 242 private: | |
| 243 IPEndPoint send_value_; | |
| 244 bool has_send_value_; | |
| 245 IPEndPoint receive_value_; | |
| 246 bool has_receive_value_; | |
| 247 }; | |
| 248 | |
| 249 // QuicConfig contains non-crypto configuration options that are negotiated in | |
| 250 // the crypto handshake. | |
| 251 class NET_EXPORT_PRIVATE QuicConfig { | |
| 252 public: | |
| 253 QuicConfig(); | |
| 254 QuicConfig(const QuicConfig& other); | |
| 255 ~QuicConfig(); | |
| 256 | |
| 257 void SetConnectionOptionsToSend(const QuicTagVector& connection_options); | |
| 258 | |
| 259 bool HasReceivedConnectionOptions() const; | |
| 260 | |
| 261 // Sets initial received connection options. All received connection options | |
| 262 // will be initialized with these fields. Initial received options may only be | |
| 263 // set once per config, prior to the setting of any other options. If options | |
| 264 // have already been set (either by previous calls or via handshake), this | |
| 265 // function does nothing and returns false. | |
| 266 bool SetInitialReceivedConnectionOptions(const QuicTagVector& tags); | |
| 267 | |
| 268 QuicTagVector ReceivedConnectionOptions() const; | |
| 269 | |
| 270 bool HasSendConnectionOptions() const; | |
| 271 | |
| 272 QuicTagVector SendConnectionOptions() const; | |
| 273 | |
| 274 // Returns true if the client is sending or the server has received a | |
| 275 // connection option. | |
| 276 bool HasClientSentConnectionOption(QuicTag tag, | |
| 277 Perspective perspective) const; | |
| 278 | |
| 279 void SetIdleConnectionStateLifetime( | |
| 280 QuicTime::Delta max_idle_connection_state_lifetime, | |
| 281 QuicTime::Delta default_idle_conection_state_lifetime); | |
| 282 | |
| 283 QuicTime::Delta IdleConnectionStateLifetime() const; | |
| 284 | |
| 285 void SetSilentClose(bool silent_close); | |
| 286 | |
| 287 bool SilentClose() const; | |
| 288 | |
| 289 void SetMaxStreamsPerConnection(size_t max_streams, size_t default_streams); | |
| 290 | |
| 291 uint32_t MaxStreamsPerConnection() const; | |
| 292 | |
| 293 void SetMaxIncomingDynamicStreamsToSend( | |
| 294 uint32_t max_incoming_dynamic_streams); | |
| 295 | |
| 296 uint32_t GetMaxIncomingDynamicStreamsToSend(); | |
| 297 | |
| 298 bool HasReceivedMaxIncomingDynamicStreams(); | |
| 299 | |
| 300 uint32_t ReceivedMaxIncomingDynamicStreams(); | |
| 301 | |
| 302 void set_max_time_before_crypto_handshake( | |
| 303 QuicTime::Delta max_time_before_crypto_handshake) { | |
| 304 max_time_before_crypto_handshake_ = max_time_before_crypto_handshake; | |
| 305 } | |
| 306 | |
| 307 QuicTime::Delta max_time_before_crypto_handshake() const { | |
| 308 return max_time_before_crypto_handshake_; | |
| 309 } | |
| 310 | |
| 311 void set_max_idle_time_before_crypto_handshake( | |
| 312 QuicTime::Delta max_idle_time_before_crypto_handshake) { | |
| 313 max_idle_time_before_crypto_handshake_ = | |
| 314 max_idle_time_before_crypto_handshake; | |
| 315 } | |
| 316 | |
| 317 QuicTime::Delta max_idle_time_before_crypto_handshake() const { | |
| 318 return max_idle_time_before_crypto_handshake_; | |
| 319 } | |
| 320 | |
| 321 void set_max_undecryptable_packets(size_t max_undecryptable_packets) { | |
| 322 max_undecryptable_packets_ = max_undecryptable_packets; | |
| 323 } | |
| 324 | |
| 325 size_t max_undecryptable_packets() const { | |
| 326 return max_undecryptable_packets_; | |
| 327 } | |
| 328 | |
| 329 bool HasSetBytesForConnectionIdToSend() const; | |
| 330 | |
| 331 // Sets the peer's connection id length, in bytes. | |
| 332 void SetBytesForConnectionIdToSend(uint32_t bytes); | |
| 333 | |
| 334 bool HasReceivedBytesForConnectionId() const; | |
| 335 | |
| 336 uint32_t ReceivedBytesForConnectionId() const; | |
| 337 | |
| 338 // Sets an estimated initial round trip time in us. | |
| 339 void SetInitialRoundTripTimeUsToSend(uint32_t rtt_us); | |
| 340 | |
| 341 bool HasReceivedInitialRoundTripTimeUs() const; | |
| 342 | |
| 343 uint32_t ReceivedInitialRoundTripTimeUs() const; | |
| 344 | |
| 345 bool HasInitialRoundTripTimeUsToSend() const; | |
| 346 | |
| 347 uint32_t GetInitialRoundTripTimeUsToSend() const; | |
| 348 | |
| 349 // Sets an initial stream flow control window size to transmit to the peer. | |
| 350 void SetInitialStreamFlowControlWindowToSend(uint32_t window_bytes); | |
| 351 | |
| 352 uint32_t GetInitialStreamFlowControlWindowToSend() const; | |
| 353 | |
| 354 bool HasReceivedInitialStreamFlowControlWindowBytes() const; | |
| 355 | |
| 356 uint32_t ReceivedInitialStreamFlowControlWindowBytes() const; | |
| 357 | |
| 358 // Sets an initial session flow control window size to transmit to the peer. | |
| 359 void SetInitialSessionFlowControlWindowToSend(uint32_t window_bytes); | |
| 360 | |
| 361 uint32_t GetInitialSessionFlowControlWindowToSend() const; | |
| 362 | |
| 363 bool HasReceivedInitialSessionFlowControlWindowBytes() const; | |
| 364 | |
| 365 uint32_t ReceivedInitialSessionFlowControlWindowBytes() const; | |
| 366 | |
| 367 // Sets socket receive buffer to transmit to the peer. | |
| 368 void SetSocketReceiveBufferToSend(uint32_t window_bytes); | |
| 369 | |
| 370 bool HasReceivedSocketReceiveBuffer() const; | |
| 371 | |
| 372 uint32_t ReceivedSocketReceiveBuffer() const; | |
| 373 | |
| 374 void SetMultipathEnabled(bool multipath_enabled); | |
| 375 | |
| 376 bool MultipathEnabled() const; | |
| 377 | |
| 378 void SetDisableConnectionMigration(); | |
| 379 | |
| 380 bool DisableConnectionMigration() const; | |
| 381 | |
| 382 void SetAlternateServerAddressToSend( | |
| 383 const IPEndPoint& alternate_server_address); | |
| 384 | |
| 385 bool HasReceivedAlternateServerAddress() const; | |
| 386 | |
| 387 const IPEndPoint& ReceivedAlternateServerAddress() const; | |
| 388 | |
| 389 void SetForceHolBlocking(); | |
| 390 | |
| 391 bool ForceHolBlocking(Perspective perspective) const; | |
| 392 | |
| 393 bool negotiated() const; | |
| 394 | |
| 395 // ToHandshakeMessage serialises the settings in this object as a series of | |
| 396 // tags /value pairs and adds them to |out|. | |
| 397 void ToHandshakeMessage(CryptoHandshakeMessage* out) const; | |
| 398 | |
| 399 // Calls ProcessPeerHello on each negotiable parameter. On failure returns | |
| 400 // the corresponding QuicErrorCode and sets detailed error in |error_details|. | |
| 401 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, | |
| 402 HelloType hello_type, | |
| 403 std::string* error_details); | |
| 404 | |
| 405 private: | |
| 406 friend class test::QuicConfigPeer; | |
| 407 | |
| 408 // SetDefaults sets the members to sensible, default values. | |
| 409 void SetDefaults(); | |
| 410 | |
| 411 // Configurations options that are not negotiated. | |
| 412 // Maximum time the session can be alive before crypto handshake is finished. | |
| 413 QuicTime::Delta max_time_before_crypto_handshake_; | |
| 414 // Maximum idle time before the crypto handshake has completed. | |
| 415 QuicTime::Delta max_idle_time_before_crypto_handshake_; | |
| 416 // Maximum number of undecryptable packets stored before CHLO/SHLO. | |
| 417 size_t max_undecryptable_packets_; | |
| 418 | |
| 419 // Connection options. | |
| 420 QuicFixedTagVector connection_options_; | |
| 421 // Idle connection state lifetime | |
| 422 QuicNegotiableUint32 idle_connection_state_lifetime_seconds_; | |
| 423 // Whether to use silent close. Defaults to 0 (false) and is otherwise true. | |
| 424 QuicNegotiableUint32 silent_close_; | |
| 425 // Maximum number of streams that the connection can support. | |
| 426 // TODO(rjshade): Remove when removing QUIC_VERSION_34 | |
| 427 QuicNegotiableUint32 max_streams_per_connection_; | |
| 428 // Maximum number of incoming dynamic streams that the connection can support. | |
| 429 QuicFixedUint32 max_incoming_dynamic_streams_; | |
| 430 // The number of bytes required for the connection ID. | |
| 431 QuicFixedUint32 bytes_for_connection_id_; | |
| 432 // Initial round trip time estimate in microseconds. | |
| 433 QuicFixedUint32 initial_round_trip_time_us_; | |
| 434 | |
| 435 // Initial stream flow control receive window in bytes. | |
| 436 QuicFixedUint32 initial_stream_flow_control_window_bytes_; | |
| 437 // Initial session flow control receive window in bytes. | |
| 438 QuicFixedUint32 initial_session_flow_control_window_bytes_; | |
| 439 | |
| 440 // Socket receive buffer in bytes. | |
| 441 // TODO(ianswett): Deprecate once QUIC_VERSION_34 is deprecated. | |
| 442 QuicFixedUint32 socket_receive_buffer_; | |
| 443 | |
| 444 // Whether to support multipath for this connection. | |
| 445 QuicNegotiableUint32 multipath_enabled_; | |
| 446 | |
| 447 // Whether tell peer not to attempt connection migration. | |
| 448 QuicFixedUint32 connection_migration_disabled_; | |
| 449 | |
| 450 // An alternate server address the client could connect to. | |
| 451 QuicFixedIPEndPoint alternate_server_address_; | |
| 452 | |
| 453 // Force HOL blocking for measurement purposes. | |
| 454 QuicFixedUint32 force_hol_blocking_; | |
| 455 }; | |
| 456 | |
| 457 } // namespace net | |
| 458 | |
| 459 #endif // NET_QUIC_QUIC_CONFIG_H_ | |
| OLD | NEW |