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 SetCongestionOptionsToSend(const QuicTagVector& congestion_options); 267 268 bool HasReceivedCongestionOptions() const; 269 270 QuicTagVector ReceivedCongestionOptions() const; 271 272 void SetLossDetectionToSend(QuicTag loss_detection); 273 274 bool HasReceivedLossDetection() const; 275 276 QuicTag ReceivedLossDetection() const; 277 278 void set_idle_connection_state_lifetime( 279 QuicTime::Delta max_idle_connection_state_lifetime, 280 QuicTime::Delta default_idle_conection_state_lifetime); 281 282 QuicTime::Delta idle_connection_state_lifetime() const; 283 284 QuicTime::Delta keepalive_timeout() const; 285 286 void set_max_streams_per_connection(size_t max_streams, 287 size_t default_streams); 288 289 uint32 max_streams_per_connection() const; 290 291 void set_max_time_before_crypto_handshake( 292 QuicTime::Delta max_time_before_crypto_handshake); 293 294 QuicTime::Delta max_time_before_crypto_handshake() const; 295 296 // Sets the peer's default initial congestion window in packets. 297 void SetInitialCongestionWindowToSend(size_t initial_window); 298 299 bool HasReceivedInitialCongestionWindow() const; 300 301 uint32 ReceivedInitialCongestionWindow() const; 302 303 // Sets an estimated initial round trip time in us. 304 void SetInitialRoundTripTimeUsToSend(size_t rtt_us); 305 306 bool HasReceivedInitialRoundTripTimeUs() const; 307 308 uint32 ReceivedInitialRoundTripTimeUs() const; 309 310 // TODO(rjshade): Remove all InitialFlowControlWindow methods when removing 311 // QUIC_VERSION_19. 312 // Sets an initial stream flow control window size to transmit to the peer. 313 void SetInitialFlowControlWindowToSend(uint32 window_bytes); 314 315 uint32 GetInitialFlowControlWindowToSend() const; 316 317 bool HasReceivedInitialFlowControlWindowBytes() const; 318 319 uint32 ReceivedInitialFlowControlWindowBytes() const; 320 321 // Sets an initial stream flow control window size to transmit to the peer. 322 void SetInitialStreamFlowControlWindowToSend(uint32 window_bytes); 323 324 uint32 GetInitialStreamFlowControlWindowToSend() const; 325 326 bool HasReceivedInitialStreamFlowControlWindowBytes() const; 327 328 uint32 ReceivedInitialStreamFlowControlWindowBytes() const; 329 330 // Sets an initial session flow control window size to transmit to the peer. 331 void SetInitialSessionFlowControlWindowToSend(uint32 window_bytes); 332 333 uint32 GetInitialSessionFlowControlWindowToSend() const; 334 335 bool HasReceivedInitialSessionFlowControlWindowBytes() const; 336 337 uint32 ReceivedInitialSessionFlowControlWindowBytes() const; 338 339 bool negotiated(); 340 341 // SetDefaults sets the members to sensible, default values. 342 void SetDefaults(); 343 344 // Enabled pacing. 345 void EnablePacing(bool enable_pacing); 346 347 // ToHandshakeMessage serialises the settings in this object as a series of 348 // tags /value pairs and adds them to |out|. 349 void ToHandshakeMessage(CryptoHandshakeMessage* out) const; 350 351 // Calls ProcessPeerHello on each negotiable parameter. On failure returns 352 // the corresponding QuicErrorCode and sets detailed error in |error_details|. 353 QuicErrorCode ProcessPeerHello(const CryptoHandshakeMessage& peer_hello, 354 HelloType hello_type, 355 std::string* error_details); 356 357 private: 358 friend class test::QuicConfigPeer; 359 360 // Congestion control feedback type. 361 QuicNegotiableTag congestion_feedback_; 362 // Congestion control option. 363 QuicFixedTagVector congestion_options_; 364 // Loss detection feedback type. 365 QuicFixedTag loss_detection_; 366 // Idle connection state lifetime 367 QuicNegotiableUint32 idle_connection_state_lifetime_seconds_; 368 // Keepalive timeout, or 0 to turn off keepalive probes 369 QuicNegotiableUint32 keepalive_timeout_seconds_; 370 // Maximum number of streams that the connection can support. 371 QuicNegotiableUint32 max_streams_per_connection_; 372 // Maximum time till the session can be alive before crypto handshake is 373 // finished. (Not negotiated). 374 QuicTime::Delta max_time_before_crypto_handshake_; 375 // Initial congestion window in packets. 376 QuicFixedUint32 initial_congestion_window_; 377 // Initial round trip time estimate in microseconds. 378 QuicFixedUint32 initial_round_trip_time_us_; 379 380 // TODO(rjshade): Remove when removing QUIC_VERSION_19. 381 // Initial flow control receive window in bytes. 382 QuicFixedUint32 initial_flow_control_window_bytes_; 383 384 // Initial stream flow control receive window in bytes. 385 QuicFixedUint32 initial_stream_flow_control_window_bytes_; 386 // Initial session flow control receive window in bytes. 387 QuicFixedUint32 initial_session_flow_control_window_bytes_; 388 }; 389 390 } // namespace net 391 392 #endif // NET_QUIC_QUIC_CONFIG_H_ 393