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: ResponseListener()43 ResponseListener() {} ~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 OnRegistration(EpollServer * eps,int fd,int event_mask)108 virtual void OnRegistration(EpollServer* eps, 109 int fd, 110 int event_mask) OVERRIDE {} OnModification(int fd,int event_mask)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. OnUnregistration(int fd,bool replaced)116 virtual void OnUnregistration(int fd, bool replaced) OVERRIDE {} OnShutdown(EpollServer * eps,int fd)117 virtual void OnShutdown(EpollServer* eps, int fd) OVERRIDE {} 118 119 // QuicDataStream::Visitor 120 virtual void OnClose(QuicDataStream* stream) OVERRIDE; 121 session()122 QuicClientSession* session() { return session_.get(); } 123 124 bool connected() const; 125 set_bind_to_address(IPAddressNumber address)126 void set_bind_to_address(IPAddressNumber address) { 127 bind_to_address_ = address; 128 } 129 bind_to_address()130 IPAddressNumber bind_to_address() const { return bind_to_address_; } 131 set_local_port(int local_port)132 void set_local_port(int local_port) { local_port_ = local_port; } 133 server_address()134 const IPEndPoint& server_address() const { return server_address_; } 135 client_address()136 const IPEndPoint& client_address() const { return client_address_; } 137 epoll_server()138 EpollServer* epoll_server() { return epoll_server_; } 139 fd()140 int fd() { return fd_; } 141 server_id()142 const QuicServerId& server_id() const { return server_id_; } 143 144 // This should only be set before the initial Connect() set_server_id(const QuicServerId & server_id)145 void set_server_id(const QuicServerId& server_id) { 146 server_id_ = server_id; 147 } 148 SetUserAgentID(const string & user_agent_id)149 void SetUserAgentID(const string& user_agent_id) { 150 crypto_config_.set_user_agent_id(user_agent_id); 151 } 152 153 // SetProofVerifier sets the ProofVerifier that will be used to verify the 154 // server's certificate and takes ownership of |verifier|. SetProofVerifier(ProofVerifier * verifier)155 void SetProofVerifier(ProofVerifier* verifier) { 156 // TODO(rtenneti): We should set ProofVerifier in QuicClientSession. 157 crypto_config_.SetProofVerifier(verifier); 158 } 159 160 // SetChannelIDSource sets a ChannelIDSource that will be called, when the 161 // server supports channel IDs, to obtain a channel ID for signing a message 162 // proving possession of the channel ID. This object takes ownership of 163 // |source|. SetChannelIDSource(ChannelIDSource * source)164 void SetChannelIDSource(ChannelIDSource* source) { 165 crypto_config_.SetChannelIDSource(source); 166 } 167 SetSupportedVersions(const QuicVersionVector & versions)168 void SetSupportedVersions(const QuicVersionVector& versions) { 169 supported_versions_ = versions; 170 } 171 172 // Takes ownership of the listener. set_response_listener(ResponseListener * listener)173 void set_response_listener(ResponseListener* listener) { 174 response_listener_.reset(listener); 175 } 176 177 protected: 178 virtual QuicConnectionId GenerateConnectionId(); 179 virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper(); 180 virtual QuicPacketWriter* CreateQuicPacketWriter(); 181 182 virtual int ReadPacket(char* buffer, 183 int buffer_len, 184 IPEndPoint* server_address, 185 IPAddressNumber* client_ip); 186 187 private: 188 friend class net::tools::test::QuicClientPeer; 189 190 // Used during initialization: creates the UDP socket FD, sets socket options, 191 // and binds the socket to our address. 192 bool CreateUDPSocket(); 193 194 // Read a UDP packet and hand it to the framer. 195 bool ReadAndProcessPacket(); 196 197 // Address of the server. 198 const IPEndPoint server_address_; 199 200 // |server_id_| is a tuple (hostname, port, is_https) of the server. 201 QuicServerId server_id_; 202 203 // config_ and crypto_config_ contain configuration and cached state about 204 // servers. 205 QuicConfig config_; 206 QuicCryptoClientConfig crypto_config_; 207 208 // Address of the client if the client is connected to the server. 209 IPEndPoint client_address_; 210 211 // If initialized, the address to bind to. 212 IPAddressNumber bind_to_address_; 213 // Local port to bind to. Initialize to 0. 214 int local_port_; 215 216 // Session which manages streams. 217 scoped_ptr<QuicClientSession> session_; 218 // Listens for events on the client socket. 219 EpollServer* epoll_server_; 220 // UDP socket. 221 int fd_; 222 223 // Helper to be used by created connections. 224 scoped_ptr<QuicEpollConnectionHelper> helper_; 225 226 // Listens for full responses. 227 scoped_ptr<ResponseListener> response_listener_; 228 229 // Writer used to actually send packets to the wire. 230 scoped_ptr<QuicPacketWriter> writer_; 231 232 // Tracks if the client is initialized to connect. 233 bool initialized_; 234 235 // If overflow_supported_ is true, this will be the number of packets dropped 236 // during the lifetime of the server. This may overflow if enough packets 237 // are dropped. 238 uint32 packets_dropped_; 239 240 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped 241 // because the socket would otherwise overflow. 242 bool overflow_supported_; 243 244 // This vector contains QUIC versions which we currently support. 245 // This should be ordered such that the highest supported version is the first 246 // element, with subsequent elements in descending order (versions can be 247 // skipped as necessary). We will always pick supported_versions_[0] as the 248 // initial version to use. 249 QuicVersionVector supported_versions_; 250 251 // If true, then the contents of each response will be printed to stdout 252 // when the stream is closed (in OnClose). 253 bool print_response_; 254 255 DISALLOW_COPY_AND_ASSIGN(QuicClient); 256 }; 257 258 } // namespace tools 259 } // namespace net 260 261 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_ 262