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
19namespace cricket {
20
21class 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.
29class TCPPort : public Port {
30 public:
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;
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
118class 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
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.
135  int reconnection_timeout() const { return reconnection_timeout_; }
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