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_STUNPORT_H_
     12 #define WEBRTC_P2P_BASE_STUNPORT_H_
     13 
     14 #include <string>
     15 
     16 #include "webrtc/p2p/base/port.h"
     17 #include "webrtc/p2p/base/stunrequest.h"
     18 #include "webrtc/base/asyncpacketsocket.h"
     19 
     20 // TODO(mallinath) - Rename stunport.cc|h to udpport.cc|h.
     21 namespace rtc {
     22 class AsyncResolver;
     23 class SignalThread;
     24 }
     25 
     26 namespace cricket {
     27 
     28 // Communicates using the address on the outside of a NAT.
     29 class UDPPort : public Port {
     30  public:
     31   static UDPPort* Create(rtc::Thread* thread,
     32                          rtc::PacketSocketFactory* factory,
     33                          rtc::Network* network,
     34                          rtc::AsyncPacketSocket* socket,
     35                          const std::string& username,
     36                          const std::string& password,
     37                          const std::string& origin,
     38                          bool emit_local_for_anyaddress) {
     39     UDPPort* port = new UDPPort(thread, factory, network, socket, username,
     40                                 password, origin, emit_local_for_anyaddress);
     41     if (!port->Init()) {
     42       delete port;
     43       port = NULL;
     44     }
     45     return port;
     46   }
     47 
     48   static UDPPort* Create(rtc::Thread* thread,
     49                          rtc::PacketSocketFactory* factory,
     50                          rtc::Network* network,
     51                          const rtc::IPAddress& ip,
     52                          uint16_t min_port,
     53                          uint16_t max_port,
     54                          const std::string& username,
     55                          const std::string& password,
     56                          const std::string& origin,
     57                          bool emit_local_for_anyaddress) {
     58     UDPPort* port =
     59         new UDPPort(thread, factory, network, ip, min_port, max_port, username,
     60                     password, origin, emit_local_for_anyaddress);
     61     if (!port->Init()) {
     62       delete port;
     63       port = NULL;
     64     }
     65     return port;
     66   }
     67 
     68   virtual ~UDPPort();
     69 
     70   rtc::SocketAddress GetLocalAddress() const {
     71     return socket_->GetLocalAddress();
     72   }
     73 
     74   const ServerAddresses& server_addresses() const {
     75     return server_addresses_;
     76   }
     77   void
     78   set_server_addresses(const ServerAddresses& addresses) {
     79     server_addresses_ = addresses;
     80   }
     81 
     82   virtual void PrepareAddress();
     83 
     84   virtual Connection* CreateConnection(const Candidate& address,
     85                                        CandidateOrigin origin);
     86   virtual int SetOption(rtc::Socket::Option opt, int value);
     87   virtual int GetOption(rtc::Socket::Option opt, int* value);
     88   virtual int GetError();
     89 
     90   virtual bool HandleIncomingPacket(
     91       rtc::AsyncPacketSocket* socket, const char* data, size_t size,
     92       const rtc::SocketAddress& remote_addr,
     93       const rtc::PacketTime& packet_time) {
     94     // All packets given to UDP port will be consumed.
     95     OnReadPacket(socket, data, size, remote_addr, packet_time);
     96     return true;
     97   }
     98   virtual bool SupportsProtocol(const std::string& protocol) const {
     99     return protocol == UDP_PROTOCOL_NAME;
    100   }
    101 
    102   void set_stun_keepalive_delay(int delay) {
    103     stun_keepalive_delay_ = delay;
    104   }
    105   int stun_keepalive_delay() const {
    106     return stun_keepalive_delay_;
    107   }
    108 
    109  protected:
    110   UDPPort(rtc::Thread* thread,
    111           rtc::PacketSocketFactory* factory,
    112           rtc::Network* network,
    113           const rtc::IPAddress& ip,
    114           uint16_t min_port,
    115           uint16_t max_port,
    116           const std::string& username,
    117           const std::string& password,
    118           const std::string& origin,
    119           bool emit_local_for_anyaddress);
    120 
    121   UDPPort(rtc::Thread* thread,
    122           rtc::PacketSocketFactory* factory,
    123           rtc::Network* network,
    124           rtc::AsyncPacketSocket* socket,
    125           const std::string& username,
    126           const std::string& password,
    127           const std::string& origin,
    128           bool emit_local_for_anyaddress);
    129 
    130   bool Init();
    131 
    132   virtual int SendTo(const void* data, size_t size,
    133                      const rtc::SocketAddress& addr,
    134                      const rtc::PacketOptions& options,
    135                      bool payload);
    136 
    137   void OnLocalAddressReady(rtc::AsyncPacketSocket* socket,
    138                            const rtc::SocketAddress& address);
    139   void OnReadPacket(rtc::AsyncPacketSocket* socket,
    140                     const char* data, size_t size,
    141                     const rtc::SocketAddress& remote_addr,
    142                     const rtc::PacketTime& packet_time);
    143 
    144   void OnSentPacket(rtc::AsyncPacketSocket* socket,
    145                     const rtc::SentPacket& sent_packet);
    146 
    147   void OnReadyToSend(rtc::AsyncPacketSocket* socket);
    148 
    149   // This method will send STUN binding request if STUN server address is set.
    150   void MaybePrepareStunCandidate();
    151 
    152   void SendStunBindingRequests();
    153 
    154   // Helper function which will set |addr|'s IP to the default local address if
    155   // |addr| is the "any" address and |emit_local_for_anyaddress_| is true. When
    156   // returning false, it indicates that the operation has failed and the
    157   // address shouldn't be used by any candidate.
    158   bool MaybeSetDefaultLocalAddress(rtc::SocketAddress* addr) const;
    159 
    160  private:
    161   // A helper class which can be called repeatedly to resolve multiple
    162   // addresses, as opposed to rtc::AsyncResolverInterface, which can only
    163   // resolve one address per instance.
    164   class AddressResolver : public sigslot::has_slots<> {
    165    public:
    166     explicit AddressResolver(rtc::PacketSocketFactory* factory);
    167     ~AddressResolver();
    168 
    169     void Resolve(const rtc::SocketAddress& address);
    170     bool GetResolvedAddress(const rtc::SocketAddress& input,
    171                             int family,
    172                             rtc::SocketAddress* output) const;
    173 
    174     // The signal is sent when resolving the specified address is finished. The
    175     // first argument is the input address, the second argument is the error
    176     // or 0 if it succeeded.
    177     sigslot::signal2<const rtc::SocketAddress&, int> SignalDone;
    178 
    179    private:
    180     typedef std::map<rtc::SocketAddress,
    181                      rtc::AsyncResolverInterface*> ResolverMap;
    182 
    183     void OnResolveResult(rtc::AsyncResolverInterface* resolver);
    184 
    185     rtc::PacketSocketFactory* socket_factory_;
    186     ResolverMap resolvers_;
    187   };
    188 
    189   // DNS resolution of the STUN server.
    190   void ResolveStunAddress(const rtc::SocketAddress& stun_addr);
    191   void OnResolveResult(const rtc::SocketAddress& input, int error);
    192 
    193   void SendStunBindingRequest(const rtc::SocketAddress& stun_addr);
    194 
    195   // Below methods handles binding request responses.
    196   void OnStunBindingRequestSucceeded(
    197       const rtc::SocketAddress& stun_server_addr,
    198       const rtc::SocketAddress& stun_reflected_addr);
    199   void OnStunBindingOrResolveRequestFailed(
    200       const rtc::SocketAddress& stun_server_addr);
    201 
    202   // Sends STUN requests to the server.
    203   void OnSendPacket(const void* data, size_t size, StunRequest* req);
    204 
    205   // TODO(mallinaht) - Move this up to cricket::Port when SignalAddressReady is
    206   // changed to SignalPortReady.
    207   void MaybeSetPortCompleteOrError();
    208 
    209   bool HasCandidateWithAddress(const rtc::SocketAddress& addr) const;
    210 
    211   ServerAddresses server_addresses_;
    212   ServerAddresses bind_request_succeeded_servers_;
    213   ServerAddresses bind_request_failed_servers_;
    214   StunRequestManager requests_;
    215   rtc::AsyncPacketSocket* socket_;
    216   int error_;
    217   rtc::scoped_ptr<AddressResolver> resolver_;
    218   bool ready_;
    219   int stun_keepalive_delay_;
    220 
    221   // This is true by default and false when
    222   // PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE is specified.
    223   bool emit_local_for_anyaddress_;
    224 
    225   friend class StunBindingRequest;
    226 };
    227 
    228 class StunPort : public UDPPort {
    229  public:
    230   static StunPort* Create(rtc::Thread* thread,
    231                           rtc::PacketSocketFactory* factory,
    232                           rtc::Network* network,
    233                           const rtc::IPAddress& ip,
    234                           uint16_t min_port,
    235                           uint16_t max_port,
    236                           const std::string& username,
    237                           const std::string& password,
    238                           const ServerAddresses& servers,
    239                           const std::string& origin) {
    240     StunPort* port = new StunPort(thread, factory, network,
    241                                   ip, min_port, max_port,
    242                                   username, password, servers,
    243                                   origin);
    244     if (!port->Init()) {
    245       delete port;
    246       port = NULL;
    247     }
    248     return port;
    249   }
    250 
    251   virtual ~StunPort() {}
    252 
    253   virtual void PrepareAddress() {
    254     SendStunBindingRequests();
    255   }
    256 
    257  protected:
    258   StunPort(rtc::Thread* thread,
    259            rtc::PacketSocketFactory* factory,
    260            rtc::Network* network,
    261            const rtc::IPAddress& ip,
    262            uint16_t min_port,
    263            uint16_t max_port,
    264            const std::string& username,
    265            const std::string& password,
    266            const ServerAddresses& servers,
    267            const std::string& origin)
    268       : UDPPort(thread,
    269                 factory,
    270                 network,
    271                 ip,
    272                 min_port,
    273                 max_port,
    274                 username,
    275                 password,
    276                 origin,
    277                 false) {
    278     // UDPPort will set these to local udp, updating these to STUN.
    279     set_type(STUN_PORT_TYPE);
    280     set_server_addresses(servers);
    281   }
    282 };
    283 
    284 }  // namespace cricket
    285 
    286 #endif  // WEBRTC_P2P_BASE_STUNPORT_H_
    287