OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // A toy client, which connects to a specified port and sends QUIC | 5 // A toy client, which connects to a specified port and sends QUIC |
6 // request to that endpoint. | 6 // request to that endpoint. |
7 | 7 |
8 #ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_ | 8 #ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_ |
9 #define NET_TOOLS_QUIC_QUIC_CLIENT_H_ | 9 #define NET_TOOLS_QUIC_QUIC_CLIENT_H_ |
10 | 10 |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
15 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
16 #include "base/strings/string_piece.h" | 16 #include "base/strings/string_piece.h" |
17 #include "net/base/ip_endpoint.h" | 17 #include "net/base/ip_endpoint.h" |
18 #include "net/quic/crypto/crypto_handshake.h" | |
19 #include "net/quic/quic_config.h" | 18 #include "net/quic/quic_config.h" |
20 #include "net/quic/quic_framer.h" | 19 #include "net/quic/quic_data_stream.h" |
21 #include "net/quic/quic_packet_creator.h" | |
22 #include "net/tools/balsa/balsa_headers.h" | 20 #include "net/tools/balsa/balsa_headers.h" |
23 #include "net/tools/epoll_server/epoll_server.h" | 21 #include "net/tools/epoll_server/epoll_server.h" |
24 #include "net/tools/quic/quic_client_session.h" | 22 #include "net/tools/quic/quic_client_base.h" |
25 #include "net/tools/quic/quic_spdy_client_stream.h" | |
26 | 23 |
27 namespace net { | 24 namespace net { |
28 | 25 |
29 class ProofVerifier; | |
30 class QuicServerId; | 26 class QuicServerId; |
31 | 27 |
32 namespace tools { | 28 namespace tools { |
33 | 29 |
34 class QuicEpollConnectionHelper; | 30 class QuicEpollConnectionHelper; |
35 | 31 |
36 namespace test { | 32 namespace test { |
37 class QuicClientPeer; | 33 class QuicClientPeer; |
38 } // namespace test | 34 } // namespace test |
39 | 35 |
40 class QuicClient : public EpollCallbackInterface, | 36 class QuicClient : public QuicClientBase, |
| 37 public EpollCallbackInterface, |
41 public QuicDataStream::Visitor { | 38 public QuicDataStream::Visitor { |
42 public: | 39 public: |
43 class ResponseListener { | 40 class ResponseListener { |
44 public: | 41 public: |
45 ResponseListener() {} | 42 ResponseListener() {} |
46 virtual ~ResponseListener() {} | 43 virtual ~ResponseListener() {} |
47 virtual void OnCompleteResponse(QuicStreamId id, | 44 virtual void OnCompleteResponse(QuicStreamId id, |
48 const BalsaHeaders& response_headers, | 45 const BalsaHeaders& response_headers, |
49 const std::string& response_body) = 0; | 46 const std::string& response_body) = 0; |
50 }; | 47 }; |
51 | 48 |
52 // A packet writer factory that always returns the same writer. | |
53 class DummyPacketWriterFactory : public QuicConnection::PacketWriterFactory { | |
54 public: | |
55 explicit DummyPacketWriterFactory(QuicPacketWriter* writer); | |
56 ~DummyPacketWriterFactory() override; | |
57 | |
58 QuicPacketWriter* Create(QuicConnection* connection) const override; | |
59 | |
60 private: | |
61 QuicPacketWriter* writer_; | |
62 }; | |
63 | |
64 // The client uses these objects to keep track of any data to resend upon | 49 // The client uses these objects to keep track of any data to resend upon |
65 // receipt of a stateless reject. Recall that the client API allows callers | 50 // receipt of a stateless reject. Recall that the client API allows callers |
66 // to optimistically send data to the server prior to handshake-confirmation. | 51 // to optimistically send data to the server prior to handshake-confirmation. |
67 // If the client subsequently receives a stateless reject, it must tear down | 52 // If the client subsequently receives a stateless reject, it must tear down |
68 // its existing session, create a new session, and resend all previously sent | 53 // its existing session, create a new session, and resend all previously sent |
69 // data. It uses these objects to keep track of all the sent data, and to | 54 // data. It uses these objects to keep track of all the sent data, and to |
70 // resend the data upon a subsequent connection. | 55 // resend the data upon a subsequent connection. |
71 class QuicDataToResend { | 56 class QuicDataToResend { |
72 public: | 57 public: |
73 // Takes ownership of |headers|. |headers| may be null, since it's possible | 58 // Takes ownership of |headers|. |headers| may be null, since it's possible |
(...skipping 22 matching lines...) Expand all Loading... |
96 const QuicVersionVector& supported_versions, | 81 const QuicVersionVector& supported_versions, |
97 EpollServer* epoll_server); | 82 EpollServer* epoll_server); |
98 QuicClient(IPEndPoint server_address, | 83 QuicClient(IPEndPoint server_address, |
99 const QuicServerId& server_id, | 84 const QuicServerId& server_id, |
100 const QuicVersionVector& supported_versions, | 85 const QuicVersionVector& supported_versions, |
101 const QuicConfig& config, | 86 const QuicConfig& config, |
102 EpollServer* epoll_server); | 87 EpollServer* epoll_server); |
103 | 88 |
104 ~QuicClient() override; | 89 ~QuicClient() override; |
105 | 90 |
106 // Initializes the client to create a connection. Should be called exactly | 91 // From QuicClientBase |
107 // once before calling StartConnect or Connect. Returns true if the | 92 bool Initialize() override; |
108 // initialization succeeds, false otherwise. | 93 bool WaitForEvents() override; |
109 bool Initialize(); | |
110 | 94 |
111 // "Connect" to the QUIC server, including performing synchronous crypto | 95 // "Connect" to the QUIC server, including performing synchronous crypto |
112 // handshake. | 96 // handshake. |
113 bool Connect(); | 97 bool Connect(); |
114 | 98 |
115 // Start the crypto handshake. This can be done in place of the synchronous | 99 // Start the crypto handshake. This can be done in place of the synchronous |
116 // Connect(), but callers are responsible for making sure the crypto handshake | 100 // Connect(), but callers are responsible for making sure the crypto handshake |
117 // completes. | 101 // completes. |
118 void StartConnect(); | 102 void StartConnect(); |
119 | 103 |
120 // Returns true if the crypto handshake has yet to establish encryption. | |
121 // Returns false if encryption is active (even if the server hasn't confirmed | |
122 // the handshake) or if the connection has been closed. | |
123 bool EncryptionBeingEstablished(); | |
124 | |
125 // Disconnects from the QUIC server. | 104 // Disconnects from the QUIC server. |
126 void Disconnect(); | 105 void Disconnect(); |
127 | 106 |
128 // Sends an HTTP request and does not wait for response before returning. | 107 // Sends an HTTP request and does not wait for response before returning. |
129 void SendRequest(const BalsaHeaders& headers, | 108 void SendRequest(const BalsaHeaders& headers, |
130 base::StringPiece body, | 109 base::StringPiece body, |
131 bool fin); | 110 bool fin); |
132 | 111 |
133 // Sends an HTTP request and waits for response before returning. | 112 // Sends an HTTP request and waits for response before returning. |
134 void SendRequestAndWaitForResponse(const BalsaHeaders& headers, | 113 void SendRequestAndWaitForResponse(const BalsaHeaders& headers, |
135 base::StringPiece body, | 114 base::StringPiece body, |
136 bool fin); | 115 bool fin); |
137 | 116 |
138 // Sends a request simple GET for each URL in |args|, and then waits for | 117 // Sends a request simple GET for each URL in |args|, and then waits for |
139 // each to complete. | 118 // each to complete. |
140 void SendRequestsAndWaitForResponse( | 119 void SendRequestsAndWaitForResponse( |
141 const std::vector<std::string>& url_list); | 120 const std::vector<std::string>& url_list); |
142 | 121 |
143 // Returns a newly created QuicSpdyClientStream, owned by the | |
144 // QuicClient. | |
145 QuicSpdyClientStream* CreateReliableClientStream(); | |
146 | |
147 // Wait for events until the stream with the given ID is closed. | |
148 void WaitForStreamToClose(QuicStreamId id); | |
149 | |
150 // Wait for events until the handshake is confirmed. | |
151 void WaitForCryptoHandshakeConfirmed(); | |
152 | |
153 // Wait up to 50ms, and handle any events which occur. | |
154 // Returns true if there are any outstanding requests. | |
155 bool WaitForEvents(); | |
156 | |
157 // Migrate to a new socket during an active connection. | 122 // Migrate to a new socket during an active connection. |
158 bool MigrateSocket(const IPAddressNumber& new_host); | 123 bool MigrateSocket(const IPAddressNumber& new_host); |
159 | 124 |
160 // From EpollCallbackInterface | 125 // From EpollCallbackInterface |
161 void OnRegistration(EpollServer* eps, int fd, int event_mask) override {} | 126 void OnRegistration(EpollServer* eps, int fd, int event_mask) override {} |
162 void OnModification(int fd, int event_mask) override {} | 127 void OnModification(int fd, int event_mask) override {} |
163 void OnEvent(int fd, EpollEvent* event) override; | 128 void OnEvent(int fd, EpollEvent* event) override; |
164 // |fd_| can be unregistered without the client being disconnected. This | 129 // |fd_| can be unregistered without the client being disconnected. This |
165 // happens in b3m QuicProber where we unregister |fd_| to feed in events to | 130 // happens in b3m QuicProber where we unregister |fd_| to feed in events to |
166 // the client from the SelectServer. | 131 // the client from the SelectServer. |
167 void OnUnregistration(int fd, bool replaced) override {} | 132 void OnUnregistration(int fd, bool replaced) override {} |
168 void OnShutdown(EpollServer* eps, int fd) override {} | 133 void OnShutdown(EpollServer* eps, int fd) override {} |
169 | 134 |
170 // QuicDataStream::Visitor | 135 // QuicDataStream::Visitor |
171 void OnClose(QuicDataStream* stream) override; | 136 void OnClose(QuicDataStream* stream) override; |
172 | 137 |
173 // If the crypto handshake has not yet been confirmed, adds the data to the | 138 // If the crypto handshake has not yet been confirmed, adds the data to the |
174 // queue of data to resend if the client receives a stateless reject. | 139 // queue of data to resend if the client receives a stateless reject. |
175 // Otherwise, deletes the data. Takes ownerership of |data_to_resend|. | 140 // Otherwise, deletes the data. Takes ownerership of |data_to_resend|. |
176 void MaybeAddQuicDataToResend(QuicDataToResend* data_to_resend); | 141 void MaybeAddQuicDataToResend(QuicDataToResend* data_to_resend); |
177 | 142 |
178 QuicClientSession* session() { return session_.get(); } | |
179 | |
180 bool connected() const; | |
181 bool goaway_received() const; | |
182 | |
183 void set_bind_to_address(IPAddressNumber address) { | 143 void set_bind_to_address(IPAddressNumber address) { |
184 bind_to_address_ = address; | 144 bind_to_address_ = address; |
185 } | 145 } |
186 | 146 |
187 IPAddressNumber bind_to_address() const { return bind_to_address_; } | 147 IPAddressNumber bind_to_address() const { return bind_to_address_; } |
188 | 148 |
189 void set_local_port(int local_port) { local_port_ = local_port; } | 149 void set_local_port(int local_port) { local_port_ = local_port; } |
190 | 150 |
191 const IPEndPoint& server_address() const { return server_address_; } | 151 const IPEndPoint& server_address() const { return server_address_; } |
192 | 152 |
193 const IPEndPoint& client_address() const { return client_address_; } | 153 const IPEndPoint& client_address() const { return client_address_; } |
194 | 154 |
195 int fd() { return fd_; } | 155 int fd() { return fd_; } |
196 | 156 |
197 const QuicServerId& server_id() const { return server_id_; } | |
198 | |
199 // This should only be set before the initial Connect() | |
200 void set_server_id(const QuicServerId& server_id) { | |
201 server_id_ = server_id; | |
202 } | |
203 | |
204 void SetUserAgentID(const std::string& user_agent_id) { | |
205 crypto_config_.set_user_agent_id(user_agent_id); | |
206 } | |
207 | |
208 // SetProofVerifier sets the ProofVerifier that will be used to verify the | |
209 // server's certificate and takes ownership of |verifier|. | |
210 void SetProofVerifier(ProofVerifier* verifier) { | |
211 // TODO(rtenneti): We should set ProofVerifier in QuicClientSession. | |
212 crypto_config_.SetProofVerifier(verifier); | |
213 } | |
214 | |
215 // SetChannelIDSource sets a ChannelIDSource that will be called, when the | |
216 // server supports channel IDs, to obtain a channel ID for signing a message | |
217 // proving possession of the channel ID. This object takes ownership of | |
218 // |source|. | |
219 void SetChannelIDSource(ChannelIDSource* source) { | |
220 crypto_config_.SetChannelIDSource(source); | |
221 } | |
222 | |
223 void SetSupportedVersions(const QuicVersionVector& versions) { | |
224 supported_versions_ = versions; | |
225 } | |
226 | |
227 // Takes ownership of the listener. | 157 // Takes ownership of the listener. |
228 void set_response_listener(ResponseListener* listener) { | 158 void set_response_listener(ResponseListener* listener) { |
229 response_listener_.reset(listener); | 159 response_listener_.reset(listener); |
230 } | 160 } |
231 | 161 |
232 QuicConfig* config() { return &config_; } | |
233 | |
234 void set_store_response(bool val) { store_response_ = val; } | 162 void set_store_response(bool val) { store_response_ = val; } |
235 | 163 |
236 size_t latest_response_code() const; | 164 size_t latest_response_code() const; |
237 const std::string& latest_response_headers() const; | 165 const std::string& latest_response_headers() const; |
238 const std::string& latest_response_body() const; | 166 const std::string& latest_response_body() const; |
239 | 167 |
240 // Change the initial maximum packet size of the connection. Has to be called | |
241 // before Connect()/StartConnect() in order to have any effect. | |
242 void set_initial_max_packet_length(QuicByteCount initial_max_packet_length) { | |
243 initial_max_packet_length_ = initial_max_packet_length; | |
244 } | |
245 | |
246 int num_stateless_rejects_received() const { | |
247 return num_stateless_rejects_received_; | |
248 } | |
249 | |
250 // The number of client hellos sent, taking stateless rejects into | |
251 // account. In the case of a stateless reject, the initial | |
252 // connection object may be torn down and a new one created. The | |
253 // user cannot rely upon the latest connection object to get the | |
254 // total number of client hellos sent, and should use this function | |
255 // instead. | |
256 int GetNumSentClientHellos(); | |
257 | |
258 // Returns any errors that occurred at the connection-level (as | |
259 // opposed to the session-level). When a stateless reject occurs, | |
260 // the error of the last session may not reflect the overall state | |
261 // of the connection. | |
262 QuicErrorCode connection_error() const; | |
263 | |
264 protected: | 168 protected: |
265 // Generates the next ConnectionId for |server_id_|. By default, if the | |
266 // cached server config contains a server-designated ID, that ID will be | |
267 // returned. Otherwise, the next random ID will be returned. | |
268 QuicConnectionId GetNextConnectionId(); | |
269 | |
270 // Returns the next server-designated ConnectionId from the cached config for | |
271 // |server_id_|, if it exists. Otherwise, returns 0. | |
272 QuicConnectionId GetNextServerDesignatedConnectionId(); | |
273 | |
274 // Generates a new, random connection ID (as opposed to a server-designated | |
275 // connection ID). | |
276 virtual QuicConnectionId GenerateNewConnectionId(); | |
277 | |
278 virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper(); | 169 virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper(); |
279 virtual QuicPacketWriter* CreateQuicPacketWriter(); | 170 virtual QuicPacketWriter* CreateQuicPacketWriter(); |
280 | 171 |
281 virtual int ReadPacket(char* buffer, | 172 virtual int ReadPacket(char* buffer, |
282 int buffer_len, | 173 int buffer_len, |
283 IPEndPoint* server_address, | 174 IPEndPoint* server_address, |
284 IPAddressNumber* client_ip); | 175 IPAddressNumber* client_ip); |
285 | 176 |
286 virtual QuicClientSession* CreateQuicClientSession( | |
287 const QuicConfig& config, | |
288 QuicConnection* connection, | |
289 const QuicServerId& server_id, | |
290 QuicCryptoClientConfig* crypto_config); | |
291 | |
292 EpollServer* epoll_server() { return epoll_server_; } | 177 EpollServer* epoll_server() { return epoll_server_; } |
293 | 178 |
294 // If the socket has been created, then unregister and close() the FD. | 179 // If the socket has been created, then unregister and close() the FD. |
295 virtual void CleanUpUDPSocket(); | 180 virtual void CleanUpUDPSocket(); |
296 | 181 |
297 private: | 182 private: |
298 friend class net::tools::test::QuicClientPeer; | 183 friend class net::tools::test::QuicClientPeer; |
299 | 184 |
300 // Specific QuicClient class for storing data to resend. | 185 // Specific QuicClient class for storing data to resend. |
301 class ClientQuicDataToResend : public QuicDataToResend { | 186 class ClientQuicDataToResend : public QuicDataToResend { |
(...skipping 24 matching lines...) Expand all Loading... |
326 | 211 |
327 // Actually clean up the socket. | 212 // Actually clean up the socket. |
328 void CleanUpUDPSocketImpl(); | 213 void CleanUpUDPSocketImpl(); |
329 | 214 |
330 // Read a UDP packet and hand it to the framer. | 215 // Read a UDP packet and hand it to the framer. |
331 bool ReadAndProcessPacket(); | 216 bool ReadAndProcessPacket(); |
332 | 217 |
333 // Address of the server. | 218 // Address of the server. |
334 const IPEndPoint server_address_; | 219 const IPEndPoint server_address_; |
335 | 220 |
336 // |server_id_| is a tuple (hostname, port, is_https) of the server. | |
337 QuicServerId server_id_; | |
338 | |
339 // config_ and crypto_config_ contain configuration and cached state about | |
340 // servers. | |
341 QuicConfig config_; | |
342 QuicCryptoClientConfig crypto_config_; | |
343 | |
344 // Address of the client if the client is connected to the server. | 221 // Address of the client if the client is connected to the server. |
345 IPEndPoint client_address_; | 222 IPEndPoint client_address_; |
346 | 223 |
347 // If initialized, the address to bind to. | 224 // If initialized, the address to bind to. |
348 IPAddressNumber bind_to_address_; | 225 IPAddressNumber bind_to_address_; |
349 // Local port to bind to. Initialize to 0. | 226 // Local port to bind to. Initialize to 0. |
350 int local_port_; | 227 int local_port_; |
351 | 228 |
352 // Writer used to actually send packets to the wire. Needs to outlive | |
353 // |session_|. | |
354 scoped_ptr<QuicPacketWriter> writer_; | |
355 | |
356 // Session which manages streams. | |
357 scoped_ptr<QuicClientSession> session_; | |
358 // Listens for events on the client socket. | 229 // Listens for events on the client socket. |
359 EpollServer* epoll_server_; | 230 EpollServer* epoll_server_; |
360 // UDP socket. | 231 // UDP socket. |
361 int fd_; | 232 int fd_; |
362 | 233 |
363 // Helper to be used by created connections. | 234 // Helper to be used by created connections. |
364 scoped_ptr<QuicEpollConnectionHelper> helper_; | 235 scoped_ptr<QuicEpollConnectionHelper> helper_; |
365 | 236 |
366 // Listens for full responses. | 237 // Listens for full responses. |
367 scoped_ptr<ResponseListener> response_listener_; | 238 scoped_ptr<ResponseListener> response_listener_; |
368 | 239 |
369 // Tracks if the client is initialized to connect. | 240 // Tracks if the client is initialized to connect. |
370 bool initialized_; | 241 bool initialized_; |
371 | 242 |
372 // If overflow_supported_ is true, this will be the number of packets dropped | 243 // If overflow_supported_ is true, this will be the number of packets dropped |
373 // during the lifetime of the server. | 244 // during the lifetime of the server. |
374 QuicPacketCount packets_dropped_; | 245 QuicPacketCount packets_dropped_; |
375 | 246 |
376 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped | 247 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped |
377 // because the socket would otherwise overflow. | 248 // because the socket would otherwise overflow. |
378 bool overflow_supported_; | 249 bool overflow_supported_; |
379 | 250 |
380 // This vector contains QUIC versions which we currently support. | |
381 // This should be ordered such that the highest supported version is the first | |
382 // element, with subsequent elements in descending order (versions can be | |
383 // skipped as necessary). We will always pick supported_versions_[0] as the | |
384 // initial version to use. | |
385 QuicVersionVector supported_versions_; | |
386 | |
387 // If true, store the latest response code, headers, and body. | 251 // If true, store the latest response code, headers, and body. |
388 bool store_response_; | 252 bool store_response_; |
389 // HTTP response code from most recent response. | 253 // HTTP response code from most recent response. |
390 size_t latest_response_code_; | 254 size_t latest_response_code_; |
391 // HTTP headers from most recent response. | 255 // HTTP headers from most recent response. |
392 std::string latest_response_headers_; | 256 std::string latest_response_headers_; |
393 // Body of most recent response. | 257 // Body of most recent response. |
394 std::string latest_response_body_; | 258 std::string latest_response_body_; |
395 | 259 |
396 // The initial value of maximum packet size of the connection. If set to | |
397 // zero, the default is used. | |
398 QuicByteCount initial_max_packet_length_; | |
399 | |
400 // The number of stateless rejects received during the current/latest | |
401 // connection. | |
402 // TODO(jokulik): Consider some consistent naming scheme (or other) for member | |
403 // variables that are kept per-request, per-connection, and over the client's | |
404 // lifetime. | |
405 int num_stateless_rejects_received_; | |
406 | |
407 // The number of hellos sent during the current/latest connection. | |
408 int num_sent_client_hellos_; | |
409 | |
410 // Used to store any errors that occurred with the overall connection (as | |
411 // opposed to that associated with the last session object). | |
412 QuicErrorCode connection_error_; | |
413 | |
414 // True when the client is attempting to connect or re-connect the session (in | |
415 // the case of a stateless reject). Set to false between a call to | |
416 // Disconnect() and the subsequent call to StartConnect(). When | |
417 // connected_or_attempting_connect_ is false, the session object corresponds | |
418 // to the previous client-level connection. | |
419 bool connected_or_attempting_connect_; | |
420 | |
421 // Keeps track of any data sent before the handshake. | 260 // Keeps track of any data sent before the handshake. |
422 std::vector<QuicDataToResend*> data_sent_before_handshake_; | 261 std::vector<QuicDataToResend*> data_sent_before_handshake_; |
423 | 262 |
424 // Once the client receives a stateless reject, keeps track of any data that | 263 // Once the client receives a stateless reject, keeps track of any data that |
425 // must be resent upon a subsequent successful connection. | 264 // must be resent upon a subsequent successful connection. |
426 std::vector<QuicDataToResend*> data_to_resend_on_connect_; | 265 std::vector<QuicDataToResend*> data_to_resend_on_connect_; |
427 | 266 |
428 DISALLOW_COPY_AND_ASSIGN(QuicClient); | 267 DISALLOW_COPY_AND_ASSIGN(QuicClient); |
429 }; | 268 }; |
430 | 269 |
431 } // namespace tools | 270 } // namespace tools |
432 } // namespace net | 271 } // namespace net |
433 | 272 |
434 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_ | 273 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_ |
OLD | NEW |