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