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 <string> 9 10 #include "base/basictypes.h" 11 #include "net/quic/quic_protocol.h" 12 #include "net/quic/quic_time.h" 13 14 namespace net { 15 16 namespace test { 17 class QuicConfigPeer; 18 } // namespace test 19 20 class CryptoHandshakeMessage; 21 22 // Describes whether or not a given QuicTag is required or optional in the 23 // handshake message. 24 enum QuicConfigPresence { 25 // This negotiable value can be absent from the handshake message. Default 26 // value is selected as the negotiated value in such a case. 27 PRESENCE_OPTIONAL, 28 // This negotiable value is required in the handshake message otherwise the 29 // Process*Hello function returns an error. 30 PRESENCE_REQUIRED, 31 }; 32 33 // Whether the CryptoHandshakeMessage is from the client or server. 34 enum HelloType { 35 CLIENT, 36 SERVER, 37 }; 38 39 // An abstract base class that stores a value that can be sent in CHLO/SHLO 40 // message. These values can be OPTIONAL or REQUIRED, depending on |presence_|. 41 class NET_EXPORT_PRIVATE QuicConfigValue { 42 public: 43 QuicConfigValue(QuicTag tag, QuicConfigPresence presence); 44 virtual ~QuicConfigValue(); 45 46 // Serialises tag name and value(s) to |out|. 47 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const = 0; 48 49 // Selects a mutually acceptable value from those offered in |peer_hello| 50 // and those defined in the subclass. 51 virtual QuicErrorCode ProcessPeerHello( 52 const CryptoHandshakeMessage& peer_hello, 53 HelloType hello_type, 54 std::string* error_details) = 0; 55 56 protected: 57 const QuicTag tag_; 58 const QuicConfigPresence presence_; 59 }; 60 61 class NET_EXPORT_PRIVATE QuicNegotiableValue : public QuicConfigValue { 62 public: 63 QuicNegotiableValue(QuicTag tag, QuicConfigPresence presence); 64 virtual ~QuicNegotiableValue(); 65 negotiated()66 bool negotiated() const { 67 return negotiated_; 68 } 69 70 protected: 71 bool negotiated_; 72 }; 73 74 class NET_EXPORT_PRIVATE QuicNegotiableUint32 : public QuicNegotiableValue { 75 public: 76 // Default and max values default to 0. 77 QuicNegotiableUint32(QuicTag name, QuicConfigPresence presence); 78 virtual ~QuicNegotiableUint32(); 79 80 // Sets the maximum possible value that can be achieved after negotiation and 81 // also the default values to be assumed if PRESENCE_OPTIONAL and the *HLO msg 82 // doesn't contain a value corresponding to |name_|. |max| is serialised via 83 // ToHandshakeMessage call if |negotiated_| is false. 84 void set(uint32 max, uint32 default_value); 85 86 // Returns the value negotiated if |negotiated_| is true, otherwise returns 87 // default_value_ (used to set default values before negotiation finishes). 88 uint32 GetUint32() const; 89 90 // Serialises |name_| and value to |out|. If |negotiated_| is true then 91 // |negotiated_value_| is serialised, otherwise |max_value_| is serialised. 92 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const OVERRIDE; 93 94 // Sets |negotiated_value_| to the minimum of |max_value_| and the 95 // corresponding value from |peer_hello|. If the corresponding value is 96 // missing and PRESENCE_OPTIONAL then |negotiated_value_| is set to 97 // |default_value_|. 98 virtual QuicErrorCode ProcessPeerHello( 99 const CryptoHandshakeMessage& peer_hello, 100 HelloType hello_type, 101 std::string* error_details) OVERRIDE; 102 103 private: 104 uint32 max_value_; 105 uint32 default_value_; 106 uint32 negotiated_value_; 107 }; 108 109 class NET_EXPORT_PRIVATE QuicNegotiableTag : public QuicNegotiableValue { 110 public: 111 QuicNegotiableTag(QuicTag name, QuicConfigPresence presence); 112 virtual ~QuicNegotiableTag(); 113 114 // Sets the possible values that |negotiated_tag_| can take after negotiation 115 // and the default value that |negotiated_tag_| takes if OPTIONAL and *HLO 116 // msg doesn't contain tag |name_|. 117 void set(const QuicTagVector& possible_values, QuicTag default_value); 118 119 // Returns the negotiated tag if |negotiated_| is true, otherwise returns 120 // |default_value_| (used to set default values before negotiation finishes). 121 QuicTag GetTag() const; 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 virtual 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 virtual QuicErrorCode ProcessPeerHello( 132 const CryptoHandshakeMessage& peer_hello, 133 HelloType hello_type, 134 std::string* error_details) OVERRIDE; 135 136 private: 137 // Reads the vector corresponding to |name_| from |msg| into |out|. If the 138 // |name_| is absent in |msg| and |presence_| is set to OPTIONAL |out| is set 139 // to |possible_values_|. 140 QuicErrorCode ReadVector(const CryptoHandshakeMessage& msg, 141 const QuicTag** out, 142 size_t* out_length, 143 std::string* error_details) const; 144 145 QuicTag negotiated_tag_; 146 QuicTagVector possible_values_; 147 QuicTag default_value_; 148 }; 149 150 // Stores uint32 from CHLO or SHLO messages that are not negotiated. 151 class NET_EXPORT_PRIVATE QuicFixedUint32 : public QuicConfigValue { 152 public: 153 QuicFixedUint32(QuicTag name, QuicConfigPresence presence); 154 virtual ~QuicFixedUint32(); 155 156 bool HasSendValue() const; 157 158 uint32 GetSendValue() const; 159 160 void SetSendValue(uint32 value); 161 162 bool HasReceivedValue() const; 163 164 uint32 GetReceivedValue() const; 165 166 void SetReceivedValue(uint32 value); 167 168 // If has_send_value is true, serialises |tag_| and |send_value_| to |out|. 169 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const OVERRIDE; 170 171 // Sets |value_| to the corresponding value from |peer_hello_| if it exists. 172 virtual QuicErrorCode ProcessPeerHello( 173 const CryptoHandshakeMessage& peer_hello, 174 HelloType hello_type, 175 std::string* error_details) OVERRIDE; 176 177 private: 178 uint32 send_value_; 179 bool has_send_value_; 180 uint32 receive_value_; 181 bool has_receive_value_; 182 }; 183 184 // Stores tag from CHLO or SHLO messages that are not negotiated. 185 class NET_EXPORT_PRIVATE QuicFixedTag : public QuicConfigValue { 186 public: 187 QuicFixedTag(QuicTag name, QuicConfigPresence presence); 188 virtual ~QuicFixedTag(); 189 190 bool HasSendValue() const; 191 192 QuicTag GetSendValue() const; 193 194 void SetSendValue(QuicTag value); 195 196 bool HasReceivedValue() const; 197 198 QuicTag GetReceivedValue() const; 199 200 void SetReceivedValue(QuicTag value); 201 202 // If has_send_value is true, serialises |tag_| and |send_value_| to |out|. 203 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const OVERRIDE; 204 205 // Sets |value_| to the corresponding value from |client_hello_| if it exists. 206 virtual QuicErrorCode ProcessPeerHello( 207 const CryptoHandshakeMessage& peer_hello, 208 HelloType hello_type, 209 std::string* error_details) OVERRIDE; 210 211 private: 212 QuicTag send_value_; 213 bool has_send_value_; 214 QuicTag receive_value_; 215 bool has_receive_value_; 216 }; 217 218 // Stores tag from CHLO or SHLO messages that are not negotiated. 219 class NET_EXPORT_PRIVATE QuicFixedTagVector : public QuicConfigValue { 220 public: 221 QuicFixedTagVector(QuicTag name, QuicConfigPresence presence); 222 virtual ~QuicFixedTagVector(); 223 224 bool HasSendValues() const; 225 226 QuicTagVector GetSendValues() const; 227 228 void SetSendValues(const QuicTagVector& values); 229 230 bool HasReceivedValues() const; 231 232 QuicTagVector GetReceivedValues() const; 233 234 void SetReceivedValues(const QuicTagVector& values); 235 236 // If has_send_value is true, serialises |tag_vector_| and |send_value_| to 237 // |out|. 238 virtual void ToHandshakeMessage(CryptoHandshakeMessage* out) const OVERRIDE; 239 240 // Sets |receive_values_| to the corresponding value from |client_hello_| if 241 // it exists. 242 virtual QuicErrorCode ProcessPeerHello( 243 const CryptoHandshakeMessage& peer_hello, 244 HelloType hello_type, 245 std::string* error_details) OVERRIDE; 246 247 private: 248 QuicTagVector send_values_; 249 bool has_send_values_; 250 QuicTagVector receive_values_; 251 bool has_receive_values_; 252 }; 253 254 // QuicConfig contains non-crypto configuration options that are negotiated in 255 // the crypto handshake. 256 class NET_EXPORT_PRIVATE QuicConfig { 257 public: 258 QuicConfig(); 259 ~QuicConfig(); 260 261 void set_congestion_feedback(const QuicTagVector& congestion_feedback, 262 QuicTag default_congestion_feedback); 263 264 QuicTag congestion_feedback() const; 265 266 void SetConnectionOptionsToSend(const QuicTagVector& connection_options); 267 268 bool HasReceivedConnectionOptions() const; 269 270 QuicTagVector ReceivedConnectionOptions() const; 271 272 bool HasSendConnectionOptions() const; 273 274 QuicTagVector SendConnectionOptions() const; 275 276 void SetLossDetectionToSend(QuicTag loss_detection); 277 278 bool HasReceivedLossDetection() const; 279 280 QuicTag ReceivedLossDetection() const; 281 282 void set_idle_connection_state_lifetime( 283 QuicTime::Delta max_idle_connection_state_lifetime, 284 QuicTime::Delta default_idle_conection_state_lifetime); 285 286 QuicTime::Delta idle_connection_state_lifetime() const; 287 288 QuicTime::Delta keepalive_timeout() const; 289 290 void set_max_streams_per_connection(size_t max_streams, 291 size_t default_streams); 292 293 uint32 max_streams_per_connection() const; 294 295 void set_max_time_before_crypto_handshake( 296 QuicTime::Delta max_time_before_crypto_handshake); 297 298 QuicTime::Delta max_time_before_crypto_handshake() const; 299 300 // Sets the peer's default initial congestion window in packets. 301 void SetInitialCongestionWindowToSend(size_t initial_window); 302 303 bool HasReceivedInitialCongestionWindow() const; 304 305 uint32 ReceivedInitialCongestionWindow() const; 306 307 // Sets an estimated initial round trip time in us. 308 void SetInitialRoundTripTimeUsToSend(size_t rtt_us); 309 310 bool HasReceivedInitialRoundTripTimeUs() const; 311 312 uint32 ReceivedInitialRoundTripTimeUs() const; 313 314 bool HasInitialRoundTripTimeUsToSend() const; 315 316 uint32 GetInitialRoundTripTimeUsToSend() const; 317 318 // TODO(rjshade): Remove all InitialFlowControlWindow methods when removing 319 // QUIC_VERSION_19. 320 // Sets an initial stream flow control window size to transmit to the peer. 321 void SetInitialFlowControlWindowToSend(uint32 window_bytes); 322 323 uint32 GetInitialFlowControlWindowToSend() const; 324 325 bool HasReceivedInitialFlowControlWindowBytes() const; 326 327 uint32 ReceivedInitialFlowControlWindowBytes() const; 328 329 // Sets an initial stream flow control window size to transmit to the peer. 330 void SetInitialStreamFlowControlWindowToSend(uint32 window_bytes); 331 332 uint32 GetInitialStreamFlowControlWindowToSend() const; 333 334 bool HasReceivedInitialStreamFlowControlWindowBytes() const; 335 336 uint32 ReceivedInitialStreamFlowControlWindowBytes() const; 337 338 // Sets an initial session flow control window size to transmit to the peer. 339 void SetInitialSessionFlowControlWindowToSend(uint32 window_bytes); 340 341 uint32 GetInitialSessionFlowControlWindowToSend() const; 342 343 bool HasReceivedInitialSessionFlowControlWindowBytes() const; 344 345 uint32 ReceivedInitialSessionFlowControlWindowBytes() const; 346 347 // Sets socket receive buffer to transmit to the peer. 348 void SetSocketReceiveBufferToSend(uint32 window_bytes); 349 350 uint32 GetSocketReceiveBufferToSend() const; 351 352 bool HasReceivedSocketReceiveBuffer() const; 353 354 uint32 ReceivedSocketReceiveBuffer() const; 355 356 bool negotiated(); 357 358 // SetDefaults sets the members to sensible, default values. 359 void SetDefaults(); 360 361 // ToHandshakeMessage serialises the settings in this object as a series of 362 // tags /value pairs and adds them to |out|. 363 void ToHandshakeMessage(CryptoHandshakeMessage* out) const; 364 365 // Calls ProcessPeerHello on each negotiable parameter. On failure returns 366 // the corresponding QuicErrorCode and sets detailed error in |error_details|. 367 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, 368 HelloType hello_type, 369 std::string* error_details); 370 371 private: 372 friend class test::QuicConfigPeer; 373 374 // Congestion control feedback type. 375 QuicNegotiableTag congestion_feedback_; 376 // Connection options. 377 QuicFixedTagVector connection_options_; 378 // Loss detection feedback type. 379 QuicFixedTag loss_detection_; 380 // Idle connection state lifetime 381 QuicNegotiableUint32 idle_connection_state_lifetime_seconds_; 382 // Keepalive timeout, or 0 to turn off keepalive probes 383 QuicNegotiableUint32 keepalive_timeout_seconds_; 384 // Maximum number of streams that the connection can support. 385 QuicNegotiableUint32 max_streams_per_connection_; 386 // Maximum time till the session can be alive before crypto handshake is 387 // finished. (Not negotiated). 388 QuicTime::Delta max_time_before_crypto_handshake_; 389 // Initial congestion window in packets. 390 QuicFixedUint32 initial_congestion_window_; 391 // Initial round trip time estimate in microseconds. 392 QuicFixedUint32 initial_round_trip_time_us_; 393 394 // TODO(rjshade): Remove when removing QUIC_VERSION_19. 395 // Initial flow control receive window in bytes. 396 QuicFixedUint32 initial_flow_control_window_bytes_; 397 398 // Initial stream flow control receive window in bytes. 399 QuicFixedUint32 initial_stream_flow_control_window_bytes_; 400 // Initial session flow control receive window in bytes. 401 QuicFixedUint32 initial_session_flow_control_window_bytes_; 402 403 // Socket receive buffer in bytes. 404 QuicFixedUint32 socket_receive_buffer_; 405 }; 406 407 } // namespace net 408 409 #endif // NET_QUIC_QUIC_CONFIG_H_ 410