• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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