Home | History | Annotate | Download | only in client
      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_CLIENT_BASICPORTALLOCATOR_H_
     12 #define WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
     13 
     14 #include <string>
     15 #include <vector>
     16 
     17 #include "webrtc/p2p/base/portallocator.h"
     18 #include "webrtc/base/messagequeue.h"
     19 #include "webrtc/base/network.h"
     20 #include "webrtc/base/scoped_ptr.h"
     21 #include "webrtc/base/thread.h"
     22 
     23 namespace cricket {
     24 
     25 class BasicPortAllocator : public PortAllocator {
     26  public:
     27   BasicPortAllocator(rtc::NetworkManager* network_manager,
     28                      rtc::PacketSocketFactory* socket_factory);
     29   explicit BasicPortAllocator(rtc::NetworkManager* network_manager);
     30   BasicPortAllocator(rtc::NetworkManager* network_manager,
     31                      rtc::PacketSocketFactory* socket_factory,
     32                      const ServerAddresses& stun_servers);
     33   BasicPortAllocator(rtc::NetworkManager* network_manager,
     34                      const ServerAddresses& stun_servers,
     35                      const rtc::SocketAddress& relay_server_udp,
     36                      const rtc::SocketAddress& relay_server_tcp,
     37                      const rtc::SocketAddress& relay_server_ssl);
     38   virtual ~BasicPortAllocator();
     39 
     40   void SetIceServers(
     41       const ServerAddresses& stun_servers,
     42       const std::vector<RelayServerConfig>& turn_servers) override {
     43     stun_servers_ = stun_servers;
     44     turn_servers_ = turn_servers;
     45   }
     46 
     47   // Set to kDefaultNetworkIgnoreMask by default.
     48   void SetNetworkIgnoreMask(int network_ignore_mask) override {
     49     // TODO(phoglund): implement support for other types than loopback.
     50     // See https://code.google.com/p/webrtc/issues/detail?id=4288.
     51     // Then remove set_network_ignore_list from NetworkManager.
     52     network_ignore_mask_ = network_ignore_mask;
     53   }
     54 
     55   int network_ignore_mask() const { return network_ignore_mask_; }
     56 
     57   rtc::NetworkManager* network_manager() { return network_manager_; }
     58 
     59   // If socket_factory() is set to NULL each PortAllocatorSession
     60   // creates its own socket factory.
     61   rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
     62 
     63   const ServerAddresses& stun_servers() const {
     64     return stun_servers_;
     65   }
     66 
     67   const std::vector<RelayServerConfig>& turn_servers() const {
     68     return turn_servers_;
     69   }
     70   virtual void AddTurnServer(const RelayServerConfig& turn_server) {
     71     turn_servers_.push_back(turn_server);
     72   }
     73 
     74   PortAllocatorSession* CreateSessionInternal(
     75       const std::string& content_name,
     76       int component,
     77       const std::string& ice_ufrag,
     78       const std::string& ice_pwd) override;
     79 
     80  private:
     81   void Construct();
     82 
     83   rtc::NetworkManager* network_manager_;
     84   rtc::PacketSocketFactory* socket_factory_;
     85   ServerAddresses stun_servers_;
     86   std::vector<RelayServerConfig> turn_servers_;
     87   bool allow_tcp_listen_;
     88   int network_ignore_mask_ = rtc::kDefaultNetworkIgnoreMask;
     89 };
     90 
     91 struct PortConfiguration;
     92 class AllocationSequence;
     93 
     94 class BasicPortAllocatorSession : public PortAllocatorSession,
     95                                   public rtc::MessageHandler {
     96  public:
     97   BasicPortAllocatorSession(BasicPortAllocator* allocator,
     98                             const std::string& content_name,
     99                             int component,
    100                             const std::string& ice_ufrag,
    101                             const std::string& ice_pwd);
    102   ~BasicPortAllocatorSession();
    103 
    104   virtual BasicPortAllocator* allocator() { return allocator_; }
    105   rtc::Thread* network_thread() { return network_thread_; }
    106   rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
    107 
    108   void StartGettingPorts() override;
    109   void StopGettingPorts() override;
    110   void ClearGettingPorts() override;
    111   bool IsGettingPorts() override { return running_; }
    112 
    113  protected:
    114   // Starts the process of getting the port configurations.
    115   virtual void GetPortConfigurations();
    116 
    117   // Adds a port configuration that is now ready.  Once we have one for each
    118   // network (or a timeout occurs), we will start allocating ports.
    119   virtual void ConfigReady(PortConfiguration* config);
    120 
    121   // MessageHandler.  Can be overriden if message IDs do not conflict.
    122   void OnMessage(rtc::Message* message) override;
    123 
    124  private:
    125   class PortData {
    126    public:
    127     PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
    128     PortData(Port* port, AllocationSequence* seq)
    129     : port_(port), sequence_(seq), state_(STATE_INIT) {
    130     }
    131 
    132     Port* port() { return port_; }
    133     AllocationSequence* sequence() { return sequence_; }
    134     bool ready() const { return state_ == STATE_READY; }
    135     bool complete() const {
    136       // Returns true if candidate allocation has completed one way or another.
    137       return ((state_ == STATE_COMPLETE) || (state_ == STATE_ERROR));
    138     }
    139 
    140     void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
    141     void set_complete() {
    142       state_ = STATE_COMPLETE;
    143     }
    144     void set_error() {
    145       ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
    146       state_ = STATE_ERROR;
    147     }
    148 
    149    private:
    150     enum State {
    151       STATE_INIT,      // No candidates allocated yet.
    152       STATE_READY,     // At least one candidate is ready for process.
    153       STATE_COMPLETE,  // All candidates allocated and ready for process.
    154       STATE_ERROR      // Error in gathering candidates.
    155     };
    156     Port* port_;
    157     AllocationSequence* sequence_;
    158     State state_;
    159   };
    160 
    161   void OnConfigReady(PortConfiguration* config);
    162   void OnConfigStop();
    163   void AllocatePorts();
    164   void OnAllocate();
    165   void DoAllocate();
    166   void OnNetworksChanged();
    167   void OnAllocationSequenceObjectsCreated();
    168   void DisableEquivalentPhases(rtc::Network* network,
    169                                PortConfiguration* config,
    170                                uint32_t* flags);
    171   void AddAllocatedPort(Port* port, AllocationSequence* seq,
    172                         bool prepare_address);
    173   void OnCandidateReady(Port* port, const Candidate& c);
    174   void OnPortComplete(Port* port);
    175   void OnPortError(Port* port);
    176   void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
    177   void OnPortDestroyed(PortInterface* port);
    178   void OnShake();
    179   void MaybeSignalCandidatesAllocationDone();
    180   void OnPortAllocationComplete(AllocationSequence* seq);
    181   PortData* FindPort(Port* port);
    182   void GetNetworks(std::vector<rtc::Network*>* networks);
    183 
    184   bool CheckCandidateFilter(const Candidate& c);
    185 
    186   BasicPortAllocator* allocator_;
    187   rtc::Thread* network_thread_;
    188   rtc::scoped_ptr<rtc::PacketSocketFactory> owned_socket_factory_;
    189   rtc::PacketSocketFactory* socket_factory_;
    190   bool allocation_started_;
    191   bool network_manager_started_;
    192   bool running_;  // set when StartGetAllPorts is called
    193   bool allocation_sequences_created_;
    194   std::vector<PortConfiguration*> configs_;
    195   std::vector<AllocationSequence*> sequences_;
    196   std::vector<PortData> ports_;
    197 
    198   friend class AllocationSequence;
    199 };
    200 
    201 // Records configuration information useful in creating ports.
    202 // TODO(deadbeef): Rename "relay" to "turn_server" in this struct.
    203 struct PortConfiguration : public rtc::MessageData {
    204   // TODO(jiayl): remove |stun_address| when Chrome is updated.
    205   rtc::SocketAddress stun_address;
    206   ServerAddresses stun_servers;
    207   std::string username;
    208   std::string password;
    209 
    210   typedef std::vector<RelayServerConfig> RelayList;
    211   RelayList relays;
    212 
    213   // TODO(jiayl): remove this ctor when Chrome is updated.
    214   PortConfiguration(const rtc::SocketAddress& stun_address,
    215                     const std::string& username,
    216                     const std::string& password);
    217 
    218   PortConfiguration(const ServerAddresses& stun_servers,
    219                     const std::string& username,
    220                     const std::string& password);
    221 
    222   // Returns addresses of both the explicitly configured STUN servers,
    223   // and TURN servers that should be used as STUN servers.
    224   ServerAddresses StunServers();
    225 
    226   // Adds another relay server, with the given ports and modifier, to the list.
    227   void AddRelay(const RelayServerConfig& config);
    228 
    229   // Determines whether the given relay server supports the given protocol.
    230   bool SupportsProtocol(const RelayServerConfig& relay,
    231                         ProtocolType type) const;
    232   bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
    233   // Helper method returns the server addresses for the matching RelayType and
    234   // Protocol type.
    235   ServerAddresses GetRelayServerAddresses(
    236       RelayType turn_type, ProtocolType type) const;
    237 };
    238 
    239 class UDPPort;
    240 class TurnPort;
    241 
    242 // Performs the allocation of ports, in a sequenced (timed) manner, for a given
    243 // network and IP address.
    244 class AllocationSequence : public rtc::MessageHandler,
    245                            public sigslot::has_slots<> {
    246  public:
    247   enum State {
    248     kInit,       // Initial state.
    249     kRunning,    // Started allocating ports.
    250     kStopped,    // Stopped from running.
    251     kCompleted,  // All ports are allocated.
    252 
    253     // kInit --> kRunning --> {kCompleted|kStopped}
    254   };
    255   AllocationSequence(BasicPortAllocatorSession* session,
    256                      rtc::Network* network,
    257                      PortConfiguration* config,
    258                      uint32_t flags);
    259   ~AllocationSequence();
    260   bool Init();
    261   void Clear();
    262   void OnNetworkRemoved();
    263 
    264   State state() const { return state_; }
    265   const rtc::Network* network() const { return network_; }
    266   bool network_removed() const { return network_removed_; }
    267 
    268   // Disables the phases for a new sequence that this one already covers for an
    269   // equivalent network setup.
    270   void DisableEquivalentPhases(rtc::Network* network,
    271                                PortConfiguration* config,
    272                                uint32_t* flags);
    273 
    274   // Starts and stops the sequence.  When started, it will continue allocating
    275   // new ports on its own timed schedule.
    276   void Start();
    277   void Stop();
    278 
    279   // MessageHandler
    280   void OnMessage(rtc::Message* msg);
    281 
    282   void EnableProtocol(ProtocolType proto);
    283   bool ProtocolEnabled(ProtocolType proto) const;
    284 
    285   // Signal from AllocationSequence, when it's done with allocating ports.
    286   // This signal is useful, when port allocation fails which doesn't result
    287   // in any candidates. Using this signal BasicPortAllocatorSession can send
    288   // its candidate discovery conclusion signal. Without this signal,
    289   // BasicPortAllocatorSession doesn't have any event to trigger signal. This
    290   // can also be achieved by starting timer in BPAS.
    291   sigslot::signal1<AllocationSequence*> SignalPortAllocationComplete;
    292 
    293  protected:
    294   // For testing.
    295   void CreateTurnPort(const RelayServerConfig& config);
    296 
    297  private:
    298   typedef std::vector<ProtocolType> ProtocolList;
    299 
    300   bool IsFlagSet(uint32_t flag) { return ((flags_ & flag) != 0); }
    301   void CreateUDPPorts();
    302   void CreateTCPPorts();
    303   void CreateStunPorts();
    304   void CreateRelayPorts();
    305   void CreateGturnPort(const RelayServerConfig& config);
    306 
    307   void OnReadPacket(rtc::AsyncPacketSocket* socket,
    308                     const char* data,
    309                     size_t size,
    310                     const rtc::SocketAddress& remote_addr,
    311                     const rtc::PacketTime& packet_time);
    312 
    313   void OnPortDestroyed(PortInterface* port);
    314 
    315   BasicPortAllocatorSession* session_;
    316   bool network_removed_ = false;
    317   rtc::Network* network_;
    318   rtc::IPAddress ip_;
    319   PortConfiguration* config_;
    320   State state_;
    321   uint32_t flags_;
    322   ProtocolList protocols_;
    323   rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
    324   // There will be only one udp port per AllocationSequence.
    325   UDPPort* udp_port_;
    326   std::vector<TurnPort*> turn_ports_;
    327   int phase_;
    328 };
    329 
    330 }  // namespace cricket
    331 
    332 #endif  // WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
    333