10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004--2005, Google Inc. 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer. 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * and/or other materials provided with the distribution. 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * derived from this software without specific prior written permission. 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */ 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/client/basicportallocator.h" 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <string> 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <vector> 320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/base/common.h" 340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/base/helpers.h" 350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/base/logging.h" 360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/basicpacketsocketfactory.h" 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/common.h" 380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/port.h" 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/relayport.h" 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/stunport.h" 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/tcpport.h" 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/turnport.h" 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/udpport.h" 440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing talk_base::CreateRandomId; 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing talk_base::CreateRandomString; 470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace { 490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 MSG_CONFIG_START = 1; 510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 MSG_CONFIG_READY = 2; 520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 MSG_ALLOCATE = 3; 530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 MSG_ALLOCATION_PHASE = 4; 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 MSG_SHAKE = 5; 550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 MSG_SEQUENCEOBJECTS_CREATED = 6; 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 MSG_CONFIG_STOP = 7; 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 ALLOCATE_DELAY = 250; 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int PHASE_UDP = 0; 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int PHASE_RELAY = 1; 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int PHASE_TCP = 2; 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int PHASE_SSLTCP = 3; 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int kNumPhases = 4; 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int SHAKE_MIN_DELAY = 45 * 1000; // 45 seconds 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst int SHAKE_MAX_DELAY = 90 * 1000; // 90 seconds 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint ShakeDelay() { 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int range = SHAKE_MAX_DELAY - SHAKE_MIN_DELAY + 1; 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SHAKE_MIN_DELAY + CreateRandomId() % range; 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst uint32 DISABLE_ALL_PHASES = 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PORTALLOCATOR_DISABLE_UDP 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org | PORTALLOCATOR_DISABLE_TCP 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org | PORTALLOCATOR_DISABLE_STUN 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org | PORTALLOCATOR_DISABLE_RELAY; 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Performs the allocation of ports, in a sequenced (timed) manner, for a given 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// network and IP address. 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass AllocationSequence : public talk_base::MessageHandler, 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public sigslot::has_slots<> { 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org enum State { 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org kInit, // Initial state. 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org kRunning, // Started allocating ports. 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org kStopped, // Stopped from running. 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org kCompleted, // All ports are allocated. 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // kInit --> kRunning --> {kCompleted|kStopped} 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org }; 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AllocationSequence(BasicPortAllocatorSession* session, 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::Network* network, 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration* config, 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 flags); 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ~AllocationSequence(); 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool Init(); 10509bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org void Clear(); 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org State state() const { return state_; } 1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Disables the phases for a new sequence that this one already covers for an 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // equivalent network setup. 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void DisableEquivalentPhases(talk_base::Network* network, 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration* config, uint32* flags); 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Starts and stops the sequence. When started, it will continue allocating 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // new ports on its own timed schedule. 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void Start(); 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void Stop(); 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // MessageHandler 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void OnMessage(talk_base::Message* msg); 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void EnableProtocol(ProtocolType proto); 1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool ProtocolEnabled(ProtocolType proto) const; 1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Signal from AllocationSequence, when it's done with allocating ports. 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This signal is useful, when port allocation fails which doesn't result 1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // in any candidates. Using this signal BasicPortAllocatorSession can send 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // its candidate discovery conclusion signal. Without this signal, 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // BasicPortAllocatorSession doesn't have any event to trigger signal. This 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // can also be achieved by starting timer in BPAS. 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sigslot::signal1<AllocationSequence*> SignalPortAllocationComplete; 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private: 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org typedef std::vector<ProtocolType> ProtocolList; 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool IsFlagSet(uint32 flag) { 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return ((flags_ & flag) != 0); 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void CreateUDPPorts(); 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void CreateTCPPorts(); 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void CreateStunPorts(); 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void CreateRelayPorts(); 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void CreateGturnPort(const RelayServerConfig& config); 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void CreateTurnPort(const RelayServerConfig& config); 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void OnReadPacket(talk_base::AsyncPacketSocket* socket, 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const char* data, size_t size, 148f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org const talk_base::SocketAddress& remote_addr, 149f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org const talk_base::PacketTime& packet_time); 150f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void OnPortDestroyed(PortInterface* port); 152afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org void OnResolvedTurnServerAddress( 153afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org TurnPort* port, const talk_base::SocketAddress& server_address, 154afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org const talk_base::SocketAddress& resolved_server_address); 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org BasicPortAllocatorSession* session_; 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::Network* network_; 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::IPAddress ip_; 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration* config_; 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org State state_; 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 flags_; 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ProtocolList protocols_; 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::scoped_ptr<talk_base::AsyncPacketSocket> udp_socket_; 164afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // There will be only one udp port per AllocationSequence. 165ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org UDPPort* udp_port_; 166afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // Keeping a map for turn ports keyed with server addresses. 167afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org std::map<talk_base::SocketAddress, Port*> turn_ports_; 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int phase_; 1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// BasicPortAllocator 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocator::BasicPortAllocator( 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::NetworkManager* network_manager, 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::PacketSocketFactory* socket_factory) 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : network_manager_(network_manager), 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket_factory_(socket_factory) { 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(socket_factory_ != NULL); 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Construct(); 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocator::BasicPortAllocator( 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::NetworkManager* network_manager) 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : network_manager_(network_manager), 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket_factory_(NULL) { 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Construct(); 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocator::BasicPortAllocator( 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::NetworkManager* network_manager, 1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::PacketSocketFactory* socket_factory, 1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const talk_base::SocketAddress& stun_address) 1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : network_manager_(network_manager), 1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket_factory_(socket_factory), 1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stun_address_(stun_address) { 1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(socket_factory_ != NULL); 1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Construct(); 1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocator::BasicPortAllocator( 2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::NetworkManager* network_manager, 2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const talk_base::SocketAddress& stun_address, 2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const talk_base::SocketAddress& relay_address_udp, 2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const talk_base::SocketAddress& relay_address_tcp, 2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const talk_base::SocketAddress& relay_address_ssl) 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : network_manager_(network_manager), 2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket_factory_(NULL), 2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org stun_address_(stun_address) { 2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayServerConfig config(RELAY_GTURN); 210ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org if (!relay_address_udp.IsNil()) 2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config.ports.push_back(ProtocolAddress(relay_address_udp, PROTO_UDP)); 212ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org if (!relay_address_tcp.IsNil()) 2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config.ports.push_back(ProtocolAddress(relay_address_tcp, PROTO_TCP)); 214ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org if (!relay_address_ssl.IsNil()) 2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config.ports.push_back(ProtocolAddress(relay_address_ssl, PROTO_SSLTCP)); 216ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org 217ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org if (!config.ports.empty()) 218ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org AddRelay(config); 2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Construct(); 2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocator::Construct() { 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allow_tcp_listen_ = true; 2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocator::~BasicPortAllocator() { 2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgPortAllocatorSession *BasicPortAllocator::CreateSessionInternal( 2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& content_name, int component, 2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& ice_ufrag, const std::string& ice_pwd) { 2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return new BasicPortAllocatorSession(this, content_name, component, 2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ice_ufrag, ice_pwd); 2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// BasicPortAllocatorSession 2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocatorSession::BasicPortAllocatorSession( 2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org BasicPortAllocator *allocator, 2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& content_name, 2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int component, 2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& ice_ufrag, 2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& ice_pwd) 2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : PortAllocatorSession(content_name, component, 2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ice_ufrag, ice_pwd, allocator->flags()), 2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocator_(allocator), network_thread_(NULL), 2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket_factory_(allocator->socket_factory()), 2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocation_started_(false), 2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_manager_started_(false), 2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org running_(false), 2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocation_sequences_created_(false) { 2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocator_->network_manager()->SignalNetworksChanged.connect( 2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, &BasicPortAllocatorSession::OnNetworksChanged); 2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocator_->network_manager()->StartUpdating(); 2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocatorSession::~BasicPortAllocatorSession() { 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocator_->network_manager()->StopUpdating(); 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (network_thread_ != NULL) 2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->Clear(this); 2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 26209bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org for (uint32 i = 0; i < sequences_.size(); ++i) { 26309bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org // AllocationSequence should clear it's map entry for turn ports before 26409bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org // ports are destroyed. 26509bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org sequences_[i]->Clear(); 26609bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org } 26709bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org 2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<PortData>::iterator it; 2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (it = ports_.begin(); it != ports_.end(); it++) 2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete it->port(); 2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (uint32 i = 0; i < configs_.size(); ++i) 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete configs_[i]; 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (uint32 i = 0; i < sequences_.size(); ++i) 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete sequences_[i]; 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::StartGettingPorts() { 2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_ = talk_base::Thread::Current(); 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!socket_factory_) { 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org owned_socket_factory_.reset( 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org new talk_base::BasicPacketSocketFactory(network_thread_)); 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket_factory_ = owned_socket_factory_.get(); 2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org running_ = true; 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->Post(this, MSG_CONFIG_START); 2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (flags() & PORTALLOCATOR_ENABLE_SHAKER) 2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE); 2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::StopGettingPorts() { 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org running_ = false; 2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->Clear(this, MSG_ALLOCATE); 2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (uint32 i = 0; i < sequences_.size(); ++i) 2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sequences_[i]->Stop(); 3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->Post(this, MSG_CONFIG_STOP); 3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnMessage(talk_base::Message *message) { 3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (message->message_id) { 3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_CONFIG_START: 3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org GetPortConfigurations(); 3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_CONFIG_READY: 3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnConfigReady(static_cast<PortConfiguration*>(message->pdata)); 3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_ALLOCATE: 3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnAllocate(); 3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_SHAKE: 3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnShake(); 3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_SEQUENCEOBJECTS_CREATED: 3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnAllocationSequenceObjectsCreated(); 3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case MSG_CONFIG_STOP: 3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org OnConfigStop(); 3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::GetPortConfigurations() { 3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration* config = new PortConfiguration(allocator_->stun_address(), 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org username(), 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org password()); 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < allocator_->relays().size(); ++i) { 3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config->AddRelay(allocator_->relays()[i]); 3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ConfigReady(config); 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::ConfigReady(PortConfiguration* config) { 3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->Post(this, MSG_CONFIG_READY, config); 3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Adds a configuration to the list. 3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnConfigReady(PortConfiguration* config) { 3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (config) 3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org configs_.push_back(config); 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AllocatePorts(); 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnConfigStop() { 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If any of the allocated ports have not completed the candidates allocation, 3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // mark those as error. Since session doesn't need any new candidates 3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // at this stage of the allocation, it's safe to discard any new candidates. 3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool send_signal = false; 3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<PortData>::iterator it = ports_.begin(); 3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != ports_.end(); ++it) { 3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!it->complete()) { 3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Updating port state to error, which didn't finish allocating candidates 3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // yet. 3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it->set_error(); 3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_signal = true; 3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Did we stop any running sequences? 3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<AllocationSequence*>::iterator it = sequences_.begin(); 3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != sequences_.end() && !send_signal; ++it) { 3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((*it)->state() == AllocationSequence::kStopped) { 3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org send_signal = true; 3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we stopped anything that was running, send a done signal now. 3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (send_signal) { 3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MaybeSignalCandidatesAllocationDone(); 3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::AllocatePorts() { 3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->Post(this, MSG_ALLOCATE); 3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnAllocate() { 3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (network_manager_started_) 3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DoAllocate(); 3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocation_started_ = true; 4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (running_) 4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->PostDelayed(ALLOCATE_DELAY, this, MSG_ALLOCATE); 4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// For each network, see if we have a sequence that covers it already. If not, 4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// create a new sequence to create the appropriate ports. 4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::DoAllocate() { 4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool done_signal_needed = false; 4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<talk_base::Network*> networks; 4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocator_->network_manager()->GetNetworks(&networks); 4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (networks.empty()) { 4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Machine has no networks; no ports will be allocated"; 4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org done_signal_needed = true; 4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (uint32 i = 0; i < networks.size(); ++i) { 4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration* config = NULL; 4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (configs_.size() > 0) 4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config = configs_.back(); 4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 sequence_flags = flags(); 4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) { 4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If all the ports are disabled we should just fire the allocation 4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // done event and return. 4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org done_signal_needed = true; 4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Disables phases that are not specified in this config. 4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!config || config->stun_address.IsNil()) { 4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // No STUN ports specified in this config. 4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sequence_flags |= PORTALLOCATOR_DISABLE_STUN; 4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!config || config->relays.empty()) { 4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // No relay ports specified in this config. 4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sequence_flags |= PORTALLOCATOR_DISABLE_RELAY; 4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!(sequence_flags & PORTALLOCATOR_ENABLE_IPV6) && 4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org networks[i]->ip().family() == AF_INET6) { 4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Skip IPv6 networks unless the flag's been set. 4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Disable phases that would only create ports equivalent to 4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // ones that we have already made. 4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DisableEquivalentPhases(networks[i], config, &sequence_flags); 4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((sequence_flags & DISABLE_ALL_PHASES) == DISABLE_ALL_PHASES) { 4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // New AllocationSequence would have nothing to do, so don't make it. 4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AllocationSequence* sequence = 4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org new AllocationSequence(this, networks[i], config, sequence_flags); 4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!sequence->Init()) { 4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete sequence; 4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org done_signal_needed = true; 4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sequence->SignalPortAllocationComplete.connect( 4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, &BasicPortAllocatorSession::OnPortAllocationComplete); 4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (running_) 4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sequence->Start(); 4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sequences_.push_back(sequence); 4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (done_signal_needed) { 4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->Post(this, MSG_SEQUENCEOBJECTS_CREATED); 4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnNetworksChanged() { 4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_manager_started_ = true; 4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (allocation_started_) 4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org DoAllocate(); 4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::DisableEquivalentPhases( 4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::Network* network, PortConfiguration* config, uint32* flags) { 4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (uint32 i = 0; i < sequences_.size() && 4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (*flags & DISABLE_ALL_PHASES) != DISABLE_ALL_PHASES; ++i) { 4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sequences_[i]->DisableEquivalentPhases(network, config, flags); 4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::AddAllocatedPort(Port* port, 4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AllocationSequence * seq, 4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool prepare_address) { 4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!port) 4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Adding allocated port for " << content_name(); 4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->set_content_name(content_name()); 4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->set_component(component_); 4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->set_generation(generation()); 4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (allocator_->proxy().type != talk_base::PROXY_NONE) 4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->set_proxy(allocator_->user_agent(), allocator_->proxy()); 4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->set_send_retransmit_count_attribute((allocator_->flags() & 4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE) != 0); 5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortData data(port, seq); 5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ports_.push_back(data); 5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->SignalCandidateReady.connect( 5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, &BasicPortAllocatorSession::OnCandidateReady); 5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->SignalPortComplete.connect(this, 5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &BasicPortAllocatorSession::OnPortComplete); 5080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->SignalDestroyed.connect(this, 5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &BasicPortAllocatorSession::OnPortDestroyed); 5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->SignalPortError.connect( 5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, &BasicPortAllocatorSession::OnPortError); 5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_INFO, port) << "Added port to allocator"; 5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (prepare_address) 5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->PrepareAddress(); 5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnAllocationSequenceObjectsCreated() { 5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org allocation_sequences_created_ = true; 5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send candidate allocation complete signal if we have no sequences. 5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MaybeSignalCandidatesAllocationDone(); 5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnCandidateReady( 5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Port* port, const Candidate& c) { 5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortData* data = FindPort(port); 5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(data != NULL); 5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Discarding any candidate signal if port allocation status is 5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // already in completed state. 5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (data->complete()) 5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send candidates whose protocol is enabled. 5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<Candidate> candidates; 5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ProtocolType pvalue; 5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (StringToProto(c.protocol().c_str(), &pvalue) && 5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org data->sequence()->ProtocolEnabled(pvalue)) { 5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org candidates.push_back(c); 5400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!candidates.empty()) { 5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalCandidatesReady(this, candidates); 5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Moving to READY state as we have atleast one candidate from the port. 5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Since this port has atleast one candidate we should forward this port 5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // to listners, to allow connections from this port. 5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!data->ready()) { 5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org data->set_ready(); 5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalPortReady(this, port); 5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnPortComplete(Port* port) { 5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 5570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortData* data = FindPort(port); 5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(data != NULL); 5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Ignore any late signals. 5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (data->complete()) 5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Moving to COMPLETE state. 5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org data->set_complete(); 5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send candidate allocation complete signal if this was the last port. 5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MaybeSignalCandidatesAllocationDone(); 5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnPortError(Port* port) { 5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortData* data = FindPort(port); 5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(data != NULL); 5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We might have already given up on this port and stopped it. 5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (data->complete()) 5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // SignalAddressError is currently sent from StunPort/TurnPort. 5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // But this signal itself is generic. 5800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org data->set_error(); 5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send candidate allocation complete signal if this was the last port. 5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MaybeSignalCandidatesAllocationDone(); 5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnProtocolEnabled(AllocationSequence* seq, 5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ProtocolType proto) { 5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<Candidate> candidates; 5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<PortData>::iterator it = ports_.begin(); 5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != ports_.end(); ++it) { 5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (it->sequence() != seq) 5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::vector<Candidate>& potentials = it->port()->Candidates(); 5940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < potentials.size(); ++i) { 5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ProtocolType pvalue; 5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!StringToProto(potentials[i].protocol().c_str(), &pvalue)) 5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org continue; 5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (pvalue == proto) { 5990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org candidates.push_back(potentials[i]); 6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!candidates.empty()) { 6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalCandidatesReady(this, candidates); 6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnPortAllocationComplete( 6100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AllocationSequence* seq) { 6110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send candidate allocation complete signal if all ports are done. 6120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org MaybeSignalCandidatesAllocationDone(); 6130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::MaybeSignalCandidatesAllocationDone() { 6160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send signal only if all required AllocationSequence objects 6170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // are created. 6180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!allocation_sequences_created_) 6190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 6200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Check that all port allocation sequences are complete. 6220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<AllocationSequence*>::iterator it = sequences_.begin(); 6230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != sequences_.end(); ++it) { 6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((*it)->state() == AllocationSequence::kRunning) 6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 6260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If all allocated ports are in complete state, session must have got all 6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // expected candidates. Session will trigger candidates allocation complete 6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // signal. 6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<PortData>::iterator it = ports_.begin(); 6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != ports_.end(); ++it) { 6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!it->complete()) 6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "All candidates gathered for " << content_name_ << ":" 6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << component_ << ":" << generation(); 6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalCandidatesAllocationDone(this); 6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnPortDestroyed( 6420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortInterface* port) { 6430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == network_thread_); 6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<PortData>::iterator iter = ports_.begin(); 6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != ports_.end(); ++iter) { 6460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (port == iter->port()) { 6470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ports_.erase(iter); 6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_INFO, port) << "Removed port from allocator (" 6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << static_cast<int>(ports_.size()) << " remaining)"; 6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BasicPortAllocatorSession::OnShake() { 6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << ">>>>> SHAKE <<<<< >>>>> SHAKE <<<<< >>>>> SHAKE <<<<<"; 6580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<Port*> ports; 6600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<Connection*> connections; 6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < ports_.size(); ++i) { 6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ports_[i].ready()) 6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ports.push_back(ports_[i].port()); 6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < ports.size(); ++i) { 6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Port::AddressMap::const_iterator iter; 6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (iter = ports[i]->connections().begin(); 6700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != ports[i]->connections().end(); 6710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter) { 6720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org connections.push_back(iter->second); 6730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << ">>>>> Destroying " << ports.size() << " ports and " 6770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << connections.size() << " connections"; 6780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < connections.size(); ++i) 6800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org connections[i]->Destroy(); 6810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (running_ || (ports.size() > 0) || (connections.size() > 0)) 6830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_thread_->PostDelayed(ShakeDelay(), this, MSG_SHAKE); 6840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBasicPortAllocatorSession::PortData* BasicPortAllocatorSession::FindPort( 6870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Port* port) { 6880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<PortData>::iterator it = ports_.begin(); 6890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != ports_.end(); ++it) { 6900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (it->port() == port) { 6910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return &*it; 6920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return NULL; 6950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// AllocationSequence 6980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgAllocationSequence::AllocationSequence(BasicPortAllocatorSession* session, 7000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::Network* network, 7010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration* config, 7020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 flags) 7030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : session_(session), 7040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_(network), 7050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ip_(network->ip()), 7060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config_(config), 7070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_(kInit), 7080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org flags_(flags), 7095c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org udp_socket_(), 710afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org udp_port_(NULL), 7110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org phase_(0) { 7120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool AllocationSequence::Init() { 7150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && 7160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org !IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_UFRAG)) { 7170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_ERROR) << "Shared socket option can't be set without " 7180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << "shared ufrag."; 7190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 7200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 7210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) { 7240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org udp_socket_.reset(session_->socket_factory()->CreateUdpSocket( 7250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::SocketAddress(ip_, 0), session_->allocator()->min_port(), 7260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->max_port())); 7270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (udp_socket_) { 7280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org udp_socket_->SignalReadPacket.connect( 7290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, &AllocationSequence::OnReadPacket); 7300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Continuing if |udp_socket_| is NULL, as local TCP and RelayPort using TCP 7320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // are next available options to setup a communication channel. 7330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 7350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 73709bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.orgvoid AllocationSequence::Clear() { 73809bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org udp_port_ = NULL; 73909bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org turn_ports_.clear(); 74009bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org} 74109bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org 7420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgAllocationSequence::~AllocationSequence() { 7430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->network_thread()->Clear(this); 7440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::DisableEquivalentPhases(talk_base::Network* network, 7470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration* config, uint32* flags) { 7480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!((network == network_) && (ip_ == network->ip()))) { 7490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Different network setup; nothing is equivalent. 7500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Else turn off the stuff that we've already got covered. 7540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Every config implicitly specifies local, so turn that off right away. 7560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *flags |= PORTALLOCATOR_DISABLE_UDP; 7570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *flags |= PORTALLOCATOR_DISABLE_TCP; 7580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (config_ && config) { 7600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (config_->stun_address == config->stun_address) { 7610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Already got this STUN server covered. 7620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *flags |= PORTALLOCATOR_DISABLE_STUN; 7630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!config_->relays.empty()) { 7650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Already got relays covered. 7660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // NOTE: This will even skip a _different_ set of relay servers if we 7670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // were to be given one, but that never happens in our codebase. Should 7680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // probably get rid of the list in PortConfiguration and just keep a 7690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // single relay server in each one. 7700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *flags |= PORTALLOCATOR_DISABLE_RELAY; 7710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::Start() { 7760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = kRunning; 7770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->network_thread()->Post(this, MSG_ALLOCATION_PHASE); 7780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::Stop() { 7810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If the port is completed, don't set it to stopped. 7820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (state_ == kRunning) { 7830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = kStopped; 7840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->network_thread()->Clear(this, MSG_ALLOCATION_PHASE); 7850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::OnMessage(talk_base::Message* msg) { 7890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(talk_base::Thread::Current() == session_->network_thread()); 7900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(msg->message_id == MSG_ALLOCATION_PHASE); 7910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const char* const PHASE_NAMES[kNumPhases] = { 7930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org "Udp", "Relay", "Tcp", "SslTcp" 7940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org }; 7950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Perform all of the phases in the current step. 7970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG_J(LS_INFO, network_) << "Allocation Phase=" 7980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << PHASE_NAMES[phase_]; 7990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org switch (phase_) { 8010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PHASE_UDP: 8020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateUDPPorts(); 8030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateStunPorts(); 8040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EnableProtocol(PROTO_UDP); 8050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PHASE_RELAY: 8080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateRelayPorts(); 8090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PHASE_TCP: 8120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateTCPPorts(); 8130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EnableProtocol(PROTO_TCP); 8140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org case PHASE_SSLTCP: 8170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org state_ = kCompleted; 8180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org EnableProtocol(PROTO_SSLTCP); 8190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 8200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org default: 8220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 8230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (state() == kRunning) { 8260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++phase_; 8270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->network_thread()->PostDelayed( 8280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->step_delay(), 8290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org this, MSG_ALLOCATION_PHASE); 8300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 8310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If all phases in AllocationSequence are completed, no allocation 8320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // steps needed further. Canceling pending signal. 8330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->network_thread()->Clear(this, MSG_ALLOCATION_PHASE); 8340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalPortAllocationComplete(this); 8350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::EnableProtocol(ProtocolType proto) { 8390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ProtocolEnabled(proto)) { 8400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protocols_.push_back(proto); 8410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->OnProtocolEnabled(this, proto); 8420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool AllocationSequence::ProtocolEnabled(ProtocolType proto) const { 8460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (ProtocolList::const_iterator it = protocols_.begin(); 8470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != protocols_.end(); ++it) { 8480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (*it == proto) 8490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 8500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 8520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::CreateUDPPorts() { 8550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_DISABLE_UDP)) { 8560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "AllocationSequence: UDP ports disabled, skipping."; 8570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 8580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(mallinath) - Remove UDPPort creating socket after shared socket 8610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // is enabled completely. 8620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org UDPPort* port = NULL; 8630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && udp_socket_) { 86419da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org port = UDPPort::Create(session_->network_thread(), 86519da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org session_->socket_factory(), network_, 8660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org udp_socket_.get(), 8670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->username(), session_->password()); 8680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 8690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port = UDPPort::Create(session_->network_thread(), 8700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->socket_factory(), 8710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_, ip_, 8720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->min_port(), 8730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->max_port(), 8740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->username(), session_->password()); 8750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (port) { 8780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If shared socket is enabled, STUN candidate will be allocated by the 8790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // UDPPort. 880bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) { 881afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org udp_port_ = port; 882bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org 883bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org // If STUN is not disabled, setting stun server address to port. 884bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org if (!IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) { 885ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org // If config has stun_address, use it to get server reflexive candidate 886ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org // otherwise use first TURN server which supports UDP. 887ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org if (config_ && !config_->stun_address.IsNil()) { 888ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org LOG(LS_INFO) << "AllocationSequence: UDPPort will be handling the " 889ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org << "STUN candidate generation."; 890bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org port->set_server_addr(config_->stun_address); 891ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org } else if (config_ && 892ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org config_->SupportsProtocol(RELAY_TURN, PROTO_UDP)) { 893ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org port->set_server_addr(config_->GetFirstRelayServerAddress( 894ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org RELAY_TURN, PROTO_UDP)); 895ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org LOG(LS_INFO) << "AllocationSequence: TURN Server address will be " 896ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org << " used for generating STUN candidate."; 897bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org } 898afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } 8990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->AddAllocatedPort(port, this, true); 9020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed); 9030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::CreateTCPPorts() { 9070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_DISABLE_TCP)) { 9080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "AllocationSequence: TCP ports disabled, skipping."; 9090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 9100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Port* port = TCPPort::Create(session_->network_thread(), 9130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->socket_factory(), 9140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_, ip_, 9150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->min_port(), 9160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->max_port(), 9170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->username(), session_->password(), 9180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->allow_tcp_listen()); 9190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (port) { 9200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->AddAllocatedPort(port, this, true); 9210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Since TCPPort is not created using shared socket, |port| will not be 9220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // added to the dequeue. 9230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::CreateStunPorts() { 9270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) { 9280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "AllocationSequence: STUN ports disabled, skipping."; 9290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 9300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) { 9330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 9340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If BasicPortAllocatorSession::OnAllocate left STUN ports enabled then we 9370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // ought to have an address for them here. 9380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(config_ && !config_->stun_address.IsNil()); 9390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!(config_ && !config_->stun_address.IsNil())) { 9400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) 9410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << "AllocationSequence: No STUN server configured, skipping."; 9420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 9430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunPort* port = StunPort::Create(session_->network_thread(), 9460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->socket_factory(), 9470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_, ip_, 9480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->min_port(), 9490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->max_port(), 9500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->username(), session_->password(), 9510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config_->stun_address); 9520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (port) { 9530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->AddAllocatedPort(port, this, true); 9540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Since StunPort is not created using shared socket, |port| will not be 9550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // added to the dequeue. 9560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::CreateRelayPorts() { 9600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (IsFlagSet(PORTALLOCATOR_DISABLE_RELAY)) { 9610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "AllocationSequence: Relay ports disabled, skipping."; 9620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 9630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If BasicPortAllocatorSession::OnAllocate left relay ports enabled then we 9660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // ought to have a relay list for them here. 9670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(config_ && !config_->relays.empty()); 9680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!(config_ && !config_->relays.empty())) { 9690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) 9700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << "AllocationSequence: No relay server configured, skipping."; 9710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 9720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortConfiguration::RelayList::const_iterator relay; 9750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (relay = config_->relays.begin(); 9760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org relay != config_->relays.end(); ++relay) { 9770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (relay->type == RELAY_GTURN) { 9780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateGturnPort(*relay); 9790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (relay->type == RELAY_TURN) { 9800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CreateTurnPort(*relay); 9810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 9820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(false); 9830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 9850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 9860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 9870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::CreateGturnPort(const RelayServerConfig& config) { 9880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(mallinath) - Rename RelayPort to GTurnPort. 9890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayPort* port = RelayPort::Create(session_->network_thread(), 9900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->socket_factory(), 9910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org network_, ip_, 9920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->min_port(), 9930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->allocator()->max_port(), 9940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org config_->username, config_->password); 9950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (port) { 9960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Since RelayPort is not created using shared socket, |port| will not be 9970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // added to the dequeue. 9980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Note: We must add the allocated port before we add addresses because 9990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // the latter will create candidates that need name and preference 10000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // settings. However, we also can't prepare the address (normally 10010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // done by AddAllocatedPort) until we have these addresses. So we 10020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // wait to do that until below. 10030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org session_->AddAllocatedPort(port, this, false); 10040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Add the addresses of this protocol. 10060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortList::const_iterator relay_port; 10070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (relay_port = config.ports.begin(); 10080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org relay_port != config.ports.end(); 10090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++relay_port) { 10100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->AddServerAddress(*relay_port); 10110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->AddExternalAddress(*relay_port); 10120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Start fetching an address for this port. 10140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port->PrepareAddress(); 10150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 10170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::CreateTurnPort(const RelayServerConfig& config) { 10190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortList::const_iterator relay_port; 10200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (relay_port = config.ports.begin(); 10210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org relay_port != config.ports.end(); ++relay_port) { 1022afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org TurnPort* port = NULL; 1023005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org // Shared socket mode must be enabled only for UDP based ports. Hence 1024005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org // don't pass shared socket for ports which will create TCP sockets. 1025005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET) && 1026005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org relay_port->proto == PROTO_UDP) { 1027afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org port = TurnPort::Create(session_->network_thread(), 1028afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org session_->socket_factory(), 1029afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org network_, udp_socket_.get(), 1030afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org session_->username(), session_->password(), 1031afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org *relay_port, config.credentials); 1032afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // If we are using shared socket for TURN and udp ports, we need to 1033afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // find a way to demux the packets to the correct port when received. 1034afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // Mapping against server_address is one way of doing this. When packet 1035afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // is received the remote_address will be checked against the map. 1036afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // If server address is not resolved, a signal will be sent from the port 1037afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // after the address is resolved. The map entry will updated with the 1038afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // resolved address when the signal is received from the port. 1039005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org if ((*relay_port).address.IsUnresolved()) { 1040afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // If server address is not resolved then listen for signal from port. 1041005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org port->SignalResolvedServerAddress.connect( 1042005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org this, &AllocationSequence::OnResolvedTurnServerAddress); 1043afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } 1044005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org turn_ports_[(*relay_port).address] = port; 104509bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org // Listen to the port destroyed signal, to allow AllocationSequence to 104609bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org // remove entrt from it's map. 104709bb4f1719581ba8529ebc34407832b200288ad9mallinath@webrtc.org port->SignalDestroyed.connect(this, &AllocationSequence::OnPortDestroyed); 1048005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org } else { 1049005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org port = TurnPort::Create(session_->network_thread(), 1050005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org session_->socket_factory(), 1051005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org network_, ip_, 1052005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org session_->allocator()->min_port(), 1053005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org session_->allocator()->max_port(), 1054005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org session_->username(), 1055005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org session_->password(), 1056005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org *relay_port, config.credentials); 10570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1058005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org ASSERT(port != NULL); 1059005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org session_->AddAllocatedPort(port, this, true); 10600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 10610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 10620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::OnReadPacket( 10640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org talk_base::AsyncPacketSocket* socket, const char* data, size_t size, 1065f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org const talk_base::SocketAddress& remote_addr, 1066f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org const talk_base::PacketTime& packet_time) { 10670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(socket == udp_socket_.get()); 1068afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // If the packet is received from one of the TURN server in the config, then 1069afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // pass down the packet to that port, otherwise it will be handed down to 1070afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // the local udp port. 1071afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org Port* port = NULL; 1072afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org std::map<talk_base::SocketAddress, Port*>::iterator iter = 1073afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org turn_ports_.find(remote_addr); 1074afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org if (iter != turn_ports_.end()) { 1075afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org port = iter->second; 1076afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } else if (udp_port_) { 1077afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org port = udp_port_; 10780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 1079afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org ASSERT(port != NULL); 1080bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org if (port) { 1081bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org port->HandleIncomingPacket(socket, data, size, remote_addr, packet_time); 1082bf9b1e0e3c606f615851d9f33f4d5222acfc921emallinath@webrtc.org } 10830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 10840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 10850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocationSequence::OnPortDestroyed(PortInterface* port) { 1086afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org if (udp_port_ == port) { 1087afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org udp_port_ = NULL; 1088afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } else { 1089afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org std::map<talk_base::SocketAddress, Port*>::iterator iter; 1090afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org for (iter = turn_ports_.begin(); iter != turn_ports_.end(); ++iter) { 1091afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org if (iter->second == port) { 1092afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org turn_ports_.erase(iter); 1093afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org break; 1094afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } 1095afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } 1096afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } 1097afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org} 1098afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org 1099afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.orgvoid AllocationSequence::OnResolvedTurnServerAddress( 1100afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org TurnPort* port, const talk_base::SocketAddress& server_address, 1101afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org const talk_base::SocketAddress& resolved_server_address) { 1102afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org std::map<talk_base::SocketAddress, Port*>::iterator iter; 1103afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org iter = turn_ports_.find(server_address); 1104258851dd5adc9951102ce955177266a4d219a87dbuildbot@webrtc.org if (iter == turn_ports_.end()) { 1105258851dd5adc9951102ce955177266a4d219a87dbuildbot@webrtc.org LOG(LS_INFO) << "TurnPort entry is not found in the map."; 1106258851dd5adc9951102ce955177266a4d219a87dbuildbot@webrtc.org return; 1107258851dd5adc9951102ce955177266a4d219a87dbuildbot@webrtc.org } 1108afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org 110996e0526e1b4d0774b89a41f3ae61d302c781d4d7buildbot@webrtc.org ASSERT(iter->second == port); 1110afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // Remove old entry and then insert using the resolved address as key. 1111afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org turn_ports_.erase(iter); 1112afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org turn_ports_[resolved_server_address] = port; 11130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// PortConfiguration 11160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgPortConfiguration::PortConfiguration( 11170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const talk_base::SocketAddress& stun_address, 11180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& username, 11190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& password) 11200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : stun_address(stun_address), 11210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org username(username), 11220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org password(password) { 11230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid PortConfiguration::AddRelay(const RelayServerConfig& config) { 11260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org relays.push_back(config); 11270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 11290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool PortConfiguration::SupportsProtocol( 1130afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org const RelayServerConfig& relay, ProtocolType type) const { 11310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PortList::const_iterator relay_port; 11320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (relay_port = relay.ports.begin(); 11330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org relay_port != relay.ports.end(); 11340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++relay_port) { 11350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (relay_port->proto == type) 11360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 11370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 11380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 11390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 11400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1141ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.orgbool PortConfiguration::SupportsProtocol(RelayType turn_type, 1142afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org ProtocolType type) const { 1143afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org for (size_t i = 0; i < relays.size(); ++i) { 1144afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org if (relays[i].type == turn_type && 1145afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org SupportsProtocol(relays[i], type)) 1146afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org return true; 1147afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org } 1148afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org return false; 1149afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org} 1150afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org 1151ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.orgtalk_base::SocketAddress PortConfiguration::GetFirstRelayServerAddress( 1152ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org RelayType turn_type, ProtocolType type) const { 1153ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org for (size_t i = 0; i < relays.size(); ++i) { 1154ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org if (relays[i].type == turn_type && SupportsProtocol(relays[i], type)) { 1155ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org return relays[i].ports.front().address; 1156ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org } 1157ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org } 1158ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org return talk_base::SocketAddress(); 1159ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org} 1160ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org 11610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 1162