Home | History | Annotate | Download | only in base
      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:
     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 
    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 
    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