1092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar/*
2092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
3092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar *
4092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar *  Use of this source code is governed by a BSD-style license
5092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar *  that can be found in the LICENSE file in the root of the source
6092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar *  tree. An additional intellectual property rights grant can be found
7092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar *  in the file PATENTS.  All contributing project authors may
8092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar *  be found in the AUTHORS file in the root of the source tree.
9092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar */
1094b9550a32d189704a8eae55505edf62662c0534Evan Cheng
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#ifndef WEBRTC_P2P_BASE_TCPPORT_H_
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#define WEBRTC_P2P_BASE_TCPPORT_H_
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include <list>
154284e1795dd47d9638bb4fbd455ddb7e2e710e80Chad Rosier#include <string>
16f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper#include "webrtc/p2p/base/port.h"
1733d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner#include "webrtc/base/asyncpacketsocket.h"
1833d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner
1933d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattnernamespace cricket {
2033d60d5e56bbf3e9ed02bc916735419091736ca3Chris Lattner
2130c729b5d043a72a8eb35b9fe4c5c180cbed9a75Chad Rosierclass TCPConnection;
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth// Communicates using a local TCP port.
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines//
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth// This class is designed to allow subclasses to take advantage of the
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth// connection management provided by this class.  A subclass should take of all
27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth// packet sending and preparation, but when a packet is received, it should
28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth// call this TCPPort::OnReadPacket (3 arg) to dispatch to a connection.
29cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarclass TCPPort : public Port {
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth public:
31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth  static TCPPort* Create(rtc::Thread* thread,
32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth                         rtc::PacketSocketFactory* factory,
33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth                         rtc::Network* network,
3416cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar                         const rtc::IPAddress& ip,
353e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng                         uint16_t min_port,
3609062b1672d33c40c38de3ff3163e0d53ebe165dDaniel Dunbar                         uint16_t max_port,
3737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                         const std::string& username,
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                         const std::string& password,
39ebdeeab812beec0385b445f3d4c41a114e0d972fEvan Cheng                         bool allow_listen) {
40092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar    TCPPort* port = new TCPPort(thread, factory, network, ip, min_port,
41092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar                                max_port, username, password, allow_listen);
42092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar    if (!port->Init()) {
43092a9dda2d13918a6410db26f41c7b5aa97ff989Daniel Dunbar      delete port;
448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier      port = NULL;
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return port;
476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  ~TCPPort() override;
496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Connection* CreateConnection(const Candidate& address,
516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                               CandidateOrigin origin) override;
526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void PrepareAddress() override;
546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  int GetOption(rtc::Socket::Option opt, int* value) override;
568ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  int SetOption(rtc::Socket::Option opt, int value) override;
578ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  int GetError() override;
588ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  bool SupportsProtocol(const std::string& protocol) const override {
598ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier    return protocol == TCP_PROTOCOL_NAME || protocol == SSLTCP_PROTOCOL_NAME;
60dd929fc704054fa79cc1171354f95d91a5b62de2Devang Patel  }
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
626a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier protected:
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TCPPort(rtc::Thread* thread,
64cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          rtc::PacketSocketFactory* factory,
6516cdcb38b2a5c5cdc216f9abafabd20e1ef7a254Daniel Dunbar          rtc::Network* network,
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          const rtc::IPAddress& ip,
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          uint16_t min_port,
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          uint16_t max_port,
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          const std::string& username,
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          const std::string& password,
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          bool allow_listen);
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool Init();
738ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Handles sending using the local TCP socket.
756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  int SendTo(const void* data,
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             size_t size,
7736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             const rtc::SocketAddress& addr,
7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             const rtc::PacketOptions& options,
7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines             bool payload) override;
808ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
818ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Accepts incoming TCP connection.
828ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnNewConnection(rtc::AsyncPacketSocket* socket,
838ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                       rtc::AsyncPacketSocket* new_socket);
848ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
858ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier private:
868ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  struct Incoming {
878ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier    rtc::SocketAddress addr;
888ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier    rtc::AsyncPacketSocket* socket;
898ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  };
908ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
918ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  rtc::AsyncPacketSocket* GetIncoming(
928ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier      const rtc::SocketAddress& addr, bool remove = false);
93ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
948ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Receives packet signal from the local TCP Socket.
958ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnReadPacket(rtc::AsyncPacketSocket* socket,
968ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                    const char* data, size_t size,
978ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                    const rtc::SocketAddress& remote_addr,
988ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                    const rtc::PacketTime& packet_time);
998ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1008ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnSentPacket(rtc::AsyncPacketSocket* socket,
1018ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                    const rtc::SentPacket& sent_packet) override;
1028ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1038ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnReadyToSend(rtc::AsyncPacketSocket* socket);
1048ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1058ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnAddressReady(rtc::AsyncPacketSocket* socket,
1068ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                      const rtc::SocketAddress& address);
107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
10891955e78e718b4a7d2272ce476e29774f6ac84eaJakub Staszak  // TODO: Is this still needed?
1098ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  bool incoming_only_;
1108ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  bool allow_listen_;
1118ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  rtc::AsyncPacketSocket* socket_;
1128ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  int error_;
1138ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  std::list<Incoming> incoming_;
1148ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  friend class TCPConnection;
1168ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier};
1178ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1188ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosierclass TCPConnection : public Connection {
1198ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier public:
1208ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Connection is outgoing unless socket is specified
1218ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  TCPConnection(TCPPort* port, const Candidate& candidate,
1228ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                rtc::AsyncPacketSocket* socket = 0);
1238ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  ~TCPConnection() override;
1248ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  int Send(const void* data,
1268ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier           size_t size,
1278ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier           const rtc::PacketOptions& options) override;
1288ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  int GetError() override;
1298ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1308ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  rtc::AsyncPacketSocket* socket() { return socket_.get(); }
1318ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1328ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnMessage(rtc::Message* pmsg) override;
133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1348ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Allow test cases to overwrite the default timeout period.
1358ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  int reconnection_timeout() const { return reconnection_timeout_; }
1368ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void set_reconnection_timeout(int timeout_in_ms) {
1378ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier    reconnection_timeout_ = timeout_in_ms;
138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1398ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1408ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier protected:
1418ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  enum {
1428ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier    MSG_TCPCONNECTION_DELAYED_ONCLOSE = Connection::MSG_FIRST_AVAILABLE,
143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  };
1448ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1458ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Set waiting_for_stun_binding_complete_ to false to allow data packets in
14691955e78e718b4a7d2272ce476e29774f6ac84eaJakub Staszak  // addition to what Port::OnConnectionRequestResponse does.
1478ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnConnectionRequestResponse(ConnectionRequest* req,
1488ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                                   StunMessage* response) override;
14991955e78e718b4a7d2272ce476e29774f6ac84eaJakub Staszak
1508ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier private:
15191955e78e718b4a7d2272ce476e29774f6ac84eaJakub Staszak  // Helper function to handle the case when Ping or Send fails with error
1528ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // related to socket close.
1538ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void MaybeReconnect();
1548ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1558ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void CreateOutgoingTcpSocket();
1568ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1578ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void ConnectSocketSignals(rtc::AsyncPacketSocket* socket);
158cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
1598ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnConnect(rtc::AsyncPacketSocket* socket);
1608ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnClose(rtc::AsyncPacketSocket* socket, int error);
1618ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnReadPacket(rtc::AsyncPacketSocket* socket,
1628ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                    const char* data, size_t size,
1638ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                    const rtc::SocketAddress& remote_addr,
1648ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier                    const rtc::PacketTime& packet_time);
1658ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  void OnReadyToSend(rtc::AsyncPacketSocket* socket);
166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1678ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  rtc::scoped_ptr<rtc::AsyncPacketSocket> socket_;
1688ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  int error_;
169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool outgoing_;
1708ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1718ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Guard against multiple outgoing tcp connection during a reconnect.
1728ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  bool connection_pending_;
1738ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1748ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Guard against data packets sent when we reconnect a TCP connection. During
1758ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // reconnecting, when a new tcp connection has being made, we can't send data
1768ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // packets out until the STUN binding is completed (i.e. the write state is
1778ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // set to WRITABLE again by Connection::OnConnectionRequestResponse). IPC
1788ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // socket, when receiving data packets before that, will trigger OnError which
1798ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // will terminate the newly created connection.
1808ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  bool pretending_to_be_writable_;
1818ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1828ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  // Allow test case to overwrite the default timeout period.
1838ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  int reconnection_timeout_;
1848ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1858ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier  friend class TCPPort;
1868ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier};
1878ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1888ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier}  // namespace cricket
1898ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier
1908ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier#endif  // WEBRTC_P2P_BASE_TCPPORT_H_
1918ccacf788aeb3834ba9b6a2dc4f524fe42c55076Chad Rosier