1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_P2P_BASE_PORTALLOCATOR_H_ 29 #define TALK_P2P_BASE_PORTALLOCATOR_H_ 30 31 #include <string> 32 #include <vector> 33 34 #include "talk/p2p/base/portinterface.h" 35 #include "webrtc/base/helpers.h" 36 #include "webrtc/base/proxyinfo.h" 37 #include "webrtc/base/sigslot.h" 38 39 namespace cricket { 40 41 // PortAllocator is responsible for allocating Port types for a given 42 // P2PSocket. It also handles port freeing. 43 // 44 // Clients can override this class to control port allocation, including 45 // what kinds of ports are allocated. 46 47 enum { 48 PORTALLOCATOR_DISABLE_UDP = 0x01, 49 PORTALLOCATOR_DISABLE_STUN = 0x02, 50 PORTALLOCATOR_DISABLE_RELAY = 0x04, 51 PORTALLOCATOR_DISABLE_TCP = 0x08, 52 PORTALLOCATOR_ENABLE_SHAKER = 0x10, 53 PORTALLOCATOR_ENABLE_BUNDLE = 0x20, 54 PORTALLOCATOR_ENABLE_IPV6 = 0x40, 55 PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80, 56 PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100, 57 PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200, 58 }; 59 60 const uint32 kDefaultPortAllocatorFlags = 0; 61 62 const uint32 kDefaultStepDelay = 1000; // 1 sec step delay. 63 // As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain 64 // internal. Less than 20ms is not acceptable. We choose 50ms as our default. 65 const uint32 kMinimumStepDelay = 50; 66 67 // CF = CANDIDATE FILTER 68 enum { 69 CF_NONE = 0x0, 70 CF_HOST = 0x1, 71 CF_REFLEXIVE = 0x2, 72 CF_RELAY = 0x4, 73 CF_ALL = 0x7, 74 }; 75 76 class PortAllocatorSessionMuxer; 77 78 class PortAllocatorSession : public sigslot::has_slots<> { 79 public: 80 // Content name passed in mostly for logging and debugging. 81 // TODO(mallinath) - Change username and password to ice_ufrag and ice_pwd. 82 PortAllocatorSession(const std::string& content_name, 83 int component, 84 const std::string& username, 85 const std::string& password, 86 uint32 flags); 87 88 // Subclasses should clean up any ports created. ~PortAllocatorSession()89 virtual ~PortAllocatorSession() {} 90 flags()91 uint32 flags() const { return flags_; } set_flags(uint32 flags)92 void set_flags(uint32 flags) { flags_ = flags; } content_name()93 std::string content_name() const { return content_name_; } component()94 int component() const { return component_; } 95 96 // Starts gathering STUN and Relay configurations. 97 virtual void StartGettingPorts() = 0; 98 virtual void StopGettingPorts() = 0; 99 virtual bool IsGettingPorts() = 0; 100 101 sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady; 102 sigslot::signal2<PortAllocatorSession*, 103 const std::vector<Candidate>&> SignalCandidatesReady; 104 sigslot::signal1<PortAllocatorSession*> SignalCandidatesAllocationDone; 105 generation()106 virtual uint32 generation() { return generation_; } set_generation(uint32 generation)107 virtual void set_generation(uint32 generation) { generation_ = generation; } 108 sigslot::signal1<PortAllocatorSession*> SignalDestroyed; 109 110 protected: username()111 const std::string& username() const { return username_; } password()112 const std::string& password() const { return password_; } 113 114 std::string content_name_; 115 int component_; 116 117 private: 118 uint32 flags_; 119 uint32 generation_; 120 std::string username_; 121 std::string password_; 122 }; 123 124 class PortAllocator : public sigslot::has_slots<> { 125 public: PortAllocator()126 PortAllocator() : 127 flags_(kDefaultPortAllocatorFlags), 128 min_port_(0), 129 max_port_(0), 130 step_delay_(kDefaultStepDelay), 131 allow_tcp_listen_(true), 132 candidate_filter_(CF_ALL) { 133 // This will allow us to have old behavior on non webrtc clients. 134 } 135 virtual ~PortAllocator(); 136 137 PortAllocatorSession* CreateSession( 138 const std::string& sid, 139 const std::string& content_name, 140 int component, 141 const std::string& ice_ufrag, 142 const std::string& ice_pwd); 143 144 PortAllocatorSessionMuxer* GetSessionMuxer(const std::string& key) const; 145 void OnSessionMuxerDestroyed(PortAllocatorSessionMuxer* session); 146 flags()147 uint32 flags() const { return flags_; } set_flags(uint32 flags)148 void set_flags(uint32 flags) { flags_ = flags; } 149 user_agent()150 const std::string& user_agent() const { return agent_; } proxy()151 const rtc::ProxyInfo& proxy() const { return proxy_; } set_proxy(const std::string & agent,const rtc::ProxyInfo & proxy)152 void set_proxy(const std::string& agent, const rtc::ProxyInfo& proxy) { 153 agent_ = agent; 154 proxy_ = proxy; 155 } 156 157 // Gets/Sets the port range to use when choosing client ports. min_port()158 int min_port() const { return min_port_; } max_port()159 int max_port() const { return max_port_; } SetPortRange(int min_port,int max_port)160 bool SetPortRange(int min_port, int max_port) { 161 if (min_port > max_port) { 162 return false; 163 } 164 165 min_port_ = min_port; 166 max_port_ = max_port; 167 return true; 168 } 169 step_delay()170 uint32 step_delay() const { return step_delay_; } set_step_delay(uint32 delay)171 void set_step_delay(uint32 delay) { 172 step_delay_ = delay; 173 } 174 allow_tcp_listen()175 bool allow_tcp_listen() const { return allow_tcp_listen_; } set_allow_tcp_listen(bool allow_tcp_listen)176 void set_allow_tcp_listen(bool allow_tcp_listen) { 177 allow_tcp_listen_ = allow_tcp_listen; 178 } 179 candidate_filter()180 uint32 candidate_filter() { return candidate_filter_; } set_candidate_filter(uint32 filter)181 bool set_candidate_filter(uint32 filter) { 182 // TODO(mallinath) - Do transition check? 183 candidate_filter_ = filter; 184 return true; 185 } 186 187 protected: 188 virtual PortAllocatorSession* CreateSessionInternal( 189 const std::string& content_name, 190 int component, 191 const std::string& ice_ufrag, 192 const std::string& ice_pwd) = 0; 193 194 typedef std::map<std::string, PortAllocatorSessionMuxer*> SessionMuxerMap; 195 196 uint32 flags_; 197 std::string agent_; 198 rtc::ProxyInfo proxy_; 199 int min_port_; 200 int max_port_; 201 uint32 step_delay_; 202 SessionMuxerMap muxers_; 203 bool allow_tcp_listen_; 204 uint32 candidate_filter_; 205 }; 206 207 } // namespace cricket 208 209 #endif // TALK_P2P_BASE_PORTALLOCATOR_H_ 210