1 // Copyright (c) 2012 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 toy client, which connects to a specified port and sends QUIC 6 // request to that endpoint. 7 8 #ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_ 9 #define NET_TOOLS_QUIC_QUIC_CLIENT_H_ 10 11 #include <string> 12 13 #include "base/basictypes.h" 14 #include "base/command_line.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "net/base/ip_endpoint.h" 17 #include "net/quic/crypto/crypto_handshake.h" 18 #include "net/quic/quic_config.h" 19 #include "net/quic/quic_framer.h" 20 #include "net/quic/quic_packet_creator.h" 21 #include "net/tools/epoll_server/epoll_server.h" 22 #include "net/tools/quic/quic_client_session.h" 23 #include "net/tools/quic/quic_spdy_client_stream.h" 24 25 namespace net { 26 27 class ProofVerifier; 28 class QuicServerId; 29 30 namespace tools { 31 32 class QuicEpollConnectionHelper; 33 34 namespace test { 35 class QuicClientPeer; 36 } // namespace test 37 38 class QuicClient : public EpollCallbackInterface, 39 public QuicDataStream::Visitor { 40 public: 41 class ResponseListener { 42 public: 43 ResponseListener() {} 44 virtual ~ResponseListener() {} 45 virtual void OnCompleteResponse(QuicStreamId id, 46 const BalsaHeaders& response_headers, 47 const string& response_body) = 0; 48 }; 49 50 // Create a quic client, which will have events managed by an externally owned 51 // EpollServer. 52 QuicClient(IPEndPoint server_address, 53 const QuicServerId& server_id, 54 const QuicVersionVector& supported_versions, 55 bool print_response, 56 EpollServer* epoll_server); 57 QuicClient(IPEndPoint server_address, 58 const QuicServerId& server_id, 59 const QuicVersionVector& supported_versions, 60 bool print_response, 61 const QuicConfig& config, 62 EpollServer* epoll_server); 63 64 virtual ~QuicClient(); 65 66 // Initializes the client to create a connection. Should be called exactly 67 // once before calling StartConnect or Connect. Returns true if the 68 // initialization succeeds, false otherwise. 69 bool Initialize(); 70 71 // "Connect" to the QUIC server, including performing synchronous crypto 72 // handshake. 73 bool Connect(); 74 75 // Start the crypto handshake. This can be done in place of the synchronous 76 // Connect(), but callers are responsible for making sure the crypto handshake 77 // completes. 78 bool StartConnect(); 79 80 // Returns true if the crypto handshake has yet to establish encryption. 81 // Returns false if encryption is active (even if the server hasn't confirmed 82 // the handshake) or if the connection has been closed. 83 bool EncryptionBeingEstablished(); 84 85 // Disconnects from the QUIC server. 86 void Disconnect(); 87 88 // Sends a request simple GET for each URL in |args|, and then waits for 89 // each to complete. 90 void SendRequestsAndWaitForResponse(const 91 base::CommandLine::StringVector& args); 92 93 // Returns a newly created QuicSpdyClientStream, owned by the 94 // QuicClient. 95 QuicSpdyClientStream* CreateReliableClientStream(); 96 97 // Wait for events until the stream with the given ID is closed. 98 void WaitForStreamToClose(QuicStreamId id); 99 100 // Wait for events until the handshake is confirmed. 101 void WaitForCryptoHandshakeConfirmed(); 102 103 // Wait up to 50ms, and handle any events which occur. 104 // Returns true if there are any outstanding requests. 105 bool WaitForEvents(); 106 107 // From EpollCallbackInterface 108 virtual void OnRegistration(EpollServer* eps, 109 int fd, 110 int event_mask) OVERRIDE {} 111 virtual void OnModification(int fd, int event_mask) OVERRIDE {} 112 virtual void OnEvent(int fd, EpollEvent* event) OVERRIDE; 113 // |fd_| can be unregistered without the client being disconnected. This 114 // happens in b3m QuicProber where we unregister |fd_| to feed in events to 115 // the client from the SelectServer. 116 virtual void OnUnregistration(int fd, bool replaced) OVERRIDE {} 117 virtual void OnShutdown(EpollServer* eps, int fd) OVERRIDE {} 118 119 // QuicDataStream::Visitor 120 virtual void OnClose(QuicDataStream* stream) OVERRIDE; 121 122 QuicClientSession* session() { return session_.get(); } 123 124 bool connected() const; 125 126 void set_bind_to_address(IPAddressNumber address) { 127 bind_to_address_ = address; 128 } 129 130 IPAddressNumber bind_to_address() const { return bind_to_address_; } 131 132 void set_local_port(int local_port) { local_port_ = local_port; } 133 134 const IPEndPoint& server_address() const { return server_address_; } 135 136 const IPEndPoint& client_address() const { return client_address_; } 137 138 int fd() { return fd_; } 139 140 const QuicServerId& server_id() const { return server_id_; } 141 142 // This should only be set before the initial Connect() 143 void set_server_id(const QuicServerId& server_id) { 144 server_id_ = server_id; 145 } 146 147 void SetUserAgentID(const string& user_agent_id) { 148 crypto_config_.set_user_agent_id(user_agent_id); 149 } 150 151 // SetProofVerifier sets the ProofVerifier that will be used to verify the 152 // server's certificate and takes ownership of |verifier|. 153 void SetProofVerifier(ProofVerifier* verifier) { 154 // TODO(rtenneti): We should set ProofVerifier in QuicClientSession. 155 crypto_config_.SetProofVerifier(verifier); 156 } 157 158 // SetChannelIDSource sets a ChannelIDSource that will be called, when the 159 // server supports channel IDs, to obtain a channel ID for signing a message 160 // proving possession of the channel ID. This object takes ownership of 161 // |source|. 162 void SetChannelIDSource(ChannelIDSource* source) { 163 crypto_config_.SetChannelIDSource(source); 164 } 165 166 void SetSupportedVersions(const QuicVersionVector& versions) { 167 supported_versions_ = versions; 168 } 169 170 // Takes ownership of the listener. 171 void set_response_listener(ResponseListener* listener) { 172 response_listener_.reset(listener); 173 } 174 175 protected: 176 virtual QuicConnectionId GenerateConnectionId(); 177 virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper(); 178 virtual QuicPacketWriter* CreateQuicPacketWriter(); 179 180 virtual int ReadPacket(char* buffer, 181 int buffer_len, 182 IPEndPoint* server_address, 183 IPAddressNumber* client_ip); 184 185 EpollServer* epoll_server() { return epoll_server_; } 186 QuicConfig* config() { return &config_; } 187 188 private: 189 friend class net::tools::test::QuicClientPeer; 190 191 // A packet writer factory that always returns the same writer 192 class DummyPacketWriterFactory : public QuicConnection::PacketWriterFactory { 193 public: 194 DummyPacketWriterFactory(QuicPacketWriter* writer); 195 virtual ~DummyPacketWriterFactory(); 196 197 virtual QuicPacketWriter* Create(QuicConnection* connection) const OVERRIDE; 198 199 private: 200 QuicPacketWriter* writer_; 201 }; 202 203 // Used during initialization: creates the UDP socket FD, sets socket options, 204 // and binds the socket to our address. 205 bool CreateUDPSocket(); 206 207 // Read a UDP packet and hand it to the framer. 208 bool ReadAndProcessPacket(); 209 210 // Address of the server. 211 const IPEndPoint server_address_; 212 213 // |server_id_| is a tuple (hostname, port, is_https) of the server. 214 QuicServerId server_id_; 215 216 // config_ and crypto_config_ contain configuration and cached state about 217 // servers. 218 QuicConfig config_; 219 QuicCryptoClientConfig crypto_config_; 220 221 // Address of the client if the client is connected to the server. 222 IPEndPoint client_address_; 223 224 // If initialized, the address to bind to. 225 IPAddressNumber bind_to_address_; 226 // Local port to bind to. Initialize to 0. 227 int local_port_; 228 229 // Writer used to actually send packets to the wire. Needs to outlive 230 // |session_|. 231 scoped_ptr<QuicPacketWriter> writer_; 232 233 // Session which manages streams. 234 scoped_ptr<QuicClientSession> session_; 235 // Listens for events on the client socket. 236 EpollServer* epoll_server_; 237 // UDP socket. 238 int fd_; 239 240 // Helper to be used by created connections. 241 scoped_ptr<QuicEpollConnectionHelper> helper_; 242 243 // Listens for full responses. 244 scoped_ptr<ResponseListener> response_listener_; 245 246 // Tracks if the client is initialized to connect. 247 bool initialized_; 248 249 // If overflow_supported_ is true, this will be the number of packets dropped 250 // during the lifetime of the server. This may overflow if enough packets 251 // are dropped. 252 uint32 packets_dropped_; 253 254 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped 255 // because the socket would otherwise overflow. 256 bool overflow_supported_; 257 258 // This vector contains QUIC versions which we currently support. 259 // This should be ordered such that the highest supported version is the first 260 // element, with subsequent elements in descending order (versions can be 261 // skipped as necessary). We will always pick supported_versions_[0] as the 262 // initial version to use. 263 QuicVersionVector supported_versions_; 264 265 // If true, then the contents of each response will be printed to stdout 266 // when the stream is closed (in OnClose). 267 bool print_response_; 268 269 DISALLOW_COPY_AND_ASSIGN(QuicClient); 270 }; 271 272 } // namespace tools 273 } // namespace net 274 275 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_ 276