• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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