Home | History | Annotate | Download | only in quic
      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 
     25 namespace net {
     26 
     27 class ProofVerifier;
     28 
     29 namespace tools {
     30 
     31 class QuicEpollConnectionHelper;
     32 
     33 namespace test {
     34 class QuicClientPeer;
     35 }  // namespace test
     36 
     37 class 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