blob: 6bd935f613ada5e30477f60ab5dd8062a6faa034 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#ifndef P2P_BASE_TCP_PORT_H_
12#define P2P_BASE_TCP_PORT_H_
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013
14#include <list>
kwiberg3ec46792016-04-27 07:22:53 -070015#include <memory>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000016#include <string>
kwiberg3ec46792016-04-27 07:22:53 -070017
tzikf0e926f2018-10-15 13:52:10 +090018#include "absl/memory/memory.h"
Jonas Orelande8e7d7b2019-05-29 09:30:55 +020019#include "p2p/base/connection.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "p2p/base/port.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/async_packet_socket.h"
Niels Möller646fddc2021-11-02 15:56:05 +010022#include "rtc_base/containers/flat_map.h"
Mirko Bonadei0cb1cfa2022-02-25 10:45:32 +000023#include "rtc_base/task_utils/pending_task_safety_flag.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000024
25namespace cricket {
26
27class TCPConnection;
28
29// Communicates using a local TCP port.
30//
31// This class is designed to allow subclasses to take advantage of the
32// connection management provided by this class. A subclass should take of all
33// packet sending and preparation, but when a packet is received, it should
34// call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
35class TCPPort : public Port {
36 public:
Jonas Orelandc06fe8b2022-03-28 14:58:26 +020037 static std::unique_ptr<TCPPort> Create(
38 rtc::Thread* thread,
39 rtc::PacketSocketFactory* factory,
40 const rtc::Network* network,
41 uint16_t min_port,
42 uint16_t max_port,
43 const std::string& username,
44 const std::string& password,
45 bool allow_listen,
Jonas Orelande62c2f22022-03-29 11:04:48 +020046 const webrtc::FieldTrialsView* field_trials = nullptr) {
Steve Antona8f1e562018-10-10 11:29:44 -070047 // Using `new` to access a non-public constructor.
48 return absl::WrapUnique(new TCPPort(thread, factory, network, min_port,
49 max_port, username, password,
Jonas Orelandc06fe8b2022-03-28 14:58:26 +020050 allow_listen, field_trials));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051 }
Stefan Holmer55674ff2016-01-14 15:49:16 +010052 ~TCPPort() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053
Stefan Holmer55674ff2016-01-14 15:49:16 +010054 Connection* CreateConnection(const Candidate& address,
55 CandidateOrigin origin) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000056
Stefan Holmer55674ff2016-01-14 15:49:16 +010057 void PrepareAddress() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000058
Niels Möller646fddc2021-11-02 15:56:05 +010059 // Options apply to accepted sockets.
60 // TODO(bugs.webrtc.org/13065): Apply also to outgoing and existing
61 // connections.
Stefan Holmer55674ff2016-01-14 15:49:16 +010062 int GetOption(rtc::Socket::Option opt, int* value) override;
63 int SetOption(rtc::Socket::Option opt, int value) override;
64 int GetError() override;
Steve Anton1cf1b7d2017-10-30 10:00:15 -070065 bool SupportsProtocol(const std::string& protocol) const override;
66 ProtocolType GetProtocol() const override;
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -070067
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000068 protected:
pkasting@chromium.org332331f2014-11-06 20:19:22 +000069 TCPPort(rtc::Thread* thread,
70 rtc::PacketSocketFactory* factory,
Niels Möllere0c6bdf2022-03-24 15:18:02 +010071 const rtc::Network* network,
Peter Boström0c4e06b2015-10-07 12:23:21 +020072 uint16_t min_port,
73 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +000074 const std::string& username,
75 const std::string& password,
Jonas Orelandc06fe8b2022-03-28 14:58:26 +020076 bool allow_listen,
Jonas Orelande62c2f22022-03-29 11:04:48 +020077 const webrtc::FieldTrialsView* field_trials);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000078
79 // Handles sending using the local TCP socket.
Stefan Holmer55674ff2016-01-14 15:49:16 +010080 int SendTo(const void* data,
81 size_t size,
82 const rtc::SocketAddress& addr,
83 const rtc::PacketOptions& options,
84 bool payload) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000085
86 // Accepts incoming TCP connection.
Niels Möller6d19d142021-10-06 11:19:03 +020087 void OnNewConnection(rtc::AsyncListenSocket* socket,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000088 rtc::AsyncPacketSocket* new_socket);
89
90 private:
91 struct Incoming {
92 rtc::SocketAddress addr;
93 rtc::AsyncPacketSocket* socket;
94 };
95
deadbeef1ee21252017-06-13 15:49:45 -070096 void TryCreateServerSocket();
97
Yves Gerey665174f2018-06-19 15:03:05 +020098 rtc::AsyncPacketSocket* GetIncoming(const rtc::SocketAddress& addr,
99 bool remove = false);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000100
101 // Receives packet signal from the local TCP Socket.
102 void OnReadPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +0200103 const char* data,
104 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000105 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100106 const int64_t& packet_time_us);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000107
Stefan Holmer55674ff2016-01-14 15:49:16 +0100108 void OnSentPacket(rtc::AsyncPacketSocket* socket,
109 const rtc::SentPacket& sent_packet) override;
110
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000111 void OnReadyToSend(rtc::AsyncPacketSocket* socket);
112
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000113 bool allow_listen_;
Niels Möller6d19d142021-10-06 11:19:03 +0200114 std::unique_ptr<rtc::AsyncListenSocket> listen_socket_;
Niels Möller646fddc2021-11-02 15:56:05 +0100115 // Options to be applied to accepted sockets.
116 // TODO(bugs.webrtc:13065): Configure connect/accept in the same way, but
117 // currently, setting OPT_NODELAY for client sockets is done (unconditionally)
118 // by BasicPacketSocketFactory::CreateClientTcpSocket.
119 webrtc::flat_map<rtc::Socket::Option, int> socket_options_;
120
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000121 int error_;
122 std::list<Incoming> incoming_;
123
124 friend class TCPConnection;
125};
126
Tommib44a7942022-04-28 12:31:47 +0200127class TCPConnection : public Connection, public sigslot::has_slots<> {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 public:
129 // Connection is outgoing unless socket is specified
Tommid7e5cfb2022-03-30 20:13:06 +0200130 TCPConnection(rtc::WeakPtr<Port> tcp_port,
Yves Gerey665174f2018-06-19 15:03:05 +0200131 const Candidate& candidate,
Tommid7e5cfb2022-03-30 20:13:06 +0200132 rtc::AsyncPacketSocket* socket = nullptr);
Stefan Holmer55674ff2016-01-14 15:49:16 +0100133 ~TCPConnection() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000134
Stefan Holmer55674ff2016-01-14 15:49:16 +0100135 int Send(const void* data,
136 size_t size,
137 const rtc::PacketOptions& options) override;
138 int GetError() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000139
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700140 rtc::AsyncPacketSocket* socket() { return socket_.get(); }
141
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700142 // Allow test cases to overwrite the default timeout period.
143 int reconnection_timeout() const { return reconnection_timeout_; }
144 void set_reconnection_timeout(int timeout_in_ms) {
145 reconnection_timeout_ = timeout_in_ms;
146 }
147
148 protected:
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700149 // Set waiting_for_stun_binding_complete_ to false to allow data packets in
150 // addition to what Port::OnConnectionRequestResponse does.
Stefan Holmer55674ff2016-01-14 15:49:16 +0100151 void OnConnectionRequestResponse(ConnectionRequest* req,
152 StunMessage* response) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000153
154 private:
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700155 // Helper function to handle the case when Ping or Send fails with error
156 // related to socket close.
157 void MaybeReconnect();
158
159 void CreateOutgoingTcpSocket();
160
161 void ConnectSocketSignals(rtc::AsyncPacketSocket* socket);
162
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163 void OnConnect(rtc::AsyncPacketSocket* socket);
164 void OnClose(rtc::AsyncPacketSocket* socket, int error);
165 void OnReadPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +0200166 const char* data,
167 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000168 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100169 const int64_t& packet_time_us);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000170 void OnReadyToSend(rtc::AsyncPacketSocket* socket);
171
Tommid7e5cfb2022-03-30 20:13:06 +0200172 TCPPort* tcp_port() {
173 RTC_DCHECK_EQ(port()->GetProtocol(), PROTO_TCP);
174 return static_cast<TCPPort*>(port());
175 }
176
kwiberg3ec46792016-04-27 07:22:53 -0700177 std::unique_ptr<rtc::AsyncPacketSocket> socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000178 int error_;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700179 bool outgoing_;
180
181 // Guard against multiple outgoing tcp connection during a reconnect.
182 bool connection_pending_;
183
184 // Guard against data packets sent when we reconnect a TCP connection. During
185 // reconnecting, when a new tcp connection has being made, we can't send data
186 // packets out until the STUN binding is completed (i.e. the write state is
187 // set to WRITABLE again by Connection::OnConnectionRequestResponse). IPC
188 // socket, when receiving data packets before that, will trigger OnError which
189 // will terminate the newly created connection.
190 bool pretending_to_be_writable_;
191
192 // Allow test case to overwrite the default timeout period.
193 int reconnection_timeout_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194
Mirko Bonadei0cb1cfa2022-02-25 10:45:32 +0000195 webrtc::ScopedTaskSafety network_safety_;
196
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000197 friend class TCPPort;
198};
199
200} // namespace cricket
201
Steve Anton10542f22019-01-11 09:11:00 -0800202#endif // P2P_BASE_TCP_PORT_H_