Home | History | Annotate | Download | only in quic
      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 
     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