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 WEBRTC_P2P_BASE_TCPPORT_H_
12 #define WEBRTC_P2P_BASE_TCPPORT_H_
13 
14 #include <list>
15 #include <string>
16 #include "webrtc/p2p/base/port.h"
17 #include "webrtc/base/asyncpacketsocket.h"
18 
19 namespace cricket {
20 
21 class TCPConnection;
22 
23 // Communicates using a local TCP port.
24 //
25 // This class is designed to allow subclasses to take advantage of the
26 // connection management provided by this class.  A subclass should take of all
27 // packet sending and preparation, but when a packet is received, it should
28 // call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
29 class TCPPort : public Port {
30  public:
Create(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,bool allow_listen)31   static TCPPort* Create(rtc::Thread* thread,
32                          rtc::PacketSocketFactory* factory,
33                          rtc::Network* network,
34                          const rtc::IPAddress& ip,
35                          uint16_t min_port,
36                          uint16_t max_port,
37                          const std::string& username,
38                          const std::string& password,
39                          bool allow_listen) {
40     TCPPort* port = new TCPPort(thread, factory, network, ip, min_port,
41                                 max_port, username, password, allow_listen);
42     if (!port->Init()) {
43       delete port;
44       port = NULL;
45     }
46     return port;
47   }
48   ~TCPPort() override;
49 
50   Connection* CreateConnection(const Candidate& address,
51                                CandidateOrigin origin) override;
52 
53   void PrepareAddress() override;
54 
55   int GetOption(rtc::Socket::Option opt, int* value) override;
56   int SetOption(rtc::Socket::Option opt, int value) override;
57   int GetError() override;
SupportsProtocol(const std::string & protocol)58   bool SupportsProtocol(const std::string& protocol) const override {
59     return protocol == TCP_PROTOCOL_NAME || protocol == SSLTCP_PROTOCOL_NAME;
60   }
61 
62  protected:
63   TCPPort(rtc::Thread* thread,
64           rtc::PacketSocketFactory* factory,
65           rtc::Network* network,
66           const rtc::IPAddress& ip,
67           uint16_t min_port,
68           uint16_t max_port,
69           const std::string& username,
70           const std::string& password,
71           bool allow_listen);
72   bool Init();
73 
74   // Handles sending using the local TCP socket.
75   int SendTo(const void* data,
76              size_t size,
77              const rtc::SocketAddress& addr,
78              const rtc::PacketOptions& options,
79              bool payload) override;
80 
81   // Accepts incoming TCP connection.
82   void OnNewConnection(rtc::AsyncPacketSocket* socket,
83                        rtc::AsyncPacketSocket* new_socket);
84 
85  private:
86   struct Incoming {
87     rtc::SocketAddress addr;
88     rtc::AsyncPacketSocket* socket;
89   };
90 
91   rtc::AsyncPacketSocket* GetIncoming(
92       const rtc::SocketAddress& addr, bool remove = false);
93 
94   // Receives packet signal from the local TCP Socket.
95   void OnReadPacket(rtc::AsyncPacketSocket* socket,
96                     const char* data, size_t size,
97                     const rtc::SocketAddress& remote_addr,
98                     const rtc::PacketTime& packet_time);
99 
100   void OnSentPacket(rtc::AsyncPacketSocket* socket,
101                     const rtc::SentPacket& sent_packet) override;
102 
103   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
104 
105   void OnAddressReady(rtc::AsyncPacketSocket* socket,
106                       const rtc::SocketAddress& address);
107 
108   // TODO: Is this still needed?
109   bool incoming_only_;
110   bool allow_listen_;
111   rtc::AsyncPacketSocket* socket_;
112   int error_;
113   std::list<Incoming> incoming_;
114 
115   friend class TCPConnection;
116 };
117 
118 class TCPConnection : public Connection {
119  public:
120   // Connection is outgoing unless socket is specified
121   TCPConnection(TCPPort* port, const Candidate& candidate,
122                 rtc::AsyncPacketSocket* socket = 0);
123   ~TCPConnection() override;
124 
125   int Send(const void* data,
126            size_t size,
127            const rtc::PacketOptions& options) override;
128   int GetError() override;
129 
socket()130   rtc::AsyncPacketSocket* socket() { return socket_.get(); }
131 
132   void OnMessage(rtc::Message* pmsg) override;
133 
134   // Allow test cases to overwrite the default timeout period.
reconnection_timeout()135   int reconnection_timeout() const { return reconnection_timeout_; }
set_reconnection_timeout(int timeout_in_ms)136   void set_reconnection_timeout(int timeout_in_ms) {
137     reconnection_timeout_ = timeout_in_ms;
138   }
139 
140  protected:
141   enum {
142     MSG_TCPCONNECTION_DELAYED_ONCLOSE = Connection::MSG_FIRST_AVAILABLE,
143   };
144 
145   // Set waiting_for_stun_binding_complete_ to false to allow data packets in
146   // addition to what Port::OnConnectionRequestResponse does.
147   void OnConnectionRequestResponse(ConnectionRequest* req,
148                                    StunMessage* response) override;
149 
150  private:
151   // Helper function to handle the case when Ping or Send fails with error
152   // related to socket close.
153   void MaybeReconnect();
154 
155   void CreateOutgoingTcpSocket();
156 
157   void ConnectSocketSignals(rtc::AsyncPacketSocket* socket);
158 
159   void OnConnect(rtc::AsyncPacketSocket* socket);
160   void OnClose(rtc::AsyncPacketSocket* socket, int error);
161   void OnReadPacket(rtc::AsyncPacketSocket* socket,
162                     const char* data, size_t size,
163                     const rtc::SocketAddress& remote_addr,
164                     const rtc::PacketTime& packet_time);
165   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
166 
167   rtc::scoped_ptr<rtc::AsyncPacketSocket> socket_;
168   int error_;
169   bool outgoing_;
170 
171   // Guard against multiple outgoing tcp connection during a reconnect.
172   bool connection_pending_;
173 
174   // Guard against data packets sent when we reconnect a TCP connection. During
175   // reconnecting, when a new tcp connection has being made, we can't send data
176   // packets out until the STUN binding is completed (i.e. the write state is
177   // set to WRITABLE again by Connection::OnConnectionRequestResponse). IPC
178   // socket, when receiving data packets before that, will trigger OnError which
179   // will terminate the newly created connection.
180   bool pretending_to_be_writable_;
181 
182   // Allow test case to overwrite the default timeout period.
183   int reconnection_timeout_;
184 
185   friend class TCPPort;
186 };
187 
188 }  // namespace cricket
189 
190 #endif  // WEBRTC_P2P_BASE_TCPPORT_H_
191