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.
5 // A toy client, which connects to a specified port and sends QUIC
6 // request to that endpoint.
8 #ifndef NET_TOOLS_QUIC_QUIC_CLIENT_H_
9 #define NET_TOOLS_QUIC_QUIC_CLIENT_H_
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/quic_config.h"
19 #include "net/quic/quic_data_stream.h"
20 #include "net/tools/balsa/balsa_headers.h"
21 #include "net/tools/epoll_server/epoll_server.h"
22 #include "net/tools/quic/quic_client_base.h"
30 class QuicEpollConnectionHelper
;
36 class QuicClient
: public QuicClientBase
,
37 public EpollCallbackInterface
,
38 public QuicDataStream::Visitor
{
40 class ResponseListener
{
43 virtual ~ResponseListener() {}
44 virtual void OnCompleteResponse(QuicStreamId id
,
45 const BalsaHeaders
& response_headers
,
46 const std::string
& response_body
) = 0;
49 // The client uses these objects to keep track of any data to resend upon
50 // receipt of a stateless reject. Recall that the client API allows callers
51 // to optimistically send data to the server prior to handshake-confirmation.
52 // If the client subsequently receives a stateless reject, it must tear down
53 // its existing session, create a new session, and resend all previously sent
54 // data. It uses these objects to keep track of all the sent data, and to
55 // resend the data upon a subsequent connection.
56 class QuicDataToResend
{
58 // Takes ownership of |headers|. |headers| may be null, since it's possible
59 // to send data without headers.
60 QuicDataToResend(BalsaHeaders
* headers
, base::StringPiece body
, bool fin
);
62 virtual ~QuicDataToResend();
64 // Must be overridden by specific classes with the actual method for
66 virtual void Resend() = 0;
69 BalsaHeaders
* headers_
;
70 base::StringPiece body_
;
74 DISALLOW_COPY_AND_ASSIGN(QuicDataToResend
);
77 // Create a quic client, which will have events managed by an externally owned
79 QuicClient(IPEndPoint server_address
,
80 const QuicServerId
& server_id
,
81 const QuicVersionVector
& supported_versions
,
82 EpollServer
* epoll_server
);
83 QuicClient(IPEndPoint server_address
,
84 const QuicServerId
& server_id
,
85 const QuicVersionVector
& supported_versions
,
86 const QuicConfig
& config
,
87 EpollServer
* epoll_server
);
89 ~QuicClient() override
;
91 // From QuicClientBase
92 bool Initialize() override
;
93 bool WaitForEvents() override
;
95 // "Connect" to the QUIC server, including performing synchronous crypto
99 // Start the crypto handshake. This can be done in place of the synchronous
100 // Connect(), but callers are responsible for making sure the crypto handshake
104 // Disconnects from the QUIC server.
107 // Sends an HTTP request and does not wait for response before returning.
108 void SendRequest(const BalsaHeaders
& headers
,
109 base::StringPiece body
,
112 // Sends an HTTP request and waits for response before returning.
113 void SendRequestAndWaitForResponse(const BalsaHeaders
& headers
,
114 base::StringPiece body
,
117 // Sends a request simple GET for each URL in |args|, and then waits for
119 void SendRequestsAndWaitForResponse(
120 const std::vector
<std::string
>& url_list
);
122 // Migrate to a new socket during an active connection.
123 bool MigrateSocket(const IPAddressNumber
& new_host
);
125 // From EpollCallbackInterface
126 void OnRegistration(EpollServer
* eps
, int fd
, int event_mask
) override
{}
127 void OnModification(int fd
, int event_mask
) override
{}
128 void OnEvent(int fd
, EpollEvent
* event
) override
;
129 // |fd_| can be unregistered without the client being disconnected. This
130 // happens in b3m QuicProber where we unregister |fd_| to feed in events to
131 // the client from the SelectServer.
132 void OnUnregistration(int fd
, bool replaced
) override
{}
133 void OnShutdown(EpollServer
* eps
, int fd
) override
{}
135 // QuicDataStream::Visitor
136 void OnClose(QuicDataStream
* stream
) override
;
138 // If the crypto handshake has not yet been confirmed, adds the data to the
139 // queue of data to resend if the client receives a stateless reject.
140 // Otherwise, deletes the data. Takes ownerership of |data_to_resend|.
141 void MaybeAddQuicDataToResend(QuicDataToResend
* data_to_resend
);
143 void set_bind_to_address(IPAddressNumber address
) {
144 bind_to_address_
= address
;
147 IPAddressNumber
bind_to_address() const { return bind_to_address_
; }
149 void set_local_port(int local_port
) { local_port_
= local_port
; }
151 const IPEndPoint
& server_address() const { return server_address_
; }
153 const IPEndPoint
& client_address() const { return client_address_
; }
155 int fd() { return fd_
; }
157 // Takes ownership of the listener.
158 void set_response_listener(ResponseListener
* listener
) {
159 response_listener_
.reset(listener
);
162 void set_store_response(bool val
) { store_response_
= val
; }
164 size_t latest_response_code() const;
165 const std::string
& latest_response_headers() const;
166 const std::string
& latest_response_body() const;
169 virtual QuicEpollConnectionHelper
* CreateQuicConnectionHelper();
170 virtual QuicPacketWriter
* CreateQuicPacketWriter();
172 virtual int ReadPacket(char* buffer
,
174 IPEndPoint
* server_address
,
175 IPAddressNumber
* client_ip
);
177 EpollServer
* epoll_server() { return epoll_server_
; }
179 // If the socket has been created, then unregister and close() the FD.
180 virtual void CleanUpUDPSocket();
183 friend class net::tools::test::QuicClientPeer
;
185 // Specific QuicClient class for storing data to resend.
186 class ClientQuicDataToResend
: public QuicDataToResend
{
188 // Takes ownership of |headers|.
189 ClientQuicDataToResend(BalsaHeaders
* headers
,
190 base::StringPiece body
,
193 : QuicDataToResend(headers
, body
, fin
), client_(client
) {
198 ~ClientQuicDataToResend() override
{}
200 void Resend() override
;
205 DISALLOW_COPY_AND_ASSIGN(ClientQuicDataToResend
);
208 // Used during initialization: creates the UDP socket FD, sets socket options,
209 // and binds the socket to our address.
210 bool CreateUDPSocket();
212 // Actually clean up the socket.
213 void CleanUpUDPSocketImpl();
215 // Read a UDP packet and hand it to the framer.
216 bool ReadAndProcessPacket();
218 // Address of the server.
219 const IPEndPoint server_address_
;
221 // Address of the client if the client is connected to the server.
222 IPEndPoint client_address_
;
224 // If initialized, the address to bind to.
225 IPAddressNumber bind_to_address_
;
226 // Local port to bind to. Initialize to 0.
229 // Listens for events on the client socket.
230 EpollServer
* epoll_server_
;
234 // Helper to be used by created connections.
235 scoped_ptr
<QuicEpollConnectionHelper
> helper_
;
237 // Listens for full responses.
238 scoped_ptr
<ResponseListener
> response_listener_
;
240 // Tracks if the client is initialized to connect.
243 // If overflow_supported_ is true, this will be the number of packets dropped
244 // during the lifetime of the server.
245 QuicPacketCount packets_dropped_
;
247 // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
248 // because the socket would otherwise overflow.
249 bool overflow_supported_
;
251 // If true, store the latest response code, headers, and body.
252 bool store_response_
;
253 // HTTP response code from most recent response.
254 size_t latest_response_code_
;
255 // HTTP headers from most recent response.
256 std::string latest_response_headers_
;
257 // Body of most recent response.
258 std::string latest_response_body_
;
260 // Keeps track of any data sent before the handshake.
261 std::vector
<QuicDataToResend
*> data_sent_before_handshake_
;
263 // Once the client receives a stateless reject, keeps track of any data that
264 // must be resent upon a subsequent successful connection.
265 std::vector
<QuicDataToResend
*> data_to_resend_on_connect_
;
267 DISALLOW_COPY_AND_ASSIGN(QuicClient
);
273 #endif // NET_TOOLS_QUIC_QUIC_CLIENT_H_