| OLD | NEW |
| (Empty) |
| 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 "base/strings/string_piece.h" | |
| 17 #include "net/base/ip_endpoint.h" | |
| 18 #include "net/quic/crypto/crypto_handshake.h" | |
| 19 #include "net/quic/quic_config.h" | |
| 20 #include "net/quic/quic_framer.h" | |
| 21 #include "net/quic/quic_packet_creator.h" | |
| 22 #include "net/tools/balsa/balsa_headers.h" | |
| 23 #include "net/tools/epoll_server/epoll_server.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 QuicEpollConnectionHelper; | |
| 35 | |
| 36 namespace test { | |
| 37 class QuicClientPeer; | |
| 38 } // namespace test | |
| 39 | |
| 40 class QuicClient : public EpollCallbackInterface, | |
| 41 public QuicDataStream::Visitor { | |
| 42 public: | |
| 43 class ResponseListener { | |
| 44 public: | |
| 45 ResponseListener() {} | |
| 46 virtual ~ResponseListener() {} | |
| 47 virtual void OnCompleteResponse(QuicStreamId id, | |
| 48 const BalsaHeaders& response_headers, | |
| 49 const std::string& response_body) = 0; | |
| 50 }; | |
| 51 | |
| 52 // Create a quic client, which will have events managed by an externally owned | |
| 53 // EpollServer. | |
| 54 QuicClient(IPEndPoint server_address, | |
| 55 const QuicServerId& server_id, | |
| 56 const QuicVersionVector& supported_versions, | |
| 57 EpollServer* epoll_server); | |
| 58 QuicClient(IPEndPoint server_address, | |
| 59 const QuicServerId& server_id, | |
| 60 const QuicVersionVector& supported_versions, | |
| 61 const QuicConfig& config, | |
| 62 EpollServer* epoll_server); | |
| 63 | |
| 64 ~QuicClient() override; | |
| 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 void 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 an HTTP request and does not wait for response before returning. | |
| 89 void SendRequest(const BalsaHeaders& headers, | |
| 90 base::StringPiece body, | |
| 91 bool fin); | |
| 92 | |
| 93 // Sends an HTTP request and waits for response before returning. | |
| 94 void SendRequestAndWaitForResponse(const BalsaHeaders& headers, | |
| 95 base::StringPiece body, | |
| 96 bool fin); | |
| 97 | |
| 98 // Sends a request simple GET for each URL in |args|, and then waits for | |
| 99 // each to complete. | |
| 100 void SendRequestsAndWaitForResponse(const | |
| 101 base::CommandLine::StringVector& args); | |
| 102 | |
| 103 // Returns a newly created QuicSpdyClientStream, owned by the | |
| 104 // QuicClient. | |
| 105 QuicSpdyClientStream* CreateReliableClientStream(); | |
| 106 | |
| 107 // Wait for events until the stream with the given ID is closed. | |
| 108 void WaitForStreamToClose(QuicStreamId id); | |
| 109 | |
| 110 // Wait for events until the handshake is confirmed. | |
| 111 void WaitForCryptoHandshakeConfirmed(); | |
| 112 | |
| 113 // Wait up to 50ms, and handle any events which occur. | |
| 114 // Returns true if there are any outstanding requests. | |
| 115 bool WaitForEvents(); | |
| 116 | |
| 117 // From EpollCallbackInterface | |
| 118 void OnRegistration(EpollServer* eps, int fd, int event_mask) override {} | |
| 119 void OnModification(int fd, int event_mask) override {} | |
| 120 void OnEvent(int fd, EpollEvent* event) override; | |
| 121 // |fd_| can be unregistered without the client being disconnected. This | |
| 122 // happens in b3m QuicProber where we unregister |fd_| to feed in events to | |
| 123 // the client from the SelectServer. | |
| 124 void OnUnregistration(int fd, bool replaced) override {} | |
| 125 void OnShutdown(EpollServer* eps, int fd) override {} | |
| 126 | |
| 127 // QuicDataStream::Visitor | |
| 128 void OnClose(QuicDataStream* stream) override; | |
| 129 | |
| 130 QuicClientSession* session() { return session_.get(); } | |
| 131 | |
| 132 bool connected() const; | |
| 133 bool goaway_received() const; | |
| 134 | |
| 135 void set_bind_to_address(IPAddressNumber address) { | |
| 136 bind_to_address_ = address; | |
| 137 } | |
| 138 | |
| 139 IPAddressNumber bind_to_address() const { return bind_to_address_; } | |
| 140 | |
| 141 void set_local_port(int local_port) { local_port_ = local_port; } | |
| 142 | |
| 143 const IPEndPoint& server_address() const { return server_address_; } | |
| 144 | |
| 145 const IPEndPoint& client_address() const { return client_address_; } | |
| 146 | |
| 147 int fd() { return fd_; } | |
| 148 | |
| 149 const QuicServerId& server_id() const { return server_id_; } | |
| 150 | |
| 151 // This should only be set before the initial Connect() | |
| 152 void set_server_id(const QuicServerId& server_id) { | |
| 153 server_id_ = server_id; | |
| 154 } | |
| 155 | |
| 156 void SetUserAgentID(const std::string& user_agent_id) { | |
| 157 crypto_config_.set_user_agent_id(user_agent_id); | |
| 158 } | |
| 159 | |
| 160 // SetProofVerifier sets the ProofVerifier that will be used to verify the | |
| 161 // server's certificate and takes ownership of |verifier|. | |
| 162 void SetProofVerifier(ProofVerifier* verifier) { | |
| 163 // TODO(rtenneti): We should set ProofVerifier in QuicClientSession. | |
| 164 crypto_config_.SetProofVerifier(verifier); | |
| 165 } | |
| 166 | |
| 167 // SetChannelIDSource sets a ChannelIDSource that will be called, when the | |
| 168 // server supports channel IDs, to obtain a channel ID for signing a message | |
| 169 // proving possession of the channel ID. This object takes ownership of | |
| 170 // |source|. | |
| 171 void SetChannelIDSource(ChannelIDSource* source) { | |
| 172 crypto_config_.SetChannelIDSource(source); | |
| 173 } | |
| 174 | |
| 175 void SetSupportedVersions(const QuicVersionVector& versions) { | |
| 176 supported_versions_ = versions; | |
| 177 } | |
| 178 | |
| 179 // Takes ownership of the listener. | |
| 180 void set_response_listener(ResponseListener* listener) { | |
| 181 response_listener_.reset(listener); | |
| 182 } | |
| 183 | |
| 184 QuicConfig* config() { return &config_; } | |
| 185 | |
| 186 void set_store_response(bool val) { store_response_ = val; } | |
| 187 | |
| 188 size_t latest_response_code() const; | |
| 189 const std::string& latest_response_headers() const; | |
| 190 const std::string& latest_response_body() const; | |
| 191 | |
| 192 protected: | |
| 193 virtual QuicConnectionId GenerateConnectionId(); | |
| 194 virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper(); | |
| 195 virtual QuicPacketWriter* CreateQuicPacketWriter(); | |
| 196 | |
| 197 virtual int ReadPacket(char* buffer, | |
| 198 int buffer_len, | |
| 199 IPEndPoint* server_address, | |
| 200 IPAddressNumber* client_ip); | |
| 201 | |
| 202 EpollServer* epoll_server() { return epoll_server_; } | |
| 203 | |
| 204 private: | |
| 205 friend class net::tools::test::QuicClientPeer; | |
| 206 | |
| 207 // A packet writer factory that always returns the same writer | |
| 208 class DummyPacketWriterFactory : public QuicConnection::PacketWriterFactory { | |
| 209 public: | |
| 210 DummyPacketWriterFactory(QuicPacketWriter* writer); | |
| 211 ~DummyPacketWriterFactory() override; | |
| 212 | |
| 213 QuicPacketWriter* Create(QuicConnection* connection) const override; | |
| 214 | |
| 215 private: | |
| 216 QuicPacketWriter* writer_; | |
| 217 }; | |
| 218 | |
| 219 // Used during initialization: creates the UDP socket FD, sets socket options, | |
| 220 // and binds the socket to our address. | |
| 221 bool CreateUDPSocket(); | |
| 222 | |
| 223 // If the socket has been created, then unregister and close() the FD. | |
| 224 void CleanUpUDPSocket(); | |
| 225 | |
| 226 // Read a UDP packet and hand it to the framer. | |
| 227 bool ReadAndProcessPacket(); | |
| 228 | |
| 229 // Address of the server. | |
| 230 const IPEndPoint server_address_; | |
| 231 | |
| 232 // |server_id_| is a tuple (hostname, port, is_https) of the server. | |
| 233 QuicServerId server_id_; | |
| 234 | |
| 235 // config_ and crypto_config_ contain configuration and cached state about | |
| 236 // servers. | |
| 237 QuicConfig config_; | |
| 238 QuicCryptoClientConfig crypto_config_; | |
| 239 | |
| 240 // Address of the client if the client is connected to the server. | |
| 241 IPEndPoint client_address_; | |
| 242 | |
| 243 // If initialized, the address to bind to. | |
| 244 IPAddressNumber bind_to_address_; | |
| 245 // Local port to bind to. Initialize to 0. | |
| 246 int local_port_; | |
| 247 | |
| 248 // Writer used to actually send packets to the wire. Needs to outlive | |
| 249 // |session_|. | |
| 250 scoped_ptr<QuicPacketWriter> writer_; | |
| 251 | |
| 252 // Session which manages streams. | |
| 253 scoped_ptr<QuicClientSession> session_; | |
| 254 // Listens for events on the client socket. | |
| 255 EpollServer* epoll_server_; | |
| 256 // UDP socket. | |
| 257 int fd_; | |
| 258 | |
| 259 // Helper to be used by created connections. | |
| 260 scoped_ptr<QuicEpollConnectionHelper> helper_; | |
| 261 | |
| 262 // Listens for full responses. | |
| 263 scoped_ptr<ResponseListener> response_listener_; | |
| 264 | |
| 265 // Tracks if the client is initialized to connect. | |
| 266 bool initialized_; | |
| 267 | |
| 268 // If overflow_supported_ is true, this will be the number of packets dropped | |
| 269 // during the lifetime of the server. | |
| 270 QuicPacketCount packets_dropped_; | |
| 271 | |
| 272 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped | |
| 273 // because the socket would otherwise overflow. | |
| 274 bool overflow_supported_; | |
| 275 | |
| 276 // This vector contains QUIC versions which we currently support. | |
| 277 // This should be ordered such that the highest supported version is the first | |
| 278 // element, with subsequent elements in descending order (versions can be | |
| 279 // skipped as necessary). We will always pick supported_versions_[0] as the | |
| 280 // initial version to use. | |
| 281 QuicVersionVector supported_versions_; | |
| 282 | |
| 283 // If true, store the latest response code, headers, and body. | |
| 284 bool store_response_; | |
| 285 // HTTP response code from most recent response. | |
| 286 size_t latest_response_code_; | |
| 287 // HTTP headers from most recent response. | |
| 288 std::string latest_response_headers_; | |
| 289 // Body of most recent response. | |
| 290 std::string latest_response_body_; | |
| 291 | |
| 292 DISALLOW_COPY_AND_ASSIGN(QuicClient); | |
| 293 }; | |
| 294 | |
| 295 } // namespace tools | |
| 296 } // namespace net | |
| 297 | |
| 298 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_ | |
| OLD | NEW |