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 // An implementation of the QuicClientBase::NetworkHelper
6 // that is based off the epoll server.
7 
8 #ifndef QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
9 #define QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
10 
11 #include <cstdint>
12 #include <memory>
13 #include <string>
14 
15 #include "net/third_party/quiche/src/quic/core/http/quic_client_push_promise_index.h"
16 #include "net/third_party/quiche/src/quic/core/quic_config.h"
17 #include "net/third_party/quiche/src/quic/core/quic_packet_reader.h"
18 #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h"
19 #include "net/third_party/quiche/src/quic/platform/api/quic_epoll.h"
20 #include "net/third_party/quiche/src/quic/tools/quic_client_base.h"
21 
22 namespace quic {
23 
24 namespace test {
25 class QuicClientPeer;
26 }  // namespace test
27 
28 // An implementation of the QuicClientBase::NetworkHelper based off
29 // the epoll server.
30 class QuicClientEpollNetworkHelper : public QuicClientBase::NetworkHelper,
31                                      public QuicEpollCallbackInterface,
32                                      public ProcessPacketInterface {
33  public:
34   // Create a quic client, which will have events managed by an externally owned
35   // EpollServer.
36   QuicClientEpollNetworkHelper(QuicEpollServer* epoll_server,
37                                QuicClientBase* client);
38   QuicClientEpollNetworkHelper(const QuicClientEpollNetworkHelper&) = delete;
39   QuicClientEpollNetworkHelper& operator=(const QuicClientEpollNetworkHelper&) =
40       delete;
41 
42   ~QuicClientEpollNetworkHelper() override;
43 
44   // Return a name describing the class for use in debug/error reporting.
45   std::string Name() const override;
46 
47   // From EpollCallbackInterface
48   void OnRegistration(QuicEpollServer* eps, int fd, int event_mask) override;
49   void OnModification(int fd, int event_mask) override;
50   void OnEvent(int fd, QuicEpollEvent* event) override;
51   // |fd_| can be unregistered without the client being disconnected. This
52   // happens in b3m QuicProber where we unregister |fd_| to feed in events to
53   // the client from the SelectServer.
54   void OnUnregistration(int fd, bool replaced) override;
55   void OnShutdown(QuicEpollServer* eps, int fd) override;
56 
57   // From ProcessPacketInterface. This will be called for each received
58   // packet.
59   void ProcessPacket(const QuicSocketAddress& self_address,
60                      const QuicSocketAddress& peer_address,
61                      const QuicReceivedPacket& packet) override;
62 
63   // From NetworkHelper.
64   void RunEventLoop() override;
65   bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
66                               QuicIpAddress bind_to_address,
67                               int bind_to_port) override;
68   void CleanUpAllUDPSockets() override;
69   QuicSocketAddress GetLatestClientAddress() const override;
70   QuicPacketWriter* CreateQuicPacketWriter() override;
71 
72   // Accessors provided for convenience, not part of any interface.
73 
epoll_server()74   QuicEpollServer* epoll_server() { return epoll_server_; }
75 
fd_address_map()76   const QuicLinkedHashMap<int, QuicSocketAddress>& fd_address_map() const {
77     return fd_address_map_;
78   }
79 
80   // If the client has at least one UDP socket, return the latest created one.
81   // Otherwise, return -1.
82   int GetLatestFD() const;
83 
84   // Create socket for connection to |server_address| with default socket
85   // options.
86   // Return fd index.
87   virtual int CreateUDPSocket(QuicSocketAddress server_address,
88                               bool* overflow_supported);
89 
client()90   QuicClientBase* client() { return client_; }
91 
set_max_reads_per_epoll_loop(int num_reads)92   void set_max_reads_per_epoll_loop(int num_reads) {
93     max_reads_per_epoll_loop_ = num_reads;
94   }
95   // If |fd| is an open UDP socket, unregister and close it. Otherwise, do
96   // nothing.
97   void CleanUpUDPSocket(int fd);
98 
99  private:
100   friend class test::QuicClientPeer;
101 
102   // Used for testing.
103   void SetClientPort(int port);
104 
105   // Actually clean up |fd|.
106   void CleanUpUDPSocketImpl(int fd);
107 
108   // Listens for events on the client socket.
109   QuicEpollServer* epoll_server_;
110 
111   // Map mapping created UDP sockets to their addresses. By using linked hash
112   // map, the order of socket creation can be recorded.
113   QuicLinkedHashMap<int, QuicSocketAddress> fd_address_map_;
114 
115   // If overflow_supported_ is true, this will be the number of packets dropped
116   // during the lifetime of the server.
117   QuicPacketCount packets_dropped_;
118 
119   // True if the kernel supports SO_RXQ_OVFL, the number of packets dropped
120   // because the socket would otherwise overflow.
121   bool overflow_supported_;
122 
123   // Point to a QuicPacketReader object on the heap. The reader allocates more
124   // space than allowed on the stack.
125   std::unique_ptr<QuicPacketReader> packet_reader_;
126 
127   QuicClientBase* client_;
128 
129   int max_reads_per_epoll_loop_;
130 };
131 
132 }  // namespace quic
133 
134 #endif  // QUICHE_QUIC_TOOLS_QUIC_CLIENT_EPOLL_NETWORK_HELPER_H_
135