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