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