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