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