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