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 SetIceServers(const ServerAddresses & stun_servers,const std::vector<RelayServerConfig> & turn_servers)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. SetNetworkIgnoreMask(int network_ignore_mask)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 network_ignore_mask()55 int network_ignore_mask() const { return network_ignore_mask_; } 56 network_manager()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. socket_factory()61 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; } 62 stun_servers()63 const ServerAddresses& stun_servers() const { 64 return stun_servers_; 65 } 66 turn_servers()67 const std::vector<RelayServerConfig>& turn_servers() const { 68 return turn_servers_; 69 } AddTurnServer(const RelayServerConfig & turn_server)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 allocator()104 virtual BasicPortAllocator* allocator() { return allocator_; } network_thread()105 rtc::Thread* network_thread() { return network_thread_; } socket_factory()106 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; } 107 108 void StartGettingPorts() override; 109 void StopGettingPorts() override; 110 void ClearGettingPorts() override; IsGettingPorts()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: PortData()127 PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {} PortData(Port * port,AllocationSequence * seq)128 PortData(Port* port, AllocationSequence* seq) 129 : port_(port), sequence_(seq), state_(STATE_INIT) { 130 } 131 port()132 Port* port() { return port_; } sequence()133 AllocationSequence* sequence() { return sequence_; } ready()134 bool ready() const { return state_ == STATE_READY; } complete()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 set_ready()140 void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; } set_complete()141 void set_complete() { 142 state_ = STATE_COMPLETE; 143 } set_error()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 state()264 State state() const { return state_; } network()265 const rtc::Network* network() const { return network_; } network_removed()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 IsFlagSet(uint32_t flag)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