xref: /aosp_15_r20/external/webrtc/p2p/base/tcp_port.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #ifndef P2P_BASE_TCP_PORT_H_
12*d9f75844SAndroid Build Coastguard Worker #define P2P_BASE_TCP_PORT_H_
13*d9f75844SAndroid Build Coastguard Worker 
14*d9f75844SAndroid Build Coastguard Worker #include <list>
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <string>
17*d9f75844SAndroid Build Coastguard Worker 
18*d9f75844SAndroid Build Coastguard Worker #include "absl/memory/memory.h"
19*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/pending_task_safety_flag.h"
21*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/connection.h"
22*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/port.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/async_packet_socket.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/containers/flat_map.h"
25*d9f75844SAndroid Build Coastguard Worker 
26*d9f75844SAndroid Build Coastguard Worker namespace cricket {
27*d9f75844SAndroid Build Coastguard Worker 
28*d9f75844SAndroid Build Coastguard Worker class TCPConnection;
29*d9f75844SAndroid Build Coastguard Worker 
30*d9f75844SAndroid Build Coastguard Worker // Communicates using a local TCP port.
31*d9f75844SAndroid Build Coastguard Worker //
32*d9f75844SAndroid Build Coastguard Worker // This class is designed to allow subclasses to take advantage of the
33*d9f75844SAndroid Build Coastguard Worker // connection management provided by this class.  A subclass should take of all
34*d9f75844SAndroid Build Coastguard Worker // packet sending and preparation, but when a packet is received, it should
35*d9f75844SAndroid Build Coastguard Worker // call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
36*d9f75844SAndroid Build Coastguard Worker class TCPPort : public Port {
37*d9f75844SAndroid Build Coastguard Worker  public:
38*d9f75844SAndroid Build Coastguard Worker   static std::unique_ptr<TCPPort> Create(
39*d9f75844SAndroid Build Coastguard Worker       rtc::Thread* thread,
40*d9f75844SAndroid Build Coastguard Worker       rtc::PacketSocketFactory* factory,
41*d9f75844SAndroid Build Coastguard Worker       const rtc::Network* network,
42*d9f75844SAndroid Build Coastguard Worker       uint16_t min_port,
43*d9f75844SAndroid Build Coastguard Worker       uint16_t max_port,
44*d9f75844SAndroid Build Coastguard Worker       absl::string_view username,
45*d9f75844SAndroid Build Coastguard Worker       absl::string_view password,
46*d9f75844SAndroid Build Coastguard Worker       bool allow_listen,
47*d9f75844SAndroid Build Coastguard Worker       const webrtc::FieldTrialsView* field_trials = nullptr) {
48*d9f75844SAndroid Build Coastguard Worker     // Using `new` to access a non-public constructor.
49*d9f75844SAndroid Build Coastguard Worker     return absl::WrapUnique(new TCPPort(thread, factory, network, min_port,
50*d9f75844SAndroid Build Coastguard Worker                                         max_port, username, password,
51*d9f75844SAndroid Build Coastguard Worker                                         allow_listen, field_trials));
52*d9f75844SAndroid Build Coastguard Worker   }
53*d9f75844SAndroid Build Coastguard Worker   ~TCPPort() override;
54*d9f75844SAndroid Build Coastguard Worker 
55*d9f75844SAndroid Build Coastguard Worker   Connection* CreateConnection(const Candidate& address,
56*d9f75844SAndroid Build Coastguard Worker                                CandidateOrigin origin) override;
57*d9f75844SAndroid Build Coastguard Worker 
58*d9f75844SAndroid Build Coastguard Worker   void PrepareAddress() override;
59*d9f75844SAndroid Build Coastguard Worker 
60*d9f75844SAndroid Build Coastguard Worker   // Options apply to accepted sockets.
61*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/13065): Apply also to outgoing and existing
62*d9f75844SAndroid Build Coastguard Worker   // connections.
63*d9f75844SAndroid Build Coastguard Worker   int GetOption(rtc::Socket::Option opt, int* value) override;
64*d9f75844SAndroid Build Coastguard Worker   int SetOption(rtc::Socket::Option opt, int value) override;
65*d9f75844SAndroid Build Coastguard Worker   int GetError() override;
66*d9f75844SAndroid Build Coastguard Worker   bool SupportsProtocol(absl::string_view protocol) const override;
67*d9f75844SAndroid Build Coastguard Worker   ProtocolType GetProtocol() const override;
68*d9f75844SAndroid Build Coastguard Worker 
69*d9f75844SAndroid Build Coastguard Worker  protected:
70*d9f75844SAndroid Build Coastguard Worker   TCPPort(rtc::Thread* thread,
71*d9f75844SAndroid Build Coastguard Worker           rtc::PacketSocketFactory* factory,
72*d9f75844SAndroid Build Coastguard Worker           const rtc::Network* network,
73*d9f75844SAndroid Build Coastguard Worker           uint16_t min_port,
74*d9f75844SAndroid Build Coastguard Worker           uint16_t max_port,
75*d9f75844SAndroid Build Coastguard Worker           absl::string_view username,
76*d9f75844SAndroid Build Coastguard Worker           absl::string_view password,
77*d9f75844SAndroid Build Coastguard Worker           bool allow_listen,
78*d9f75844SAndroid Build Coastguard Worker           const webrtc::FieldTrialsView* field_trials);
79*d9f75844SAndroid Build Coastguard Worker 
80*d9f75844SAndroid Build Coastguard Worker   // Handles sending using the local TCP socket.
81*d9f75844SAndroid Build Coastguard Worker   int SendTo(const void* data,
82*d9f75844SAndroid Build Coastguard Worker              size_t size,
83*d9f75844SAndroid Build Coastguard Worker              const rtc::SocketAddress& addr,
84*d9f75844SAndroid Build Coastguard Worker              const rtc::PacketOptions& options,
85*d9f75844SAndroid Build Coastguard Worker              bool payload) override;
86*d9f75844SAndroid Build Coastguard Worker 
87*d9f75844SAndroid Build Coastguard Worker   // Accepts incoming TCP connection.
88*d9f75844SAndroid Build Coastguard Worker   void OnNewConnection(rtc::AsyncListenSocket* socket,
89*d9f75844SAndroid Build Coastguard Worker                        rtc::AsyncPacketSocket* new_socket);
90*d9f75844SAndroid Build Coastguard Worker 
91*d9f75844SAndroid Build Coastguard Worker  private:
92*d9f75844SAndroid Build Coastguard Worker   struct Incoming {
93*d9f75844SAndroid Build Coastguard Worker     rtc::SocketAddress addr;
94*d9f75844SAndroid Build Coastguard Worker     rtc::AsyncPacketSocket* socket;
95*d9f75844SAndroid Build Coastguard Worker   };
96*d9f75844SAndroid Build Coastguard Worker 
97*d9f75844SAndroid Build Coastguard Worker   void TryCreateServerSocket();
98*d9f75844SAndroid Build Coastguard Worker 
99*d9f75844SAndroid Build Coastguard Worker   rtc::AsyncPacketSocket* GetIncoming(const rtc::SocketAddress& addr,
100*d9f75844SAndroid Build Coastguard Worker                                       bool remove = false);
101*d9f75844SAndroid Build Coastguard Worker 
102*d9f75844SAndroid Build Coastguard Worker   // Receives packet signal from the local TCP Socket.
103*d9f75844SAndroid Build Coastguard Worker   void OnReadPacket(rtc::AsyncPacketSocket* socket,
104*d9f75844SAndroid Build Coastguard Worker                     const char* data,
105*d9f75844SAndroid Build Coastguard Worker                     size_t size,
106*d9f75844SAndroid Build Coastguard Worker                     const rtc::SocketAddress& remote_addr,
107*d9f75844SAndroid Build Coastguard Worker                     const int64_t& packet_time_us);
108*d9f75844SAndroid Build Coastguard Worker 
109*d9f75844SAndroid Build Coastguard Worker   void OnSentPacket(rtc::AsyncPacketSocket* socket,
110*d9f75844SAndroid Build Coastguard Worker                     const rtc::SentPacket& sent_packet) override;
111*d9f75844SAndroid Build Coastguard Worker 
112*d9f75844SAndroid Build Coastguard Worker   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
113*d9f75844SAndroid Build Coastguard Worker 
114*d9f75844SAndroid Build Coastguard Worker   bool allow_listen_;
115*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::AsyncListenSocket> listen_socket_;
116*d9f75844SAndroid Build Coastguard Worker   // Options to be applied to accepted sockets.
117*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc:13065): Configure connect/accept in the same way, but
118*d9f75844SAndroid Build Coastguard Worker   // currently, setting OPT_NODELAY for client sockets is done (unconditionally)
119*d9f75844SAndroid Build Coastguard Worker   // by BasicPacketSocketFactory::CreateClientTcpSocket.
120*d9f75844SAndroid Build Coastguard Worker   webrtc::flat_map<rtc::Socket::Option, int> socket_options_;
121*d9f75844SAndroid Build Coastguard Worker 
122*d9f75844SAndroid Build Coastguard Worker   int error_;
123*d9f75844SAndroid Build Coastguard Worker   std::list<Incoming> incoming_;
124*d9f75844SAndroid Build Coastguard Worker 
125*d9f75844SAndroid Build Coastguard Worker   friend class TCPConnection;
126*d9f75844SAndroid Build Coastguard Worker };
127*d9f75844SAndroid Build Coastguard Worker 
128*d9f75844SAndroid Build Coastguard Worker class TCPConnection : public Connection, public sigslot::has_slots<> {
129*d9f75844SAndroid Build Coastguard Worker  public:
130*d9f75844SAndroid Build Coastguard Worker   // Connection is outgoing unless socket is specified
131*d9f75844SAndroid Build Coastguard Worker   TCPConnection(rtc::WeakPtr<Port> tcp_port,
132*d9f75844SAndroid Build Coastguard Worker                 const Candidate& candidate,
133*d9f75844SAndroid Build Coastguard Worker                 rtc::AsyncPacketSocket* socket = nullptr);
134*d9f75844SAndroid Build Coastguard Worker   ~TCPConnection() override;
135*d9f75844SAndroid Build Coastguard Worker 
136*d9f75844SAndroid Build Coastguard Worker   int Send(const void* data,
137*d9f75844SAndroid Build Coastguard Worker            size_t size,
138*d9f75844SAndroid Build Coastguard Worker            const rtc::PacketOptions& options) override;
139*d9f75844SAndroid Build Coastguard Worker   int GetError() override;
140*d9f75844SAndroid Build Coastguard Worker 
socket()141*d9f75844SAndroid Build Coastguard Worker   rtc::AsyncPacketSocket* socket() { return socket_.get(); }
142*d9f75844SAndroid Build Coastguard Worker 
143*d9f75844SAndroid Build Coastguard Worker   // Allow test cases to overwrite the default timeout period.
reconnection_timeout()144*d9f75844SAndroid Build Coastguard Worker   int reconnection_timeout() const { return reconnection_timeout_; }
set_reconnection_timeout(int timeout_in_ms)145*d9f75844SAndroid Build Coastguard Worker   void set_reconnection_timeout(int timeout_in_ms) {
146*d9f75844SAndroid Build Coastguard Worker     reconnection_timeout_ = timeout_in_ms;
147*d9f75844SAndroid Build Coastguard Worker   }
148*d9f75844SAndroid Build Coastguard Worker 
149*d9f75844SAndroid Build Coastguard Worker  protected:
150*d9f75844SAndroid Build Coastguard Worker   // Set waiting_for_stun_binding_complete_ to false to allow data packets in
151*d9f75844SAndroid Build Coastguard Worker   // addition to what Port::OnConnectionRequestResponse does.
152*d9f75844SAndroid Build Coastguard Worker   void OnConnectionRequestResponse(StunRequest* req,
153*d9f75844SAndroid Build Coastguard Worker                                    StunMessage* response) override;
154*d9f75844SAndroid Build Coastguard Worker 
155*d9f75844SAndroid Build Coastguard Worker  private:
156*d9f75844SAndroid Build Coastguard Worker   // Helper function to handle the case when Ping or Send fails with error
157*d9f75844SAndroid Build Coastguard Worker   // related to socket close.
158*d9f75844SAndroid Build Coastguard Worker   void MaybeReconnect();
159*d9f75844SAndroid Build Coastguard Worker 
160*d9f75844SAndroid Build Coastguard Worker   void CreateOutgoingTcpSocket();
161*d9f75844SAndroid Build Coastguard Worker 
162*d9f75844SAndroid Build Coastguard Worker   void ConnectSocketSignals(rtc::AsyncPacketSocket* socket);
163*d9f75844SAndroid Build Coastguard Worker 
164*d9f75844SAndroid Build Coastguard Worker   void OnConnect(rtc::AsyncPacketSocket* socket);
165*d9f75844SAndroid Build Coastguard Worker   void OnClose(rtc::AsyncPacketSocket* socket, int error);
166*d9f75844SAndroid Build Coastguard Worker   void OnReadPacket(rtc::AsyncPacketSocket* socket,
167*d9f75844SAndroid Build Coastguard Worker                     const char* data,
168*d9f75844SAndroid Build Coastguard Worker                     size_t size,
169*d9f75844SAndroid Build Coastguard Worker                     const rtc::SocketAddress& remote_addr,
170*d9f75844SAndroid Build Coastguard Worker                     const int64_t& packet_time_us);
171*d9f75844SAndroid Build Coastguard Worker   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
172*d9f75844SAndroid Build Coastguard Worker 
tcp_port()173*d9f75844SAndroid Build Coastguard Worker   TCPPort* tcp_port() {
174*d9f75844SAndroid Build Coastguard Worker     RTC_DCHECK_EQ(port()->GetProtocol(), PROTO_TCP);
175*d9f75844SAndroid Build Coastguard Worker     return static_cast<TCPPort*>(port());
176*d9f75844SAndroid Build Coastguard Worker   }
177*d9f75844SAndroid Build Coastguard Worker 
178*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::AsyncPacketSocket> socket_;
179*d9f75844SAndroid Build Coastguard Worker   int error_;
180*d9f75844SAndroid Build Coastguard Worker   bool outgoing_;
181*d9f75844SAndroid Build Coastguard Worker 
182*d9f75844SAndroid Build Coastguard Worker   // Guard against multiple outgoing tcp connection during a reconnect.
183*d9f75844SAndroid Build Coastguard Worker   bool connection_pending_;
184*d9f75844SAndroid Build Coastguard Worker 
185*d9f75844SAndroid Build Coastguard Worker   // Guard against data packets sent when we reconnect a TCP connection. During
186*d9f75844SAndroid Build Coastguard Worker   // reconnecting, when a new tcp connection has being made, we can't send data
187*d9f75844SAndroid Build Coastguard Worker   // packets out until the STUN binding is completed (i.e. the write state is
188*d9f75844SAndroid Build Coastguard Worker   // set to WRITABLE again by Connection::OnConnectionRequestResponse). IPC
189*d9f75844SAndroid Build Coastguard Worker   // socket, when receiving data packets before that, will trigger OnError which
190*d9f75844SAndroid Build Coastguard Worker   // will terminate the newly created connection.
191*d9f75844SAndroid Build Coastguard Worker   bool pretending_to_be_writable_;
192*d9f75844SAndroid Build Coastguard Worker 
193*d9f75844SAndroid Build Coastguard Worker   // Allow test case to overwrite the default timeout period.
194*d9f75844SAndroid Build Coastguard Worker   int reconnection_timeout_;
195*d9f75844SAndroid Build Coastguard Worker 
196*d9f75844SAndroid Build Coastguard Worker   webrtc::ScopedTaskSafety network_safety_;
197*d9f75844SAndroid Build Coastguard Worker 
198*d9f75844SAndroid Build Coastguard Worker   friend class TCPPort;
199*d9f75844SAndroid Build Coastguard Worker };
200*d9f75844SAndroid Build Coastguard Worker 
201*d9f75844SAndroid Build Coastguard Worker }  // namespace cricket
202*d9f75844SAndroid Build Coastguard Worker 
203*d9f75844SAndroid Build Coastguard Worker #endif  // P2P_BASE_TCP_PORT_H_
204