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 28cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/relayport.h" 292a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/asyncpacketsocket.h" 302a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/helpers.h" 312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/logging.h" 320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const uint32 kMessageConnectTimeout = 1; 360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kKeepAliveDelay = 10 * 60 * 1000; 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kRetryTimeout = 50 * 1000; // ICE says 50 secs 380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// How long to wait for a socket to connect to remote host in milliseconds 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// before trying another connection. 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kSoftConnectTimeoutMs = 3 * 1000; 410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Handles a connection to one address/port/protocol combination for a 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// particular RelayEntry. 440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass RelayConnection : public sigslot::has_slots<> { 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection(const ProtocolAddress* protocol_address, 472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket, 482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Thread* thread); 490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ~RelayConnection(); 502a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket() const { return socket_; } 510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const ProtocolAddress* protocol_address() { 530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return protocol_address_; 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 562a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SocketAddress GetAddress() const { 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return protocol_address_->address; 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ProtocolType GetProtocol() const { 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return protocol_address_->proto; 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org int SetSocketOption(rtc::Socket::Option opt, int value); 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Validates a response to a STUN allocate request. 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool CheckResponse(StunMessage* msg); 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sends data to the relay server. 702a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org int Send(const void* pv, size_t cb, const rtc::PacketOptions& options); 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sends a STUN allocate request message to the relay server. 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void SendAllocateRequest(RelayEntry* entry, int delay); 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Return the latest error generated by the socket. 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int GetError() { return socket_->GetError(); } 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Called on behalf of a StunRequest to write data to the socket. This is 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // already STUN intended for the server, so no wrapping is necessary. 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void OnSendPacket(const void* data, size_t size, StunRequest* req); 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private: 832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket_; 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const ProtocolAddress* protocol_address_; 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunRequestManager *request_manager_; 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Manages a number of connections to the relayserver, one for each 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// available protocol. We aim to use each connection for only a 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// specific destination address so that we can avoid wrapping every 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// packet in a STUN send / data indication. 922a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgclass RelayEntry : public rtc::MessageHandler, 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public sigslot::has_slots<> { 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 952a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org RelayEntry(RelayPort* port, const rtc::SocketAddress& ext_addr); 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ~RelayEntry(); 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayPort* port() { return port_; } 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1002a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& address() const { return ext_addr_; } 1012a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org void set_address(const rtc::SocketAddress& addr) { ext_addr_ = addr; } 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool connected() const { return connected_; } 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool locked() const { return locked_; } 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Returns the last error on the socket of this entry. 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int GetError(); 1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Returns the most preferred connection of the given 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // ones. Connections are rated based on protocol in the order of: 1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // UDP, TCP and SSLTCP, where UDP is the most preferred protocol 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org static RelayConnection* GetBestConnection(RelayConnection* conn1, 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection* conn2); 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sends the STUN requests to the server to initiate this connection. 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void Connect(); 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Called when this entry becomes connected. The address given is the one 1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // exposed to the outside world on the relay server. 1202a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org void OnConnect(const rtc::SocketAddress& mapped_addr, 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection* socket); 1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sends a packet to the given destination address using the socket of this 1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // entry. This will wrap the packet in STUN if necessary. 1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int SendTo(const void* data, size_t size, 1262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& addr, 1272a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketOptions& options); 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Schedules a keep-alive allocate request. 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void ScheduleKeepAlive(); 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org void SetServerIndex(size_t sindex) { server_index_ = sindex; } 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sets this option on the socket of each connection. 1352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org int SetSocketOption(rtc::Socket::Option opt, int value); 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t ServerIndex() const { return server_index_; } 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Try a different server address 1402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org void HandleConnectFailure(rtc::AsyncPacketSocket* socket); 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Implementation of the MessageHandler Interface. 1432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org virtual void OnMessage(rtc::Message *pmsg); 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private: 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayPort* port_; 1472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SocketAddress ext_addr_; 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t server_index_; 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool connected_; 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org bool locked_; 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection* current_connection_; 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Called when a TCP connection is established or fails 1542a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org void OnSocketConnect(rtc::AsyncPacketSocket* socket); 1552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org void OnSocketClose(rtc::AsyncPacketSocket* socket, int error); 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Called when a packet is received on this socket. 158f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org void OnReadPacket( 1592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket, 160f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org const char* data, size_t size, 1612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& remote_addr, 1622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketTime& packet_time); 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Called when the socket is currently able to send. 1642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org void OnReadyToSend(rtc::AsyncPacketSocket* socket); 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Sends the given data on the socket to the server with no wrapping. This 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // returns the number of bytes written or -1 if an error occurred. 168391247d05a663265807c400947ab6eb01ae3d690mallinath@webrtc.org int SendPacket(const void* data, size_t size, 1692a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketOptions& options); 1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Handles an allocate request for a particular RelayEntry. 1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass AllocateRequest : public StunRequest { 1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public: 1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AllocateRequest(RelayEntry* entry, RelayConnection* connection); 1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual ~AllocateRequest() {} 1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void Prepare(StunMessage* request); 1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual int GetNextDelay(); 1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void OnResponse(StunMessage* response); 1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void OnErrorResponse(StunMessage* response); 1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org virtual void OnTimeout(); 1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private: 1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayEntry* entry_; 1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection* connection_; 1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org uint32 start_time_; 1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}; 1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgRelayPort::RelayPort( 1932a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Thread* thread, rtc::PacketSocketFactory* factory, 1942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Network* network, const rtc::IPAddress& ip, 1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int min_port, int max_port, const std::string& username, 1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const std::string& password) 1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port, 1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org username, password), 1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_(false), 2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org error_(0) { 2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entries_.push_back( 2022a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org new RelayEntry(this, rtc::SocketAddress())); 2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO: set local preference value for TCP based candidates. 2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgRelayPort::~RelayPort() { 2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < entries_.size(); ++i) 2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete entries_[i]; 2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org thread()->Clear(this); 2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayPort::AddServerAddress(const ProtocolAddress& addr) { 2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Since HTTP proxies usually only allow 443, 2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // let's up the priority on PROTO_SSLTCP 2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (addr.proto == PROTO_SSLTCP && 2162a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org (proxy().type == rtc::PROXY_HTTPS || 2172a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org proxy().type == rtc::PROXY_UNKNOWN)) { 2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org server_addr_.push_front(addr); 2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org server_addr_.push_back(addr); 2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayPort::AddExternalAddress(const ProtocolAddress& addr) { 2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string proto_name = ProtoToString(addr.proto); 2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<ProtocolAddress>::iterator it = external_addr_.begin(); 2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org it != external_addr_.end(); ++it) { 2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((it->address == addr.address) && (it->proto == addr.proto)) { 2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Redundant relay address: " << proto_name 2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " @ " << addr.address.ToSensitiveString(); 2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 2320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org external_addr_.push_back(addr); 2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayPort::SetReady() { 2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ready_) { 2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<ProtocolAddress>::iterator iter; 2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (iter = external_addr_.begin(); 2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != external_addr_.end(); ++iter) { 2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::string proto_name = ProtoToString(iter->proto); 243afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // In case of Gturn, related address is set to null socket address. 244afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // This is due to as mapped address stun attribute is used for allocated 245afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org // address. 2462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org AddAddress(iter->address, iter->address, rtc::SocketAddress(), 24758c89b128d6e4dbe00a9a18bb3029f63bd43ce6dmallinath@webrtc.org proto_name, "", RELAY_PORT_TYPE, 24858c89b128d6e4dbe00a9a18bb3029f63bd43ce6dmallinath@webrtc.org ICE_TYPE_PREFERENCE_RELAY, 0, false); 2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_ = true; 2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org SignalPortComplete(this); 2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst ProtocolAddress * RelayPort::ServerAddress(size_t index) const { 2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (index < server_addr_.size()) 2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return &server_addr_[index]; 2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return NULL; 2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool RelayPort::HasMagicCookie(const char* data, size_t size) { 2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (size < 24 + sizeof(TURN_MAGIC_COOKIE_VALUE)) { 2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 265b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org return memcmp(data + 24, 266b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org TURN_MAGIC_COOKIE_VALUE, 267b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org sizeof(TURN_MAGIC_COOKIE_VALUE)) == 0; 2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayPort::PrepareAddress() { 2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We initiate a connect on the first entry. If this completes, it will fill 2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // in the server address as the address of this port. 2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(entries_.size() == 1); 2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entries_[0]->Connect(); 2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ready_ = false; 2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgConnection* RelayPort::CreateConnection(const Candidate& address, 2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CandidateOrigin origin) { 2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We only create conns to non-udp sockets if they are incoming on this port 2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((address.protocol() != UDP_PROTOCOL_NAME) && 2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (origin != ORIGIN_THIS_PORT)) { 2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return 0; 2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We don't support loopback on relays 2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (address.type() == Type()) { 2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return 0; 2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!IsCompatibleAddress(address.address())) { 2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return 0; 2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org size_t index = 0; 2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < Candidates().size(); ++i) { 2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const Candidate& local = Candidates()[i]; 2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (local.protocol() == address.protocol()) { 3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org index = i; 3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Connection * conn = new ProxyConnection(this, index, address); 3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org AddConnection(conn); 3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return conn; 3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint RelayPort::SendTo(const void* data, size_t size, 3112a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& addr, 3122a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketOptions& options, 313391247d05a663265807c400947ab6eb01ae3d690mallinath@webrtc.org bool payload) { 3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Try to find an entry for this specific address. Note that the first entry 3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // created was not given an address initially, so it can be set to the first 3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // address that comes along. 3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayEntry* entry = 0; 3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < entries_.size(); ++i) { 3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (entries_[i]->address().IsNil() && payload) { 3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry = entries_[i]; 3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry->set_address(addr); 3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (entries_[i]->address() == addr) { 3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry = entries_[i]; 3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org break; 3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we did not find one, then we make a new one. This will not be useable 3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // until it becomes connected, however. 3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!entry && payload) { 3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry = new RelayEntry(this, addr); 3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!entries_.empty()) { 3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry->SetServerIndex(entries_[0]->ServerIndex()); 3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry->Connect(); 3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entries_.push_back(entry); 3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If the entry is connected, then we can send on it (though wrapping may 3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // still be necessary). Otherwise, we can't yet use this connection, so we 3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // default to the first one. 3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!entry || !entry->connected()) { 3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(!entries_.empty()); 3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry = entries_[0]; 3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!entry->connected()) { 3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org error_ = EWOULDBLOCK; 3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SOCKET_ERROR; 3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Send the actual contents to the server using the usual mechanism. 354f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org int sent = entry->SendTo(data, size, addr, options); 3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (sent <= 0) { 3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(sent < 0); 3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org error_ = entry->GetError(); 3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SOCKET_ERROR; 3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The caller of the function is expecting the number of user data bytes, 3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // rather than the size of the packet. 3621a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org return static_cast<int>(size); 3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgint RelayPort::SetOption(rtc::Socket::Option opt, int value) { 3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int result = 0; 3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < entries_.size(); ++i) { 3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (entries_[i]->SetSocketOption(opt, value) < 0) { 3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org result = -1; 3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org error_ = entries_[i]->GetError(); 3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org options_.push_back(OptionValue(opt, value)); 3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return result; 3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3772a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgint RelayPort::GetOption(rtc::Socket::Option opt, int* value) { 3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<OptionValue>::iterator it; 3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (it = options_.begin(); it < options_.end(); ++it) { 3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (it->first == opt) { 3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *value = it->second; 3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return 0; 3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return SOCKET_ERROR; 3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint RelayPort::GetError() { 3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return error_; 3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayPort::OnReadPacket( 3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const char* data, size_t size, 3942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& remote_addr, 395f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org ProtocolType proto, 3962a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketTime& packet_time) { 3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (Connection* conn = GetConnection(remote_addr)) { 398f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org conn->OnReadPacket(data, size, packet_time); 3990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Port::OnReadPacket(data, size, remote_addr, proto); 4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgRelayConnection::RelayConnection(const ProtocolAddress* protocol_address, 4052a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket, 4062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::Thread* thread) 4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : socket_(socket), 4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protocol_address_(protocol_address) { 4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org request_manager_ = new StunRequestManager(thread); 4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org request_manager_->SignalSendPacket.connect(this, 4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org &RelayConnection::OnSendPacket); 4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgRelayConnection::~RelayConnection() { 4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete request_manager_; 4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete socket_; 4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4192a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgint RelayConnection::SetSocketOption(rtc::Socket::Option opt, 4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int value) { 4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (socket_) { 4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return socket_->SetOption(opt, value); 4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return 0; 4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool RelayConnection::CheckResponse(StunMessage* msg) { 4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return request_manager_->CheckResponse(msg); 4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayConnection::OnSendPacket(const void* data, size_t size, 4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunRequest* req) { 433391247d05a663265807c400947ab6eb01ae3d690mallinath@webrtc.org // TODO(mallinath) Find a way to get DSCP value from Port. 4342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::PacketOptions options; // Default dscp set to NO_CHANGE. 435f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org int sent = socket_->SendTo(data, size, GetAddress(), options); 4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (sent <= 0) { 4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_VERBOSE) << "OnSendPacket: failed sending to " << GetAddress() << 438b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org strerror(socket_->GetError()); 4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(sent < 0); 4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 443391247d05a663265807c400947ab6eb01ae3d690mallinath@webrtc.orgint RelayConnection::Send(const void* pv, size_t cb, 4442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketOptions& options) { 445f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org return socket_->SendTo(pv, cb, GetAddress(), options); 4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayConnection::SendAllocateRequest(RelayEntry* entry, int delay) { 4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org request_manager_->SendDelayed(new AllocateRequest(entry, this), delay); 4500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgRelayEntry::RelayEntry(RelayPort* port, 4532a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& ext_addr) 4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : port_(port), ext_addr_(ext_addr), 4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org server_index_(0), connected_(false), locked_(false), 4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_(NULL) { 4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgRelayEntry::~RelayEntry() { 4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Remove all RelayConnections and dispose sockets. 4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org delete current_connection_; 4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_ = NULL; 4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayEntry::Connect() { 4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we're already connected, return. 4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (connected_) 4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we've exhausted all options, bail out. 4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const ProtocolAddress* ra = port()->ServerAddress(server_index_); 4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!ra) { 4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "No more relay addresses left to try"; 4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Remove any previous connection. 4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_) { 4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port()->thread()->Dispose(current_connection_); 4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_ = NULL; 4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Try to set up our new socket. 4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_INFO) << "Connecting to relay via " << ProtoToString(ra->proto) << 4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org " @ " << ra->address.ToSensitiveString(); 4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4872a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket = NULL; 4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ra->proto == PROTO_UDP) { 4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // UDP sockets are simple. 4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket = port_->socket_factory()->CreateUdpSocket( 4922a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SocketAddress(port_->ip(), 0), 4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->min_port(), port_->max_port()); 4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (ra->proto == PROTO_TCP || ra->proto == PROTO_SSLTCP) { 4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int opts = (ra->proto == PROTO_SSLTCP) ? 4962a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::PacketSocketFactory::OPT_SSLTCP : 0; 4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket = port_->socket_factory()->CreateClientTcpSocket( 4982a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SocketAddress(port_->ip(), 0), ra->address, 4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->proxy(), port_->user_agent(), opts); 5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Unknown protocol (" << ra->proto << ")"; 5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!socket) { 5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Socket creation failed"; 5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we failed to get a socket, move on to the next protocol. 5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!socket) { 5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port()->thread()->Post(this, kMessageConnectTimeout); 5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Otherwise, create the new connection and configure any socket options. 5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket->SignalReadPacket.connect(this, &RelayEntry::OnReadPacket); 5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket->SignalReadyToSend.connect(this, &RelayEntry::OnReadyToSend); 5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_ = new RelayConnection(ra, socket, port()->thread()); 5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (size_t i = 0; i < port_->options().size(); ++i) { 5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_->SetSocketOption(port_->options()[i].first, 5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->options()[i].second); 5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we're trying UDP, start binding requests. 5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If we're trying TCP, wait for connection with a fixed timeout. 5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if ((ra->proto == PROTO_TCP) || (ra->proto == PROTO_SSLTCP)) { 5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket->SignalClose.connect(this, &RelayEntry::OnSocketClose); 5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket->SignalConnect.connect(this, &RelayEntry::OnSocketConnect); 5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port()->thread()->PostDelayed(kSoftConnectTimeoutMs, this, 5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org kMessageConnectTimeout); 5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_->SendAllocateRequest(this, 0); 5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint RelayEntry::GetError() { 5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_ != NULL) { 5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return current_connection_->GetError(); 5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return 0; 5400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgRelayConnection* RelayEntry::GetBestConnection(RelayConnection* conn1, 5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection* conn2) { 5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return conn1->GetProtocol() <= conn2->GetProtocol() ? conn1 : conn2; 5450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid RelayEntry::OnConnect(const rtc::SocketAddress& mapped_addr, 5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection* connection) { 5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We are connected, notify our parent. 5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ProtocolType proto = PROTO_UDP; 5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Relay allocate succeeded: " << ProtoToString(proto) 5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " @ " << mapped_addr.ToSensitiveString(); 5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org connected_ = true; 5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->AddExternalAddress(ProtocolAddress(mapped_addr, proto)); 5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->SetReady(); 5570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 5580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint RelayEntry::SendTo(const void* data, size_t size, 5602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& addr, 5612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketOptions& options) { 5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If this connection is locked to the address given, then we can send the 5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // packet with no wrapper. 5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (locked_ && (ext_addr_ == addr)) 565f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org return SendPacket(data, size, options); 5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Otherwise, we must wrap the given data in a STUN SEND request so that we 5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // can communicate the destination address to the server. 5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // 5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Note that we do not use a StunRequest here. This is because there is 5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // likely no reason to resend this packet. If it is late, we just drop it. 5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The next send to this address will try again. 5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayMessage request; 5750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org request.SetType(STUN_SEND_REQUEST); 5760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunByteStringAttribute* magic_cookie_attr = 5780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunAttribute::CreateByteString(STUN_ATTR_MAGIC_COOKIE); 5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org magic_cookie_attr->CopyBytes(TURN_MAGIC_COOKIE_VALUE, 5800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org sizeof(TURN_MAGIC_COOKIE_VALUE)); 5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VERIFY(request.AddAttribute(magic_cookie_attr)); 5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunByteStringAttribute* username_attr = 5840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunAttribute::CreateByteString(STUN_ATTR_USERNAME); 5850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org username_attr->CopyBytes(port_->username_fragment().c_str(), 5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->username_fragment().size()); 5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VERIFY(request.AddAttribute(username_attr)); 5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunAddressAttribute* addr_attr = 5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunAttribute::CreateAddress(STUN_ATTR_DESTINATION_ADDRESS); 5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org addr_attr->SetIP(addr.ipaddr()); 5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org addr_attr->SetPort(addr.port()); 5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VERIFY(request.AddAttribute(addr_attr)); 5940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Attempt to lock 5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (ext_addr_ == addr) { 5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunUInt32Attribute* options_attr = 5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunAttribute::CreateUInt32(STUN_ATTR_OPTIONS); 5990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org options_attr->SetValue(0x1); 6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VERIFY(request.AddAttribute(options_attr)); 6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunByteStringAttribute* data_attr = 6040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunAttribute::CreateByteString(STUN_ATTR_DATA); 6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org data_attr->CopyBytes(data, size); 6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VERIFY(request.AddAttribute(data_attr)); 6070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO: compute the HMAC. 6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6102a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::ByteBuffer buf; 6110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org request.Write(&buf); 6120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 613f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org return SendPacket(buf.Data(), buf.Length(), options); 6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayEntry::ScheduleKeepAlive() { 6170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_) { 6180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_->SendAllocateRequest(this, kKeepAliveDelay); 6190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6222a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgint RelayEntry::SetSocketOption(rtc::Socket::Option opt, int value) { 6230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Set the option on all available sockets. 6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int socket_error = 0; 6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_) { 6260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket_error = current_connection_->SetSocketOption(opt, value); 6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return socket_error; 6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid RelayEntry::HandleConnectFailure( 6322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket) { 6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Make sure it's the current connection that has failed, it might 6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // be an old socked that has not yet been disposed. 6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!socket || 6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (current_connection_ && socket == current_connection_->socket())) { 6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_) 6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port()->SignalConnectFailure(current_connection_->protocol_address()); 6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Try to connect to the next server address. 6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org server_index_ += 1; 6420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org Connect(); 6430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid RelayEntry::OnMessage(rtc::Message *pmsg) { 6470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(pmsg->message_id == kMessageConnectTimeout); 6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_) { 6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const ProtocolAddress* ra = current_connection_->protocol_address(); 6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(LS_WARNING) << "Relay " << ra->proto << " connection to " << 6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ra->address << " timed out"; 6520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Currently we connect to each server address in sequence. If we 6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // have more addresses to try, treat this is an error and move on to 6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // the next address, otherwise give this connection more time and 6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // await the real timeout. 6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // 6580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO: Connect to servers in parallel to speed up connect time 6590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // and to avoid giving up too early. 6600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->SignalSoftTimeout(ra); 6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org HandleConnectFailure(current_connection_->socket()); 6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org HandleConnectFailure(NULL); 6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid RelayEntry::OnSocketConnect(rtc::AsyncPacketSocket* socket) { 6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "relay tcp connected to " << 6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org socket->GetRemoteAddress().ToSensitiveString(); 6700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_ != NULL) { 6710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org current_connection_->SendAllocateRequest(this, 0); 6720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid RelayEntry::OnSocketClose(rtc::AsyncPacketSocket* socket, 6760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int error) { 6770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org PLOG(LERROR, error) << "Relay connection failed: socket closed"; 6780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org HandleConnectFailure(socket); 6790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 6800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 681f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.orgvoid RelayEntry::OnReadPacket( 6822a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::AsyncPacketSocket* socket, 683f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org const char* data, size_t size, 6842a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::SocketAddress& remote_addr, 6852a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketTime& packet_time) { 6860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // ASSERT(remote_addr == port_->server_addr()); 6870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO: are we worried about this? 6880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_ == NULL || socket != current_connection_->socket()) { 6900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This packet comes from an unknown address. 6910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(WARNING) << "Dropping packet: unknown address"; 6920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 6930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 6940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 6950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If the magic cookie is not present, then this is an unwrapped packet sent 6960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // by the server, The actual remote address is the one we recorded. 6970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!port_->HasMagicCookie(data, size)) { 6980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (locked_) { 699f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org port_->OnReadPacket(data, size, ext_addr_, PROTO_UDP, packet_time); 7000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 7010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(WARNING) << "Dropping packet: entry not locked"; 7020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::ByteBuffer buf(data, size); 7070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayMessage msg; 7080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!msg.Read(&buf)) { 7090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Incoming packet was not STUN"; 7100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The incoming packet should be a STUN ALLOCATE response, SEND response, or 7140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // DATA indication. 7150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_->CheckResponse(&msg)) { 7160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (msg.type() == STUN_SEND_RESPONSE) { 7180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (const StunUInt32Attribute* options_attr = 7190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org msg.GetUInt32(STUN_ATTR_OPTIONS)) { 7200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (options_attr->value() & 0x1) { 7210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org locked_ = true; 7220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (msg.type() != STUN_DATA_INDICATION) { 7260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Received BAD stun type from server: " << msg.type(); 7270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This must be a data indication. 7310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const StunAddressAttribute* addr_attr = 7330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org msg.GetAddress(STUN_ATTR_SOURCE_ADDRESS2); 7340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!addr_attr) { 7350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Data indication has no source address"; 7360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (addr_attr->family() != 1) { 7380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Source address has bad family"; 7390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SocketAddress remote_addr2(addr_attr->ipaddr(), addr_attr->port()); 7430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const StunByteStringAttribute* data_attr = msg.GetByteString(STUN_ATTR_DATA); 7450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!data_attr) { 7460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Data indication has no data"; 7470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 7480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Process the actual data and remote address in the normal manner. 7510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->OnReadPacket(data_attr->bytes(), data_attr->length(), remote_addr2, 752f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org PROTO_UDP, packet_time); 7530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid RelayEntry::OnReadyToSend(rtc::AsyncPacketSocket* socket) { 7560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (connected()) { 7570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org port_->OnReadyToSend(); 7580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 761391247d05a663265807c400947ab6eb01ae3d690mallinath@webrtc.orgint RelayEntry::SendPacket(const void* data, size_t size, 7622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org const rtc::PacketOptions& options) { 7630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org int sent = 0; 7640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (current_connection_) { 7650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We are connected, no need to send packets anywere else than to 7660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // the current connection. 767f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org sent = current_connection_->Send(data, size, options); 7680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 7690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return sent; 7700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgAllocateRequest::AllocateRequest(RelayEntry* entry, 7730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org RelayConnection* connection) 7740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org : StunRequest(new RelayMessage()), 7750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry_(entry), 7760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org connection_(connection) { 7772a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org start_time_ = rtc::Time(); 7780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocateRequest::Prepare(StunMessage* request) { 7810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org request->SetType(STUN_ALLOCATE_REQUEST); 7820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunByteStringAttribute* username_attr = 7840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org StunAttribute::CreateByteString(STUN_ATTR_USERNAME); 7850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org username_attr->CopyBytes( 7860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry_->port()->username_fragment().c_str(), 7870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry_->port()->username_fragment().size()); 7880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org VERIFY(request->AddAttribute(username_attr)); 7890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgint AllocateRequest::GetNextDelay() { 7922a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org int delay = 100 * rtc::_max(1 << count_, 2); 7930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org count_ += 1; 7940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (count_ == 5) 7950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org timeout_ = true; 7960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return delay; 7970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 7980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 7990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocateRequest::OnResponse(StunMessage* response) { 8000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const StunAddressAttribute* addr_attr = 8010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org response->GetAddress(STUN_ATTR_MAPPED_ADDRESS); 8020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!addr_attr) { 8030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Allocate response missing mapped address."; 8040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else if (addr_attr->family() != 1) { 8050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Mapped address has bad family"; 8060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 8072a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org rtc::SocketAddress addr(addr_attr->ipaddr(), addr_attr->port()); 8080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry_->OnConnect(addr, connection_); 8090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // We will do a keep-alive regardless of whether this request suceeds. 8120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // This should have almost no impact on network usage. 8130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry_->ScheduleKeepAlive(); 8140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocateRequest::OnErrorResponse(StunMessage* response) { 8170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org const StunErrorCodeAttribute* attr = response->GetErrorCode(); 8180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!attr) { 8190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Bad allocate response error code"; 8200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 8210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Allocate error response:" 8220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " code=" << attr->code() 8230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << " reason='" << attr->reason() << "'"; 8240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 8250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org if (rtc::TimeSince(start_time_) <= kRetryTimeout) 8270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry_->ScheduleKeepAlive(); 8280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid AllocateRequest::OnTimeout() { 8310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org LOG(INFO) << "Allocate request timed out"; 8320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org entry_->HandleConnectFailure(connection_->socket()); 8330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 8340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 8350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 836