blob: 932af50aa45eb0c42bd8850924e746b034290fb2 [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"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000023
24namespace cricket {
25
26class TCPConnection;
27
28// Communicates using a local TCP port.
29//
30// This class is designed to allow subclasses to take advantage of the
31// connection management provided by this class. A subclass should take of all
32// packet sending and preparation, but when a packet is received, it should
33// call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
34class TCPPort : public Port {
35 public:
Steve Antona8f1e562018-10-10 11:29:44 -070036 static std::unique_ptr<TCPPort> Create(rtc::Thread* thread,
37 rtc::PacketSocketFactory* factory,
38 rtc::Network* network,
39 uint16_t min_port,
40 uint16_t max_port,
41 const std::string& username,
42 const std::string& password,
43 bool allow_listen) {
44 // Using `new` to access a non-public constructor.
45 return absl::WrapUnique(new TCPPort(thread, factory, network, min_port,
46 max_port, username, password,
47 allow_listen));
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000048 }
Stefan Holmer55674ff2016-01-14 15:49:16 +010049 ~TCPPort() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000050
Stefan Holmer55674ff2016-01-14 15:49:16 +010051 Connection* CreateConnection(const Candidate& address,
52 CandidateOrigin origin) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053
Stefan Holmer55674ff2016-01-14 15:49:16 +010054 void PrepareAddress() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000055
Niels Möller646fddc2021-11-02 15:56:05 +010056 // Options apply to accepted sockets.
57 // TODO(bugs.webrtc.org/13065): Apply also to outgoing and existing
58 // connections.
Stefan Holmer55674ff2016-01-14 15:49:16 +010059 int GetOption(rtc::Socket::Option opt, int* value) override;
60 int SetOption(rtc::Socket::Option opt, int value) override;
61 int GetError() override;
Steve Anton1cf1b7d2017-10-30 10:00:15 -070062 bool SupportsProtocol(const std::string& protocol) const override;
63 ProtocolType GetProtocol() const override;
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -070064
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000065 protected:
pkasting@chromium.org332331f2014-11-06 20:19:22 +000066 TCPPort(rtc::Thread* thread,
67 rtc::PacketSocketFactory* factory,
68 rtc::Network* network,
Peter Boström0c4e06b2015-10-07 12:23:21 +020069 uint16_t min_port,
70 uint16_t max_port,
pkasting@chromium.org332331f2014-11-06 20:19:22 +000071 const std::string& username,
72 const std::string& password,
73 bool allow_listen);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000074
75 // Handles sending using the local TCP socket.
Stefan Holmer55674ff2016-01-14 15:49:16 +010076 int SendTo(const void* data,
77 size_t size,
78 const rtc::SocketAddress& addr,
79 const rtc::PacketOptions& options,
80 bool payload) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000081
82 // Accepts incoming TCP connection.
Niels Möller6d19d142021-10-06 11:19:03 +020083 void OnNewConnection(rtc::AsyncListenSocket* socket,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000084 rtc::AsyncPacketSocket* new_socket);
85
86 private:
87 struct Incoming {
88 rtc::SocketAddress addr;
89 rtc::AsyncPacketSocket* socket;
90 };
91
deadbeef1ee21252017-06-13 15:49:45 -070092 void TryCreateServerSocket();
93
Yves Gerey665174f2018-06-19 15:03:05 +020094 rtc::AsyncPacketSocket* GetIncoming(const rtc::SocketAddress& addr,
95 bool remove = false);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000096
97 // Receives packet signal from the local TCP Socket.
98 void OnReadPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +020099 const char* data,
100 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000101 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100102 const int64_t& packet_time_us);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000103
Stefan Holmer55674ff2016-01-14 15:49:16 +0100104 void OnSentPacket(rtc::AsyncPacketSocket* socket,
105 const rtc::SentPacket& sent_packet) override;
106
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000107 void OnReadyToSend(rtc::AsyncPacketSocket* socket);
108
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000109 bool allow_listen_;
Niels Möller6d19d142021-10-06 11:19:03 +0200110 std::unique_ptr<rtc::AsyncListenSocket> listen_socket_;
Niels Möller646fddc2021-11-02 15:56:05 +0100111 // Options to be applied to accepted sockets.
112 // TODO(bugs.webrtc:13065): Configure connect/accept in the same way, but
113 // currently, setting OPT_NODELAY for client sockets is done (unconditionally)
114 // by BasicPacketSocketFactory::CreateClientTcpSocket.
115 webrtc::flat_map<rtc::Socket::Option, int> socket_options_;
116
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000117 int error_;
118 std::list<Incoming> incoming_;
119
120 friend class TCPConnection;
121};
122
123class TCPConnection : public Connection {
124 public:
125 // Connection is outgoing unless socket is specified
Yves Gerey665174f2018-06-19 15:03:05 +0200126 TCPConnection(TCPPort* port,
127 const Candidate& candidate,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 rtc::AsyncPacketSocket* socket = 0);
Stefan Holmer55674ff2016-01-14 15:49:16 +0100129 ~TCPConnection() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000130
Stefan Holmer55674ff2016-01-14 15:49:16 +0100131 int Send(const void* data,
132 size_t size,
133 const rtc::PacketOptions& options) override;
134 int GetError() override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000135
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700136 rtc::AsyncPacketSocket* socket() { return socket_.get(); }
137
Taylor Brandstetter05ea12e2022-02-25 02:28:35 +0000138 void OnMessage(rtc::Message* pmsg) override;
139
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700140 // Allow test cases to overwrite the default timeout period.
141 int reconnection_timeout() const { return reconnection_timeout_; }
142 void set_reconnection_timeout(int timeout_in_ms) {
143 reconnection_timeout_ = timeout_in_ms;
144 }
145
146 protected:
Taylor Brandstetter05ea12e2022-02-25 02:28:35 +0000147 enum {
148 MSG_TCPCONNECTION_DELAYED_ONCLOSE = Connection::MSG_FIRST_AVAILABLE,
149 MSG_TCPCONNECTION_FAILED_CREATE_SOCKET,
150 };
151
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700152 // Set waiting_for_stun_binding_complete_ to false to allow data packets in
153 // addition to what Port::OnConnectionRequestResponse does.
Stefan Holmer55674ff2016-01-14 15:49:16 +0100154 void OnConnectionRequestResponse(ConnectionRequest* req,
155 StunMessage* response) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000156
157 private:
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700158 // Helper function to handle the case when Ping or Send fails with error
159 // related to socket close.
160 void MaybeReconnect();
161
162 void CreateOutgoingTcpSocket();
163
164 void ConnectSocketSignals(rtc::AsyncPacketSocket* socket);
165
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000166 void OnConnect(rtc::AsyncPacketSocket* socket);
167 void OnClose(rtc::AsyncPacketSocket* socket, int error);
168 void OnReadPacket(rtc::AsyncPacketSocket* socket,
Yves Gerey665174f2018-06-19 15:03:05 +0200169 const char* data,
170 size_t size,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000171 const rtc::SocketAddress& remote_addr,
Niels Möllere6933812018-11-05 13:01:41 +0100172 const int64_t& packet_time_us);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000173 void OnReadyToSend(rtc::AsyncPacketSocket* socket);
174
kwiberg3ec46792016-04-27 07:22:53 -0700175 std::unique_ptr<rtc::AsyncPacketSocket> socket_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000176 int error_;
Guo-wei Shiehbe508a12015-04-06 12:48:47 -0700177 bool outgoing_;
178
179 // Guard against multiple outgoing tcp connection during a reconnect.
180 bool connection_pending_;
181
182 // Guard against data packets sent when we reconnect a TCP connection. During
183 // reconnecting, when a new tcp connection has being made, we can't send data
184 // packets out until the STUN binding is completed (i.e. the write state is
185 // set to WRITABLE again by Connection::OnConnectionRequestResponse). IPC
186 // socket, when receiving data packets before that, will trigger OnError which
187 // will terminate the newly created connection.
188 bool pretending_to_be_writable_;
189
190 // Allow test case to overwrite the default timeout period.
191 int reconnection_timeout_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000192
193 friend class TCPPort;
194};
195
196} // namespace cricket
197
Steve Anton10542f22019-01-11 09:11:00 -0800198#endif // P2P_BASE_TCP_PORT_H_