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_BASE_PORTALLOCATOR_H_
12 #define WEBRTC_P2P_BASE_PORTALLOCATOR_H_
13 
14 #include <string>
15 #include <vector>
16 
17 #include "webrtc/p2p/base/portinterface.h"
18 #include "webrtc/base/helpers.h"
19 #include "webrtc/base/proxyinfo.h"
20 #include "webrtc/base/sigslot.h"
21 
22 namespace cricket {
23 
24 // PortAllocator is responsible for allocating Port types for a given
25 // P2PSocket. It also handles port freeing.
26 //
27 // Clients can override this class to control port allocation, including
28 // what kinds of ports are allocated.
29 
30 enum {
31   PORTALLOCATOR_DISABLE_UDP = 0x01,
32   PORTALLOCATOR_DISABLE_STUN = 0x02,
33   PORTALLOCATOR_DISABLE_RELAY = 0x04,
34   PORTALLOCATOR_DISABLE_TCP = 0x08,
35   PORTALLOCATOR_ENABLE_SHAKER = 0x10,
36   PORTALLOCATOR_ENABLE_BUNDLE = 0x20,
37   PORTALLOCATOR_ENABLE_IPV6 = 0x40,
38   PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80,
39   PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
40   PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
41   PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION = 0x400,
42 };
43 
44 const uint32 kDefaultPortAllocatorFlags = 0;
45 
46 const uint32 kDefaultStepDelay = 1000;  // 1 sec step delay.
47 // As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain
48 // internal. Less than 20ms is not acceptable. We choose 50ms as our default.
49 const uint32 kMinimumStepDelay = 50;
50 
51 // CF = CANDIDATE FILTER
52 enum {
53   CF_NONE = 0x0,
54   CF_HOST = 0x1,
55   CF_REFLEXIVE = 0x2,
56   CF_RELAY = 0x4,
57   CF_ALL = 0x7,
58 };
59 
60 class PortAllocatorSessionMuxer;
61 
62 class PortAllocatorSession : public sigslot::has_slots<> {
63  public:
64   // Content name passed in mostly for logging and debugging.
65   // TODO(mallinath) - Change username and password to ice_ufrag and ice_pwd.
66   PortAllocatorSession(const std::string& content_name,
67                        int component,
68                        const std::string& username,
69                        const std::string& password,
70                        uint32 flags);
71 
72   // Subclasses should clean up any ports created.
~PortAllocatorSession()73   virtual ~PortAllocatorSession() {}
74 
flags()75   uint32 flags() const { return flags_; }
set_flags(uint32 flags)76   void set_flags(uint32 flags) { flags_ = flags; }
content_name()77   std::string content_name() const { return content_name_; }
component()78   int component() const { return component_; }
79 
80   // Starts gathering STUN and Relay configurations.
81   virtual void StartGettingPorts() = 0;
82   virtual void StopGettingPorts() = 0;
83   virtual bool IsGettingPorts() = 0;
84 
85   sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady;
86   sigslot::signal2<PortAllocatorSession*,
87                    const std::vector<Candidate>&> SignalCandidatesReady;
88   sigslot::signal1<PortAllocatorSession*> SignalCandidatesAllocationDone;
89 
generation()90   virtual uint32 generation() { return generation_; }
set_generation(uint32 generation)91   virtual void set_generation(uint32 generation) { generation_ = generation; }
92   sigslot::signal1<PortAllocatorSession*> SignalDestroyed;
93 
94  protected:
username()95   const std::string& username() const { return username_; }
password()96   const std::string& password() const { return password_; }
97 
98   std::string content_name_;
99   int component_;
100 
101  private:
102   uint32 flags_;
103   uint32 generation_;
104   std::string username_;
105   std::string password_;
106 };
107 
108 class PortAllocator : public sigslot::has_slots<> {
109  public:
PortAllocator()110   PortAllocator() :
111       flags_(kDefaultPortAllocatorFlags),
112       min_port_(0),
113       max_port_(0),
114       step_delay_(kDefaultStepDelay),
115       allow_tcp_listen_(true),
116       candidate_filter_(CF_ALL) {
117     // This will allow us to have old behavior on non webrtc clients.
118   }
119   virtual ~PortAllocator();
120 
121   PortAllocatorSession* CreateSession(
122       const std::string& sid,
123       const std::string& content_name,
124       int component,
125       const std::string& ice_ufrag,
126       const std::string& ice_pwd);
127 
128   PortAllocatorSessionMuxer* GetSessionMuxer(const std::string& key) const;
129   void OnSessionMuxerDestroyed(PortAllocatorSessionMuxer* session);
130 
flags()131   uint32 flags() const { return flags_; }
set_flags(uint32 flags)132   void set_flags(uint32 flags) { flags_ = flags; }
133 
user_agent()134   const std::string& user_agent() const { return agent_; }
proxy()135   const rtc::ProxyInfo& proxy() const { return proxy_; }
set_proxy(const std::string & agent,const rtc::ProxyInfo & proxy)136   void set_proxy(const std::string& agent, const rtc::ProxyInfo& proxy) {
137     agent_ = agent;
138     proxy_ = proxy;
139   }
140 
141   // Gets/Sets the port range to use when choosing client ports.
min_port()142   int min_port() const { return min_port_; }
max_port()143   int max_port() const { return max_port_; }
SetPortRange(int min_port,int max_port)144   bool SetPortRange(int min_port, int max_port) {
145     if (min_port > max_port) {
146       return false;
147     }
148 
149     min_port_ = min_port;
150     max_port_ = max_port;
151     return true;
152   }
153 
step_delay()154   uint32 step_delay() const { return step_delay_; }
set_step_delay(uint32 delay)155   void set_step_delay(uint32 delay) {
156     step_delay_ = delay;
157   }
158 
allow_tcp_listen()159   bool allow_tcp_listen() const { return allow_tcp_listen_; }
set_allow_tcp_listen(bool allow_tcp_listen)160   void set_allow_tcp_listen(bool allow_tcp_listen) {
161     allow_tcp_listen_ = allow_tcp_listen;
162   }
163 
candidate_filter()164   uint32 candidate_filter() { return candidate_filter_; }
set_candidate_filter(uint32 filter)165   bool set_candidate_filter(uint32 filter) {
166     // TODO(mallinath) - Do transition check?
167     candidate_filter_ = filter;
168     return true;
169   }
170 
171   // Gets/Sets the Origin value used for WebRTC STUN requests.
origin()172   const std::string& origin() const { return origin_; }
set_origin(const std::string & origin)173   void set_origin(const std::string& origin) { origin_ = origin; }
174 
175  protected:
176   virtual PortAllocatorSession* CreateSessionInternal(
177       const std::string& content_name,
178       int component,
179       const std::string& ice_ufrag,
180       const std::string& ice_pwd) = 0;
181 
182   typedef std::map<std::string, PortAllocatorSessionMuxer*> SessionMuxerMap;
183 
184   uint32 flags_;
185   std::string agent_;
186   rtc::ProxyInfo proxy_;
187   int min_port_;
188   int max_port_;
189   uint32 step_delay_;
190   SessionMuxerMap muxers_;
191   bool allow_tcp_listen_;
192   uint32 candidate_filter_;
193   std::string origin_;
194 };
195 
196 }  // namespace cricket
197 
198 #endif  // WEBRTC_P2P_BASE_PORTALLOCATOR_H_
199