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/base/helpers.h" 35 #include "talk/base/proxyinfo.h" 36 #include "talk/base/sigslot.h" 37 #include "talk/p2p/base/portinterface.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 const uint32 PORTALLOCATOR_DISABLE_UDP = 0x01; 48 const uint32 PORTALLOCATOR_DISABLE_STUN = 0x02; 49 const uint32 PORTALLOCATOR_DISABLE_RELAY = 0x04; 50 const uint32 PORTALLOCATOR_DISABLE_TCP = 0x08; 51 const uint32 PORTALLOCATOR_ENABLE_SHAKER = 0x10; 52 const uint32 PORTALLOCATOR_ENABLE_BUNDLE = 0x20; 53 const uint32 PORTALLOCATOR_ENABLE_IPV6 = 0x40; 54 const uint32 PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80; 55 const uint32 PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100; 56 const uint32 PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200; 57 58 const uint32 kDefaultPortAllocatorFlags = 0; 59 60 const uint32 kDefaultStepDelay = 1000; // 1 sec step delay. 61 // As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain 62 // internal. Less than 20ms is not acceptable. We choose 50ms as our default. 63 const uint32 kMinimumStepDelay = 50; 64 65 class PortAllocatorSessionMuxer; 66 67 class PortAllocatorSession : public sigslot::has_slots<> { 68 public: 69 // Content name passed in mostly for logging and debugging. 70 // TODO(mallinath) - Change username and password to ice_ufrag and ice_pwd. 71 PortAllocatorSession(const std::string& content_name, 72 int component, 73 const std::string& username, 74 const std::string& password, 75 uint32 flags); 76 77 // Subclasses should clean up any ports created. 78 virtual ~PortAllocatorSession() {} 79 80 uint32 flags() const { return flags_; } 81 void set_flags(uint32 flags) { flags_ = flags; } 82 std::string content_name() const { return content_name_; } 83 int component() const { return component_; } 84 85 // Starts gathering STUN and Relay configurations. 86 virtual void StartGettingPorts() = 0; 87 virtual void StopGettingPorts() = 0; 88 virtual bool IsGettingPorts() = 0; 89 90 sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady; 91 sigslot::signal2<PortAllocatorSession*, 92 const std::vector<Candidate>&> SignalCandidatesReady; 93 sigslot::signal1<PortAllocatorSession*> SignalCandidatesAllocationDone; 94 95 virtual uint32 generation() { return generation_; } 96 virtual void set_generation(uint32 generation) { generation_ = generation; } 97 sigslot::signal1<PortAllocatorSession*> SignalDestroyed; 98 99 protected: 100 const std::string& username() const { return username_; } 101 const std::string& password() const { return password_; } 102 103 std::string content_name_; 104 int component_; 105 106 private: 107 uint32 flags_; 108 uint32 generation_; 109 std::string username_; 110 std::string password_; 111 }; 112 113 class PortAllocator : public sigslot::has_slots<> { 114 public: 115 PortAllocator() : 116 flags_(kDefaultPortAllocatorFlags), 117 min_port_(0), 118 max_port_(0), 119 step_delay_(kDefaultStepDelay), 120 allow_tcp_listen_(true) { 121 // This will allow us to have old behavior on non webrtc clients. 122 } 123 virtual ~PortAllocator(); 124 125 PortAllocatorSession* CreateSession( 126 const std::string& sid, 127 const std::string& content_name, 128 int component, 129 const std::string& ice_ufrag, 130 const std::string& ice_pwd); 131 132 PortAllocatorSessionMuxer* GetSessionMuxer(const std::string& key) const; 133 void OnSessionMuxerDestroyed(PortAllocatorSessionMuxer* session); 134 135 uint32 flags() const { return flags_; } 136 void set_flags(uint32 flags) { flags_ = flags; } 137 138 const std::string& user_agent() const { return agent_; } 139 const talk_base::ProxyInfo& proxy() const { return proxy_; } 140 void set_proxy(const std::string& agent, const talk_base::ProxyInfo& proxy) { 141 agent_ = agent; 142 proxy_ = proxy; 143 } 144 145 // Gets/Sets the port range to use when choosing client ports. 146 int min_port() const { return min_port_; } 147 int max_port() const { return max_port_; } 148 bool SetPortRange(int min_port, int max_port) { 149 if (min_port > max_port) { 150 return false; 151 } 152 153 min_port_ = min_port; 154 max_port_ = max_port; 155 return true; 156 } 157 158 uint32 step_delay() const { return step_delay_; } 159 void set_step_delay(uint32 delay) { 160 ASSERT(delay >= kMinimumStepDelay); 161 step_delay_ = delay; 162 } 163 164 bool allow_tcp_listen() const { return allow_tcp_listen_; } 165 void set_allow_tcp_listen(bool allow_tcp_listen) { 166 allow_tcp_listen_ = allow_tcp_listen; 167 } 168 169 protected: 170 virtual PortAllocatorSession* CreateSessionInternal( 171 const std::string& content_name, 172 int component, 173 const std::string& ice_ufrag, 174 const std::string& ice_pwd) = 0; 175 176 typedef std::map<std::string, PortAllocatorSessionMuxer*> SessionMuxerMap; 177 178 uint32 flags_; 179 std::string agent_; 180 talk_base::ProxyInfo proxy_; 181 int min_port_; 182 int max_port_; 183 uint32 step_delay_; 184 SessionMuxerMap muxers_; 185 bool allow_tcp_listen_; 186 }; 187 188 } // namespace cricket 189 190 #endif // TALK_P2P_BASE_PORTALLOCATOR_H_ 191