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