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