Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2012, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #ifndef TALK_P2P_BASE_TURNPORT_H_
     29 #define TALK_P2P_BASE_TURNPORT_H_
     30 
     31 #include <stdio.h>
     32 #include <list>
     33 #include <set>
     34 #include <string>
     35 
     36 #include "talk/p2p/base/port.h"
     37 #include "talk/p2p/client/basicportallocator.h"
     38 #include "webrtc/base/asyncpacketsocket.h"
     39 
     40 namespace rtc {
     41 class AsyncResolver;
     42 class SignalThread;
     43 }
     44 
     45 namespace cricket {
     46 
     47 extern const char TURN_PORT_TYPE[];
     48 class TurnAllocateRequest;
     49 class TurnEntry;
     50 
     51 class TurnPort : public Port {
     52  public:
     53   static TurnPort* Create(rtc::Thread* thread,
     54                           rtc::PacketSocketFactory* factory,
     55                           rtc::Network* network,
     56                           rtc::AsyncPacketSocket* socket,
     57                           const std::string& username,  // ice username.
     58                           const std::string& password,  // ice password.
     59                           const ProtocolAddress& server_address,
     60                           const RelayCredentials& credentials,
     61                           int server_priority) {
     62     return new TurnPort(thread, factory, network, socket,
     63                         username, password, server_address,
     64                         credentials, server_priority);
     65   }
     66 
     67   static TurnPort* Create(rtc::Thread* thread,
     68                           rtc::PacketSocketFactory* factory,
     69                           rtc::Network* network,
     70                           const rtc::IPAddress& ip,
     71                           int min_port, int max_port,
     72                           const std::string& username,  // ice username.
     73                           const std::string& password,  // ice password.
     74                           const ProtocolAddress& server_address,
     75                           const RelayCredentials& credentials,
     76                           int server_priority) {
     77     return new TurnPort(thread, factory, network, ip, min_port, max_port,
     78                         username, password, server_address, credentials,
     79                         server_priority);
     80   }
     81 
     82   virtual ~TurnPort();
     83 
     84   const ProtocolAddress& server_address() const { return server_address_; }
     85 
     86   bool connected() const { return connected_; }
     87   const RelayCredentials& credentials() const { return credentials_; }
     88 
     89   virtual void PrepareAddress();
     90   virtual Connection* CreateConnection(
     91       const Candidate& c, PortInterface::CandidateOrigin origin);
     92   virtual int SendTo(const void* data, size_t size,
     93                      const rtc::SocketAddress& addr,
     94                      const rtc::PacketOptions& options,
     95                      bool payload);
     96   virtual int SetOption(rtc::Socket::Option opt, int value);
     97   virtual int GetOption(rtc::Socket::Option opt, int* value);
     98   virtual int GetError();
     99 
    100   virtual bool HandleIncomingPacket(
    101       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
    102       const rtc::SocketAddress& remote_addr,
    103       const rtc::PacketTime& packet_time) {
    104     OnReadPacket(socket, data, size, remote_addr, packet_time);
    105     return true;
    106   }
    107   virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
    108                             const char* data, size_t size,
    109                             const rtc::SocketAddress& remote_addr,
    110                             const rtc::PacketTime& packet_time);
    111 
    112   virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
    113 
    114   void OnSocketConnect(rtc::AsyncPacketSocket* socket);
    115   void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
    116 
    117 
    118   const std::string& hash() const { return hash_; }
    119   const std::string& nonce() const { return nonce_; }
    120 
    121   int error() const { return error_; }
    122 
    123   void OnAllocateMismatch();
    124 
    125   rtc::AsyncPacketSocket* socket() const {
    126     return socket_;
    127   }
    128 
    129   // Signal with resolved server address.
    130   // Parameters are port, server address and resolved server address.
    131   // This signal will be sent only if server address is resolved successfully.
    132   sigslot::signal3<TurnPort*,
    133                    const rtc::SocketAddress&,
    134                    const rtc::SocketAddress&> SignalResolvedServerAddress;
    135 
    136   // This signal is only for testing purpose.
    137   sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
    138       SignalCreatePermissionResult;
    139 
    140  protected:
    141   TurnPort(rtc::Thread* thread,
    142            rtc::PacketSocketFactory* factory,
    143            rtc::Network* network,
    144            rtc::AsyncPacketSocket* socket,
    145            const std::string& username,
    146            const std::string& password,
    147            const ProtocolAddress& server_address,
    148            const RelayCredentials& credentials,
    149            int server_priority);
    150 
    151   TurnPort(rtc::Thread* thread,
    152            rtc::PacketSocketFactory* factory,
    153            rtc::Network* network,
    154            const rtc::IPAddress& ip,
    155            int min_port, int max_port,
    156            const std::string& username,
    157            const std::string& password,
    158            const ProtocolAddress& server_address,
    159            const RelayCredentials& credentials,
    160            int server_priority);
    161 
    162  private:
    163   enum {
    164     MSG_ERROR = MSG_FIRST_AVAILABLE,
    165     MSG_ALLOCATE_MISMATCH
    166   };
    167 
    168   typedef std::list<TurnEntry*> EntryList;
    169   typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
    170   typedef std::set<rtc::SocketAddress> AttemptedServerSet;
    171 
    172   virtual void OnMessage(rtc::Message* pmsg);
    173 
    174   bool CreateTurnClientSocket();
    175 
    176   void set_nonce(const std::string& nonce) { nonce_ = nonce; }
    177   void set_realm(const std::string& realm) {
    178     if (realm != realm_) {
    179       realm_ = realm;
    180       UpdateHash();
    181     }
    182   }
    183 
    184   bool SetAlternateServer(const rtc::SocketAddress& address);
    185   void ResolveTurnAddress(const rtc::SocketAddress& address);
    186   void OnResolveResult(rtc::AsyncResolverInterface* resolver);
    187 
    188   void AddRequestAuthInfo(StunMessage* msg);
    189   void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
    190   // Stun address from allocate success response.
    191   // Currently used only for testing.
    192   void OnStunAddress(const rtc::SocketAddress& address);
    193   void OnAllocateSuccess(const rtc::SocketAddress& address,
    194                          const rtc::SocketAddress& stun_address);
    195   void OnAllocateError();
    196   void OnAllocateRequestTimeout();
    197 
    198   void HandleDataIndication(const char* data, size_t size,
    199                             const rtc::PacketTime& packet_time);
    200   void HandleChannelData(int channel_id, const char* data, size_t size,
    201                          const rtc::PacketTime& packet_time);
    202   void DispatchPacket(const char* data, size_t size,
    203       const rtc::SocketAddress& remote_addr,
    204       ProtocolType proto, const rtc::PacketTime& packet_time);
    205 
    206   bool ScheduleRefresh(int lifetime);
    207   void SendRequest(StunRequest* request, int delay);
    208   int Send(const void* data, size_t size,
    209            const rtc::PacketOptions& options);
    210   void UpdateHash();
    211   bool UpdateNonce(StunMessage* response);
    212 
    213   bool HasPermission(const rtc::IPAddress& ipaddr) const;
    214   TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
    215   TurnEntry* FindEntry(int channel_id) const;
    216   TurnEntry* CreateEntry(const rtc::SocketAddress& address);
    217   void DestroyEntry(const rtc::SocketAddress& address);
    218   void OnConnectionDestroyed(Connection* conn);
    219 
    220   ProtocolAddress server_address_;
    221   RelayCredentials credentials_;
    222   AttemptedServerSet attempted_server_addresses_;
    223 
    224   rtc::AsyncPacketSocket* socket_;
    225   SocketOptionsMap socket_options_;
    226   rtc::AsyncResolverInterface* resolver_;
    227   int error_;
    228 
    229   StunRequestManager request_manager_;
    230   std::string realm_;       // From 401/438 response message.
    231   std::string nonce_;       // From 401/438 response message.
    232   std::string hash_;        // Digest of username:realm:password
    233 
    234   int next_channel_number_;
    235   EntryList entries_;
    236 
    237   bool connected_;
    238   // By default the value will be set to 0. This value will be used in
    239   // calculating the candidate priority.
    240   int server_priority_;
    241 
    242   // The number of retries made due to allocate mismatch error.
    243   size_t allocate_mismatch_retries_;
    244 
    245   friend class TurnEntry;
    246   friend class TurnAllocateRequest;
    247   friend class TurnRefreshRequest;
    248   friend class TurnCreatePermissionRequest;
    249   friend class TurnChannelBindRequest;
    250 };
    251 
    252 }  // namespace cricket
    253 
    254 #endif  // TALK_P2P_BASE_TURNPORT_H_
    255