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