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/command_line.h"
14#include "base/containers/hash_tables.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/flip_server/epoll_server.h"
22#include "net/tools/quic/quic_client_session.h"
23#include "net/tools/quic/quic_reliable_client_stream.h"
24
25namespace net {
26
27class ProofVerifier;
28
29namespace tools {
30
31class QuicEpollConnectionHelper;
32
33namespace test {
34class QuicClientPeer;
35}  // namespace test
36
37class QuicClient : public EpollCallbackInterface {
38 public:
39  QuicClient(IPEndPoint server_address, const std::string& server_hostname,
40             const QuicVersion version);
41  QuicClient(IPEndPoint server_address,
42             const std::string& server_hostname,
43             const QuicConfig& config,
44             const QuicVersion version);
45
46  virtual ~QuicClient();
47
48  // Initializes the client to create a connection. Should be called exactly
49  // once before calling StartConnect or Connect. Returns true if the
50  // initialization succeeds, false otherwise.
51  bool Initialize();
52
53  // "Connect" to the QUIC server, including performing synchronous crypto
54  // handshake.
55  bool Connect();
56
57  // Start the crypto handshake.  This can be done in place of the synchronous
58  // Connect(), but callers are responsible for making sure the crypto handshake
59  // completes.
60  bool StartConnect();
61
62  // Returns true if the crypto handshake has yet to establish encryption.
63  // Returns false if encryption is active (even if the server hasn't confirmed
64  // the handshake) or if the connection has been closed.
65  bool EncryptionBeingEstablished();
66
67  // Disconnects from the QUIC server.
68  void Disconnect();
69
70  // Sends a request simple GET for each URL in arg, and then waits for
71  // each to complete.
72  void SendRequestsAndWaitForResponse(const CommandLine::StringVector& args);
73
74  // Returns a newly created CreateReliableClientStream, owned by the
75  // QuicClient.
76  QuicReliableClientStream* CreateReliableClientStream();
77
78  // Wait for events until the stream with the given ID is closed.
79  void WaitForStreamToClose(QuicStreamId id);
80
81  // Wait for events until the handshake is confirmed.
82  void WaitForCryptoHandshakeConfirmed();
83
84  // Wait up to 50ms, and handle any events which occur.
85  // Returns true if there are any outstanding requests.
86  bool WaitForEvents();
87
88  // From EpollCallbackInterface
89  virtual void OnRegistration(
90      EpollServer* eps, int fd, int event_mask) OVERRIDE {}
91  virtual void OnModification(int fd, int event_mask) OVERRIDE {}
92  virtual void OnEvent(int fd, EpollEvent* event) OVERRIDE;
93  // |fd_| can be unregistered without the client being disconnected. This
94  // happens in b3m QuicProber where we unregister |fd_| to feed in events to
95  // the client from the SelectServer.
96  virtual void OnUnregistration(int fd, bool replaced) OVERRIDE {}
97  virtual void OnShutdown(EpollServer* eps, int fd) OVERRIDE {}
98
99  QuicPacketCreator::Options* options();
100
101  QuicClientSession* session() { return session_.get(); }
102
103  bool connected() const;
104
105  int packets_dropped() { return packets_dropped_; }
106
107  void set_bind_to_address(IPAddressNumber address) {
108    bind_to_address_ = address;
109  }
110
111  IPAddressNumber bind_to_address() const { return bind_to_address_; }
112
113  void set_local_port(int local_port) { local_port_ = local_port; }
114
115  int local_port() { return local_port_; }
116
117  const IPEndPoint& server_address() const { return server_address_; }
118
119  const IPEndPoint& client_address() const { return client_address_; }
120
121  EpollServer* epoll_server() { return &epoll_server_; }
122
123  int fd() { return fd_; }
124
125  // This should only be set before the initial Connect()
126  void set_server_hostname(const string& hostname) {
127    server_hostname_ = hostname;
128  }
129
130  // SetProofVerifier sets the ProofVerifier that will be used to verify the
131  // server's certificate and takes ownership of |verifier|.
132  void SetProofVerifier(ProofVerifier* verifier) {
133    // TODO(rtenneti): We should set ProofVerifier in QuicClientSession.
134    crypto_config_.SetProofVerifier(verifier);
135  }
136
137  // SetChannelIDSigner sets a ChannelIDSigner that will be called when the
138  // server supports channel IDs to sign a message proving possession of the
139  // given ChannelID. This object takes ownership of |signer|.
140  void SetChannelIDSigner(ChannelIDSigner* signer) {
141    crypto_config_.SetChannelIDSigner(signer);
142  }
143
144 protected:
145  virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper();
146
147 private:
148  friend class net::tools::test::QuicClientPeer;
149
150  // Read a UDP packet and hand it to the framer.
151  bool ReadAndProcessPacket();
152
153  // Set of streams created (and owned) by this client
154  base::hash_set<QuicReliableClientStream*> streams_;
155
156  // Address of the server.
157  const IPEndPoint server_address_;
158
159  // Hostname of the server. This may be a DNS name or an IP address literal.
160  std::string server_hostname_;
161
162  // config_ and crypto_config_ contain configuration and cached state about
163  // servers.
164  QuicConfig config_;
165  QuicCryptoClientConfig crypto_config_;
166
167  // Address of the client if the client is connected to the server.
168  IPEndPoint client_address_;
169
170  // If initialized, the address to bind to.
171  IPAddressNumber bind_to_address_;
172  // Local port to bind to. Initialize to 0.
173  int local_port_;
174
175  // Session which manages streams.
176  scoped_ptr<QuicClientSession> session_;
177  // Listens for events on the client socket.
178  EpollServer epoll_server_;
179  // UDP socket.
180  int fd_;
181
182  // Tracks if the client is initialized to connect.
183  bool initialized_;
184
185  // If overflow_supported_ is true, this will be the number of packets dropped
186  // during the lifetime of the server.  This may overflow if enough packets
187  // are dropped.
188  int packets_dropped_;
189
190  // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
191  // because the socket would otherwise overflow.
192  bool overflow_supported_;
193
194  // Which QUIC version does this client talk?
195  QuicVersion version_;
196
197  DISALLOW_COPY_AND_ASSIGN(QuicClient);
198};
199
200}  // namespace tools
201}  // namespace net
202
203#endif  // NET_TOOLS_QUIC_QUIC_CLIENT_H_
204