OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2015 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 // A base class for the toy client, which connects to a specified port and sends |
| 6 // QUIC request to that endpoint. |
| 7 |
| 8 #ifndef NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_ |
| 9 #define NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_ |
| 10 |
| 11 #include <string> |
| 12 |
| 13 #include "base/basictypes.h" |
| 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "net/base/ip_endpoint.h" |
| 16 #include "net/log/net_log.h" |
| 17 #include "net/quic/crypto/crypto_handshake.h" |
| 18 #include "net/quic/crypto/quic_crypto_client_config.h" |
| 19 #include "net/quic/quic_bandwidth.h" |
| 20 #include "net/quic/quic_config.h" |
| 21 #include "net/quic/quic_connection.h" |
| 22 #include "net/quic/quic_packet_writer.h" |
| 23 #include "net/quic/quic_protocol.h" |
| 24 #include "net/tools/quic/quic_client_session.h" |
| 25 #include "net/tools/quic/quic_spdy_client_stream.h" |
| 26 |
| 27 namespace net { |
| 28 |
| 29 class ProofVerifier; |
| 30 class QuicServerId; |
| 31 |
| 32 namespace tools { |
| 33 |
| 34 class QuicClientBase { |
| 35 public: |
| 36 // A packet writer factory that always returns the same writer. |
| 37 class DummyPacketWriterFactory : public QuicConnection::PacketWriterFactory { |
| 38 public: |
| 39 explicit DummyPacketWriterFactory(QuicPacketWriter* writer); |
| 40 ~DummyPacketWriterFactory() override; |
| 41 |
| 42 QuicPacketWriter* Create(QuicConnection* connection) const override; |
| 43 |
| 44 private: |
| 45 QuicPacketWriter* writer_; |
| 46 }; |
| 47 |
| 48 QuicClientBase(const QuicServerId& server_id, |
| 49 const QuicVersionVector& supported_versions, |
| 50 const QuicConfig& config); |
| 51 |
| 52 ~QuicClientBase(); |
| 53 |
| 54 // Initializes the client to create a connection. Should be called exactly |
| 55 // once before calling StartConnect or Connect. Returns true if the |
| 56 // initialization succeeds, false otherwise. |
| 57 virtual bool Initialize(); |
| 58 |
| 59 // Returns true if the crypto handshake has yet to establish encryption. |
| 60 // Returns false if encryption is active (even if the server hasn't confirmed |
| 61 // the handshake) or if the connection has been closed. |
| 62 bool EncryptionBeingEstablished(); |
| 63 |
| 64 // Returns a newly created QuicSpdyClientStream, owned by the |
| 65 // QuicSimpleClient. |
| 66 QuicSpdyClientStream* CreateReliableClientStream(); |
| 67 |
| 68 // Wait for events until the stream with the given ID is closed. |
| 69 void WaitForStreamToClose(QuicStreamId id); |
| 70 |
| 71 // Wait for events until the handshake is confirmed. |
| 72 void WaitForCryptoHandshakeConfirmed(); |
| 73 |
| 74 // Wait up to 50ms, and handle any events which occur. |
| 75 // Returns true if there are any outstanding requests. |
| 76 virtual bool WaitForEvents() = 0; |
| 77 |
| 78 QuicClientSession* session() { return session_.get(); } |
| 79 |
| 80 bool connected() const; |
| 81 bool goaway_received() const; |
| 82 |
| 83 const QuicServerId& server_id() const { return server_id_; } |
| 84 |
| 85 // This should only be set before the initial Connect() |
| 86 void set_server_id(const QuicServerId& server_id) { server_id_ = server_id; } |
| 87 |
| 88 void SetUserAgentID(const std::string& user_agent_id) { |
| 89 crypto_config_.set_user_agent_id(user_agent_id); |
| 90 } |
| 91 |
| 92 // SetProofVerifier sets the ProofVerifier that will be used to verify the |
| 93 // server's certificate and takes ownership of |verifier|. |
| 94 void SetProofVerifier(ProofVerifier* verifier) { |
| 95 // TODO(rtenneti): We should set ProofVerifier in QuicClientSession. |
| 96 crypto_config_.SetProofVerifier(verifier); |
| 97 } |
| 98 |
| 99 // SetChannelIDSource sets a ChannelIDSource that will be called, when the |
| 100 // server supports channel IDs, to obtain a channel ID for signing a message |
| 101 // proving possession of the channel ID. This object takes ownership of |
| 102 // |source|. |
| 103 void SetChannelIDSource(ChannelIDSource* source) { |
| 104 crypto_config_.SetChannelIDSource(source); |
| 105 } |
| 106 |
| 107 const QuicVersionVector& supported_versions() const { |
| 108 return supported_versions_; |
| 109 } |
| 110 |
| 111 void SetSupportedVersions(const QuicVersionVector& versions) { |
| 112 supported_versions_ = versions; |
| 113 } |
| 114 |
| 115 QuicConfig* config() { return &config_; } |
| 116 |
| 117 QuicCryptoClientConfig* crypto_config() { return &crypto_config_; } |
| 118 |
| 119 // Change the initial maximum packet size of the connection. Has to be called |
| 120 // before Connect()/StartConnect() in order to have any effect. |
| 121 void set_initial_max_packet_length(QuicByteCount initial_max_packet_length) { |
| 122 initial_max_packet_length_ = initial_max_packet_length; |
| 123 } |
| 124 |
| 125 int num_stateless_rejects_received() const { |
| 126 return num_stateless_rejects_received_; |
| 127 } |
| 128 |
| 129 // The number of client hellos sent, taking stateless rejects into |
| 130 // account. In the case of a stateless reject, the initial |
| 131 // connection object may be torn down and a new one created. The |
| 132 // user cannot rely upon the latest connection object to get the |
| 133 // total number of client hellos sent, and should use this function |
| 134 // instead. |
| 135 int GetNumSentClientHellos(); |
| 136 |
| 137 // Gather the stats for the last session and update the stats for the overall |
| 138 // connection. |
| 139 void UpdateStats(); |
| 140 |
| 141 // Returns any errors that occurred at the connection-level (as |
| 142 // opposed to the session-level). When a stateless reject occurs, |
| 143 // the error of the last session may not reflect the overall state |
| 144 // of the connection. |
| 145 QuicErrorCode connection_error() const; |
| 146 void set_connection_error(QuicErrorCode connection_error) { |
| 147 connection_error_ = connection_error; |
| 148 } |
| 149 |
| 150 bool connected_or_attempting_connect() const { |
| 151 return connected_or_attempting_connect_; |
| 152 } |
| 153 void set_connected_or_attempting_connect( |
| 154 bool connected_or_attempting_connect) { |
| 155 connected_or_attempting_connect_ = connected_or_attempting_connect; |
| 156 } |
| 157 |
| 158 QuicPacketWriter* writer() { return writer_.get(); } |
| 159 void set_writer(QuicPacketWriter* writer) { |
| 160 if (writer_.get() != writer) { |
| 161 writer_.reset(writer); |
| 162 } |
| 163 } |
| 164 void reset_writer() { writer_.reset(); } |
| 165 |
| 166 QuicByteCount initial_max_packet_length() { |
| 167 return initial_max_packet_length_; |
| 168 } |
| 169 |
| 170 protected: |
| 171 virtual QuicClientSession* CreateQuicClientSession( |
| 172 QuicConnection* connection); |
| 173 |
| 174 // Generates the next ConnectionId for |server_id_|. By default, if the |
| 175 // cached server config contains a server-designated ID, that ID will be |
| 176 // returned. Otherwise, the next random ID will be returned. |
| 177 QuicConnectionId GetNextConnectionId(); |
| 178 |
| 179 // Returns the next server-designated ConnectionId from the cached config for |
| 180 // |server_id_|, if it exists. Otherwise, returns 0. |
| 181 QuicConnectionId GetNextServerDesignatedConnectionId(); |
| 182 |
| 183 // Generates a new, random connection ID (as opposed to a server-designated |
| 184 // connection ID). |
| 185 virtual QuicConnectionId GenerateNewConnectionId(); |
| 186 |
| 187 private: |
| 188 // |server_id_| is a tuple (hostname, port, is_https) of the server. |
| 189 QuicServerId server_id_; |
| 190 |
| 191 // config_ and crypto_config_ contain configuration and cached state about |
| 192 // servers. |
| 193 QuicConfig config_; |
| 194 QuicCryptoClientConfig crypto_config_; |
| 195 |
| 196 // Writer used to actually send packets to the wire. Needs to outlive |
| 197 // |session_|. |
| 198 scoped_ptr<QuicPacketWriter> writer_; |
| 199 |
| 200 // Session which manages streams. |
| 201 scoped_ptr<QuicClientSession> session_; |
| 202 |
| 203 // This vector contains QUIC versions which we currently support. |
| 204 // This should be ordered such that the highest supported version is the first |
| 205 // element, with subsequent elements in descending order (versions can be |
| 206 // skipped as necessary). We will always pick supported_versions_[0] as the |
| 207 // initial version to use. |
| 208 QuicVersionVector supported_versions_; |
| 209 |
| 210 // The initial value of maximum packet size of the connection. If set to |
| 211 // zero, the default is used. |
| 212 QuicByteCount initial_max_packet_length_; |
| 213 |
| 214 // The number of stateless rejects received during the current/latest |
| 215 // connection. |
| 216 // TODO(jokulik): Consider some consistent naming scheme (or other) for member |
| 217 // variables that are kept per-request, per-connection, and over the client's |
| 218 // lifetime. |
| 219 int num_stateless_rejects_received_; |
| 220 |
| 221 // The number of hellos sent during the current/latest connection. |
| 222 int num_sent_client_hellos_; |
| 223 |
| 224 // Used to store any errors that occurred with the overall connection (as |
| 225 // opposed to that associated with the last session object). |
| 226 QuicErrorCode connection_error_; |
| 227 |
| 228 // True when the client is attempting to connect or re-connect the session (in |
| 229 // the case of a stateless reject). Set to false between a call to |
| 230 // Disconnect() and the subsequent call to StartConnect(). When |
| 231 // connected_or_attempting_connect_ is false, the session object corresponds |
| 232 // to the previous client-level connection. |
| 233 bool connected_or_attempting_connect_; |
| 234 |
| 235 DISALLOW_COPY_AND_ASSIGN(QuicClientBase); |
| 236 }; |
| 237 |
| 238 } // namespace tools |
| 239 } // namespace net |
| 240 |
| 241 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_ |
OLD | NEW |