Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2012 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_TURNPORT_H_
     12 #define WEBRTC_P2P_BASE_TURNPORT_H_
     13 
     14 #include <stdio.h>
     15 #include <list>
     16 #include <set>
     17 #include <string>
     18 
     19 #include "webrtc/base/asyncinvoker.h"
     20 #include "webrtc/base/asyncpacketsocket.h"
     21 #include "webrtc/p2p/base/port.h"
     22 #include "webrtc/p2p/client/basicportallocator.h"
     23 
     24 namespace rtc {
     25 class AsyncResolver;
     26 class SignalThread;
     27 }
     28 
     29 namespace cricket {
     30 
     31 extern const char TURN_PORT_TYPE[];
     32 class TurnAllocateRequest;
     33 class TurnEntry;
     34 
     35 class TurnPort : public Port {
     36  public:
     37   enum PortState {
     38     STATE_CONNECTING,    // Initial state, cannot send any packets.
     39     STATE_CONNECTED,     // Socket connected, ready to send stun requests.
     40     STATE_READY,         // Received allocate success, can send any packets.
     41     STATE_DISCONNECTED,  // TCP connection died, cannot send any packets.
     42   };
     43   static TurnPort* Create(rtc::Thread* thread,
     44                           rtc::PacketSocketFactory* factory,
     45                           rtc::Network* network,
     46                           rtc::AsyncPacketSocket* socket,
     47                           const std::string& username,  // ice username.
     48                           const std::string& password,  // ice password.
     49                           const ProtocolAddress& server_address,
     50                           const RelayCredentials& credentials,
     51                           int server_priority,
     52                           const std::string& origin) {
     53     return new TurnPort(thread, factory, network, socket, username, password,
     54                         server_address, credentials, server_priority, origin);
     55   }
     56 
     57   static TurnPort* Create(rtc::Thread* thread,
     58                           rtc::PacketSocketFactory* factory,
     59                           rtc::Network* network,
     60                           const rtc::IPAddress& ip,
     61                           uint16_t min_port,
     62                           uint16_t max_port,
     63                           const std::string& username,  // ice username.
     64                           const std::string& password,  // ice password.
     65                           const ProtocolAddress& server_address,
     66                           const RelayCredentials& credentials,
     67                           int server_priority,
     68                           const std::string& origin) {
     69     return new TurnPort(thread, factory, network, ip, min_port, max_port,
     70                         username, password, server_address, credentials,
     71                         server_priority, origin);
     72   }
     73 
     74   virtual ~TurnPort();
     75 
     76   const ProtocolAddress& server_address() const { return server_address_; }
     77   // Returns an empty address if the local address has not been assigned.
     78   rtc::SocketAddress GetLocalAddress() const;
     79 
     80   bool ready() const { return state_ == STATE_READY; }
     81   bool connected() const {
     82     return state_ == STATE_READY || state_ == STATE_CONNECTED;
     83   }
     84   const RelayCredentials& credentials() const { return credentials_; }
     85 
     86   virtual void PrepareAddress();
     87   virtual Connection* CreateConnection(
     88       const Candidate& c, PortInterface::CandidateOrigin origin);
     89   virtual int SendTo(const void* data, size_t size,
     90                      const rtc::SocketAddress& addr,
     91                      const rtc::PacketOptions& options,
     92                      bool payload);
     93   virtual int SetOption(rtc::Socket::Option opt, int value);
     94   virtual int GetOption(rtc::Socket::Option opt, int* value);
     95   virtual int GetError();
     96 
     97   virtual bool HandleIncomingPacket(
     98       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
     99       const rtc::SocketAddress& remote_addr,
    100       const rtc::PacketTime& packet_time) {
    101     OnReadPacket(socket, data, size, remote_addr, packet_time);
    102     return true;
    103   }
    104   virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
    105                             const char* data, size_t size,
    106                             const rtc::SocketAddress& remote_addr,
    107                             const rtc::PacketTime& packet_time);
    108 
    109   virtual void OnSentPacket(rtc::AsyncPacketSocket* socket,
    110                             const rtc::SentPacket& sent_packet);
    111   virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
    112   virtual bool SupportsProtocol(const std::string& protocol) const {
    113     // Turn port only connects to UDP candidates.
    114     return protocol == UDP_PROTOCOL_NAME;
    115   }
    116 
    117   void OnSocketConnect(rtc::AsyncPacketSocket* socket);
    118   void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
    119 
    120 
    121   const std::string& hash() const { return hash_; }
    122   const std::string& nonce() const { return nonce_; }
    123 
    124   int error() const { return error_; }
    125 
    126   void OnAllocateMismatch();
    127 
    128   rtc::AsyncPacketSocket* socket() const {
    129     return socket_;
    130   }
    131 
    132   // For testing only.
    133   rtc::AsyncInvoker* invoker() { return &invoker_; }
    134 
    135   // Signal with resolved server address.
    136   // Parameters are port, server address and resolved server address.
    137   // This signal will be sent only if server address is resolved successfully.
    138   sigslot::signal3<TurnPort*,
    139                    const rtc::SocketAddress&,
    140                    const rtc::SocketAddress&> SignalResolvedServerAddress;
    141 
    142   // All public methods/signals below are for testing only.
    143   sigslot::signal2<TurnPort*, int> SignalTurnRefreshResult;
    144   sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
    145       SignalCreatePermissionResult;
    146   void FlushRequests(int msg_type) { request_manager_.Flush(msg_type); }
    147   bool HasRequests() { return !request_manager_.empty(); }
    148   void set_credentials(RelayCredentials& credentials) {
    149     credentials_ = credentials;
    150   }
    151   // Finds the turn entry with |address| and sets its channel id.
    152   // Returns true if the entry is found.
    153   bool SetEntryChannelId(const rtc::SocketAddress& address, int channel_id);
    154 
    155  protected:
    156   TurnPort(rtc::Thread* thread,
    157            rtc::PacketSocketFactory* factory,
    158            rtc::Network* network,
    159            rtc::AsyncPacketSocket* socket,
    160            const std::string& username,
    161            const std::string& password,
    162            const ProtocolAddress& server_address,
    163            const RelayCredentials& credentials,
    164            int server_priority,
    165            const std::string& origin);
    166 
    167   TurnPort(rtc::Thread* thread,
    168            rtc::PacketSocketFactory* factory,
    169            rtc::Network* network,
    170            const rtc::IPAddress& ip,
    171            uint16_t min_port,
    172            uint16_t max_port,
    173            const std::string& username,
    174            const std::string& password,
    175            const ProtocolAddress& server_address,
    176            const RelayCredentials& credentials,
    177            int server_priority,
    178            const std::string& origin);
    179 
    180  private:
    181   enum {
    182     MSG_ALLOCATE_ERROR = MSG_FIRST_AVAILABLE,
    183     MSG_ALLOCATE_MISMATCH,
    184     MSG_TRY_ALTERNATE_SERVER,
    185     MSG_REFRESH_ERROR
    186   };
    187 
    188   typedef std::list<TurnEntry*> EntryList;
    189   typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
    190   typedef std::set<rtc::SocketAddress> AttemptedServerSet;
    191 
    192   virtual void OnMessage(rtc::Message* pmsg);
    193 
    194   bool CreateTurnClientSocket();
    195 
    196   void set_nonce(const std::string& nonce) { nonce_ = nonce; }
    197   void set_realm(const std::string& realm) {
    198     if (realm != realm_) {
    199       realm_ = realm;
    200       UpdateHash();
    201     }
    202   }
    203 
    204   // Shuts down the turn port, usually because of some fatal errors.
    205   void Close();
    206   void OnTurnRefreshError();
    207   bool SetAlternateServer(const rtc::SocketAddress& address);
    208   void ResolveTurnAddress(const rtc::SocketAddress& address);
    209   void OnResolveResult(rtc::AsyncResolverInterface* resolver);
    210 
    211   void AddRequestAuthInfo(StunMessage* msg);
    212   void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
    213   // Stun address from allocate success response.
    214   // Currently used only for testing.
    215   void OnStunAddress(const rtc::SocketAddress& address);
    216   void OnAllocateSuccess(const rtc::SocketAddress& address,
    217                          const rtc::SocketAddress& stun_address);
    218   void OnAllocateError();
    219   void OnAllocateRequestTimeout();
    220 
    221   void HandleDataIndication(const char* data, size_t size,
    222                             const rtc::PacketTime& packet_time);
    223   void HandleChannelData(int channel_id, const char* data, size_t size,
    224                          const rtc::PacketTime& packet_time);
    225   void DispatchPacket(const char* data, size_t size,
    226       const rtc::SocketAddress& remote_addr,
    227       ProtocolType proto, const rtc::PacketTime& packet_time);
    228 
    229   bool ScheduleRefresh(int lifetime);
    230   void SendRequest(StunRequest* request, int delay);
    231   int Send(const void* data, size_t size,
    232            const rtc::PacketOptions& options);
    233   void UpdateHash();
    234   bool UpdateNonce(StunMessage* response);
    235 
    236   bool HasPermission(const rtc::IPAddress& ipaddr) const;
    237   TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
    238   TurnEntry* FindEntry(int channel_id) const;
    239   bool EntryExists(TurnEntry* e);
    240   void CreateOrRefreshEntry(const rtc::SocketAddress& address);
    241   void DestroyEntry(TurnEntry* entry);
    242   // Destroys the entry only if |timestamp| matches the destruction timestamp
    243   // in |entry|.
    244   void DestroyEntryIfNotCancelled(TurnEntry* entry, uint32_t timestamp);
    245   void ScheduleEntryDestruction(TurnEntry* entry);
    246   void CancelEntryDestruction(TurnEntry* entry);
    247   void OnConnectionDestroyed(Connection* conn);
    248 
    249   // Destroys the connection with remote address |address|. Returns true if
    250   // a connection is found and destroyed.
    251   bool DestroyConnection(const rtc::SocketAddress& address);
    252 
    253   ProtocolAddress server_address_;
    254   RelayCredentials credentials_;
    255   AttemptedServerSet attempted_server_addresses_;
    256 
    257   rtc::AsyncPacketSocket* socket_;
    258   SocketOptionsMap socket_options_;
    259   rtc::AsyncResolverInterface* resolver_;
    260   int error_;
    261 
    262   StunRequestManager request_manager_;
    263   std::string realm_;       // From 401/438 response message.
    264   std::string nonce_;       // From 401/438 response message.
    265   std::string hash_;        // Digest of username:realm:password
    266 
    267   int next_channel_number_;
    268   EntryList entries_;
    269 
    270   PortState state_;
    271   // By default the value will be set to 0. This value will be used in
    272   // calculating the candidate priority.
    273   int server_priority_;
    274 
    275   // The number of retries made due to allocate mismatch error.
    276   size_t allocate_mismatch_retries_;
    277 
    278   rtc::AsyncInvoker invoker_;
    279 
    280   friend class TurnEntry;
    281   friend class TurnAllocateRequest;
    282   friend class TurnRefreshRequest;
    283   friend class TurnCreatePermissionRequest;
    284   friend class TurnChannelBindRequest;
    285 };
    286 
    287 }  // namespace cricket
    288 
    289 #endif  // WEBRTC_P2P_BASE_TURNPORT_H_
    290