Index: net/tools/quic/quic_client_base.h |
diff --git a/net/tools/quic/quic_client_base.h b/net/tools/quic/quic_client_base.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..50582c3357200b14c6cfd876dbed557b88043a1d |
--- /dev/null |
+++ b/net/tools/quic/quic_client_base.h |
@@ -0,0 +1,241 @@ |
+// Copyright (c) 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+// |
+// A base class for the toy client, which connects to a specified port and sends |
+// QUIC request to that endpoint. |
+ |
+#ifndef NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_ |
+#define NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_ |
+ |
+#include <string> |
+ |
+#include "base/basictypes.h" |
+#include "base/memory/scoped_ptr.h" |
+#include "net/base/ip_endpoint.h" |
+#include "net/log/net_log.h" |
+#include "net/quic/crypto/crypto_handshake.h" |
+#include "net/quic/crypto/quic_crypto_client_config.h" |
+#include "net/quic/quic_bandwidth.h" |
+#include "net/quic/quic_config.h" |
+#include "net/quic/quic_connection.h" |
+#include "net/quic/quic_packet_writer.h" |
+#include "net/quic/quic_protocol.h" |
+#include "net/tools/quic/quic_client_session.h" |
+#include "net/tools/quic/quic_spdy_client_stream.h" |
+ |
+namespace net { |
+ |
+class ProofVerifier; |
+class QuicServerId; |
+ |
+namespace tools { |
+ |
+class QuicClientBase { |
+ public: |
+ // A packet writer factory that always returns the same writer. |
+ class DummyPacketWriterFactory : public QuicConnection::PacketWriterFactory { |
+ public: |
+ explicit DummyPacketWriterFactory(QuicPacketWriter* writer); |
+ ~DummyPacketWriterFactory() override; |
+ |
+ QuicPacketWriter* Create(QuicConnection* connection) const override; |
+ |
+ private: |
+ QuicPacketWriter* writer_; |
+ }; |
+ |
+ QuicClientBase(const QuicServerId& server_id, |
+ const QuicVersionVector& supported_versions, |
+ const QuicConfig& config); |
+ |
+ ~QuicClientBase(); |
+ |
+ // Initializes the client to create a connection. Should be called exactly |
+ // once before calling StartConnect or Connect. Returns true if the |
+ // initialization succeeds, false otherwise. |
+ virtual bool Initialize(); |
+ |
+ // Returns true if the crypto handshake has yet to establish encryption. |
+ // Returns false if encryption is active (even if the server hasn't confirmed |
+ // the handshake) or if the connection has been closed. |
+ bool EncryptionBeingEstablished(); |
+ |
+ // Returns a newly created QuicSpdyClientStream, owned by the |
+ // QuicSimpleClient. |
+ QuicSpdyClientStream* CreateReliableClientStream(); |
+ |
+ // Wait for events until the stream with the given ID is closed. |
+ void WaitForStreamToClose(QuicStreamId id); |
+ |
+ // Wait for events until the handshake is confirmed. |
+ void WaitForCryptoHandshakeConfirmed(); |
+ |
+ // Wait up to 50ms, and handle any events which occur. |
+ // Returns true if there are any outstanding requests. |
+ virtual bool WaitForEvents() = 0; |
+ |
+ QuicClientSession* session() { return session_.get(); } |
+ |
+ bool connected() const; |
+ bool goaway_received() const; |
+ |
+ const QuicServerId& server_id() const { return server_id_; } |
+ |
+ // This should only be set before the initial Connect() |
+ void set_server_id(const QuicServerId& server_id) { server_id_ = server_id; } |
+ |
+ void SetUserAgentID(const std::string& user_agent_id) { |
+ crypto_config_.set_user_agent_id(user_agent_id); |
+ } |
+ |
+ // SetProofVerifier sets the ProofVerifier that will be used to verify the |
+ // server's certificate and takes ownership of |verifier|. |
+ void SetProofVerifier(ProofVerifier* verifier) { |
+ // TODO(rtenneti): We should set ProofVerifier in QuicClientSession. |
+ crypto_config_.SetProofVerifier(verifier); |
+ } |
+ |
+ // SetChannelIDSource sets a ChannelIDSource that will be called, when the |
+ // server supports channel IDs, to obtain a channel ID for signing a message |
+ // proving possession of the channel ID. This object takes ownership of |
+ // |source|. |
+ void SetChannelIDSource(ChannelIDSource* source) { |
+ crypto_config_.SetChannelIDSource(source); |
+ } |
+ |
+ const QuicVersionVector& supported_versions() const { |
+ return supported_versions_; |
+ } |
+ |
+ void SetSupportedVersions(const QuicVersionVector& versions) { |
+ supported_versions_ = versions; |
+ } |
+ |
+ QuicConfig* config() { return &config_; } |
+ |
+ QuicCryptoClientConfig* crypto_config() { return &crypto_config_; } |
+ |
+ // Change the initial maximum packet size of the connection. Has to be called |
+ // before Connect()/StartConnect() in order to have any effect. |
+ void set_initial_max_packet_length(QuicByteCount initial_max_packet_length) { |
+ initial_max_packet_length_ = initial_max_packet_length; |
+ } |
+ |
+ int num_stateless_rejects_received() const { |
+ return num_stateless_rejects_received_; |
+ } |
+ |
+ // The number of client hellos sent, taking stateless rejects into |
+ // account. In the case of a stateless reject, the initial |
+ // connection object may be torn down and a new one created. The |
+ // user cannot rely upon the latest connection object to get the |
+ // total number of client hellos sent, and should use this function |
+ // instead. |
+ int GetNumSentClientHellos(); |
+ |
+ // Gather the stats for the last session and update the stats for the overall |
+ // connection. |
+ void UpdateStats(); |
+ |
+ // Returns any errors that occurred at the connection-level (as |
+ // opposed to the session-level). When a stateless reject occurs, |
+ // the error of the last session may not reflect the overall state |
+ // of the connection. |
+ QuicErrorCode connection_error() const; |
+ void set_connection_error(QuicErrorCode connection_error) { |
+ connection_error_ = connection_error; |
+ } |
+ |
+ bool connected_or_attempting_connect() const { |
+ return connected_or_attempting_connect_; |
+ } |
+ void set_connected_or_attempting_connect( |
+ bool connected_or_attempting_connect) { |
+ connected_or_attempting_connect_ = connected_or_attempting_connect; |
+ } |
+ |
+ QuicPacketWriter* writer() { return writer_.get(); } |
+ void set_writer(QuicPacketWriter* writer) { |
+ if (writer_.get() != writer) { |
+ writer_.reset(writer); |
+ } |
+ } |
+ void reset_writer() { writer_.reset(); } |
+ |
+ QuicByteCount initial_max_packet_length() { |
+ return initial_max_packet_length_; |
+ } |
+ |
+ protected: |
+ virtual QuicClientSession* CreateQuicClientSession( |
+ QuicConnection* connection); |
+ |
+ // Generates the next ConnectionId for |server_id_|. By default, if the |
+ // cached server config contains a server-designated ID, that ID will be |
+ // returned. Otherwise, the next random ID will be returned. |
+ QuicConnectionId GetNextConnectionId(); |
+ |
+ // Returns the next server-designated ConnectionId from the cached config for |
+ // |server_id_|, if it exists. Otherwise, returns 0. |
+ QuicConnectionId GetNextServerDesignatedConnectionId(); |
+ |
+ // Generates a new, random connection ID (as opposed to a server-designated |
+ // connection ID). |
+ virtual QuicConnectionId GenerateNewConnectionId(); |
+ |
+ private: |
+ // |server_id_| is a tuple (hostname, port, is_https) of the server. |
+ QuicServerId server_id_; |
+ |
+ // config_ and crypto_config_ contain configuration and cached state about |
+ // servers. |
+ QuicConfig config_; |
+ QuicCryptoClientConfig crypto_config_; |
+ |
+ // Writer used to actually send packets to the wire. Needs to outlive |
+ // |session_|. |
+ scoped_ptr<QuicPacketWriter> writer_; |
+ |
+ // Session which manages streams. |
+ scoped_ptr<QuicClientSession> session_; |
+ |
+ // This vector contains QUIC versions which we currently support. |
+ // This should be ordered such that the highest supported version is the first |
+ // element, with subsequent elements in descending order (versions can be |
+ // skipped as necessary). We will always pick supported_versions_[0] as the |
+ // initial version to use. |
+ QuicVersionVector supported_versions_; |
+ |
+ // The initial value of maximum packet size of the connection. If set to |
+ // zero, the default is used. |
+ QuicByteCount initial_max_packet_length_; |
+ |
+ // The number of stateless rejects received during the current/latest |
+ // connection. |
+ // TODO(jokulik): Consider some consistent naming scheme (or other) for member |
+ // variables that are kept per-request, per-connection, and over the client's |
+ // lifetime. |
+ int num_stateless_rejects_received_; |
+ |
+ // The number of hellos sent during the current/latest connection. |
+ int num_sent_client_hellos_; |
+ |
+ // Used to store any errors that occurred with the overall connection (as |
+ // opposed to that associated with the last session object). |
+ QuicErrorCode connection_error_; |
+ |
+ // True when the client is attempting to connect or re-connect the session (in |
+ // the case of a stateless reject). Set to false between a call to |
+ // Disconnect() and the subsequent call to StartConnect(). When |
+ // connected_or_attempting_connect_ is false, the session object corresponds |
+ // to the previous client-level connection. |
+ bool connected_or_attempting_connect_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(QuicClientBase); |
+}; |
+ |
+} // namespace tools |
+} // namespace net |
+ |
+#endif // NET_TOOLS_QUIC_QUIC_CLIENT_BASE_H_ |