10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2009 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/basicpacketsocketfactory.h"
29cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/relayport.h"
30cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/relayserver.h"
312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/gunit.h"
322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/helpers.h"
33cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/logging.h"
342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/physicalsocketserver.h"
352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/scoped_ptr.h"
362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/socketadapters.h"
372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/socketaddress.h"
382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/ssladapter.h"
392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/thread.h"
402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/virtualsocketserver.h"
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgusing rtc::SocketAddress;
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kLocalAddress = SocketAddress("192.168.1.2", 0);
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kRelayUdpAddr = SocketAddress("99.99.99.1", 5000);
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kRelayTcpAddr = SocketAddress("99.99.99.2", 5001);
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kRelaySslAddr = SocketAddress("99.99.99.3", 443);
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kRelayExtAddr = SocketAddress("99.99.99.3", 5002);
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kTimeoutMs = 1000;
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kMaxTimeoutMs = 5000;
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Tests connecting a RelayPort to a fake relay server
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// (cricket::RelayServer) using all currently available protocols. The
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// network layer is faked out by using a VirtualSocketServer for
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// creating sockets. The test will monitor the current state of the
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// RelayPort and created sockets by listening for signals such as,
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// SignalConnectFailure, SignalConnectTimeout, SignalSocketClosed and
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// SignalReadPacket.
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass RelayPortTest : public testing::Test,
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      public sigslot::has_slots<> {
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  RelayPortTest()
642a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      : main_(rtc::Thread::Current()),
652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        physical_socket_server_(new rtc::PhysicalSocketServer),
662a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        virtual_socket_server_(new rtc::VirtualSocketServer(
670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            physical_socket_server_.get())),
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ss_scope_(virtual_socket_server_.get()),
692a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
702a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        socket_factory_(rtc::Thread::Current()),
712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        username_(rtc::CreateRandomString(16)),
722a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        password_(rtc::CreateRandomString(16)),
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        relay_port_(cricket::RelayPort::Create(main_, &socket_factory_,
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                               &network_,
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                               kLocalAddress.ipaddr(),
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                               0, 0, username_, password_)),
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        relay_server_(new cricket::RelayServer(main_)) {
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
802a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void OnReadPacket(rtc::AsyncPacketSocket* socket,
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    const char* data, size_t size,
822a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                    const rtc::SocketAddress& remote_addr,
832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                    const rtc::PacketTime& packet_time) {
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    received_packet_count_[socket]++;
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnConnectFailure(const cricket::ProtocolAddress* addr) {
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    failed_connections_.push_back(*addr);
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnSoftTimeout(const cricket::ProtocolAddress* addr) {
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    soft_timedout_connections_.push_back(*addr);
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected:
960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static void SetUpTestCase() {
972a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::InitializeSSL();
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
100104540ba5b8d056cb0195bcd2e5d20abaa3dde7dmallinath@webrtc.org  static void TearDownTestCase() {
1012a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::CleanupSSL();
102104540ba5b8d056cb0195bcd2e5d20abaa3dde7dmallinath@webrtc.org  }
103104540ba5b8d056cb0195bcd2e5d20abaa3dde7dmallinath@webrtc.org
104104540ba5b8d056cb0195bcd2e5d20abaa3dde7dmallinath@webrtc.org
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  virtual void SetUp() {
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // The relay server needs an external socket to work properly.
1072a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncUDPSocket* ext_socket =
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateAsyncUdpSocket(kRelayExtAddr);
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_server_->AddExternalSocket(ext_socket);
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Listen for failures.
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->SignalConnectFailure.
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        connect(this, &RelayPortTest::OnConnectFailure);
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Listen for soft timeouts.
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->SignalSoftTimeout.
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        connect(this, &RelayPortTest::OnSoftTimeout);
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Udp has the highest 'goodness' value of the three different
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // protocols used for connecting to the relay server. As soon as
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // PrepareAddress is called, the RelayPort will start trying to
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // connect to the given UDP address. As soon as a response to the
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // sent STUN allocate request message has been received, the
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // RelayPort will consider the connection to be complete and will
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // abort any other connection attempts.
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void TestConnectUdp() {
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Add a UDP socket to the relay server.
1292a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncUDPSocket* internal_udp_socket =
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateAsyncUdpSocket(kRelayUdpAddr);
1312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_server_->AddInternalSocket(internal_udp_socket);
1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Now add our relay addresses to the relay port and let it start.
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->AddServerAddress(
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP));
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->AddServerAddress(
1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->PrepareAddress();
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should be connected.
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kTimeoutMs);
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Make sure that we are happy with UDP, ie. not continuing with
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // TCP, SSLTCP, etc.
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    WAIT(relay_server_->HasConnection(kRelayTcpAddr), kTimeoutMs);
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should have only one connection.
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(1, relay_server_->GetConnectionCount());
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should be the UDP address.
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(relay_server_->HasConnection(kRelayUdpAddr));
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TCP has the second best 'goodness' value, and as soon as UDP
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // connection has failed, the RelayPort will attempt to connect via
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TCP. Here we add a fake UDP address together with a real TCP
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // address to simulate an UDP failure. As soon as UDP has failed the
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // RelayPort will try the TCP adress and succed.
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void TestConnectTcp() {
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create a fake UDP address for relay port to simulate a failure.
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::ProtocolAddress fake_protocol_address =
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::ProtocolAddress(kRelayUdpAddr, cricket::PROTO_UDP);
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create a server socket for the RelayServer.
1682a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncSocket* server_socket = CreateServerSocket(kRelayTcpAddr);
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_server_->AddInternalServerSocket(server_socket, cricket::PROTO_TCP);
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Add server addresses to the relay port and let it start.
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->AddServerAddress(
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::ProtocolAddress(fake_protocol_address));
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->AddServerAddress(
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP));
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->PrepareAddress();
1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(relay_port_->IsReady());
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should have timed out in 200 + 200 + 400 + 800 + 1600 ms.
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT(HasFailed(&fake_protocol_address), 3600);
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Wait until relayport is ready.
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should have only one connection.
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(1, relay_server_->GetConnectionCount());
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should be the TCP address.
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(relay_server_->HasConnection(kRelayTcpAddr));
1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void TestConnectSslTcp() {
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create a fake TCP address for relay port to simulate a failure.
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // We skip UDP here since transition from UDP to TCP has been
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // tested above.
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::ProtocolAddress fake_protocol_address =
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::ProtocolAddress(kRelayTcpAddr, cricket::PROTO_TCP);
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create a ssl server socket for the RelayServer.
2012a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncSocket* ssl_server_socket =
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateServerSocket(kRelaySslAddr);
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_server_->AddInternalServerSocket(ssl_server_socket,
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                           cricket::PROTO_SSLTCP);
2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create a tcp server socket that listens on the fake address so
2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // the relay port can attempt to connect to it.
2082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::scoped_ptr<rtc::AsyncSocket> tcp_server_socket(
2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        CreateServerSocket(kRelayTcpAddr));
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Add server addresses to the relay port and let it start.
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->AddServerAddress(fake_protocol_address);
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->AddServerAddress(
2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        cricket::ProtocolAddress(kRelaySslAddr, cricket::PROTO_SSLTCP));
2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    relay_port_->PrepareAddress();
2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(relay_port_->IsReady());
2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should have timed out in 3000 ms(relayport.cc, kSoftConnectTimeoutMs).
2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT_MARGIN(HasTimedOut(&fake_protocol_address), 3000, 100);
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Wait until relayport is ready.
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT(relay_port_->IsReady(), kMaxTimeoutMs);
2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should have only one connection.
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(1, relay_server_->GetConnectionCount());
2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Should be the SSLTCP address.
2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(relay_server_->HasConnection(kRelaySslAddr));
2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private:
2322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::AsyncUDPSocket* CreateAsyncUdpSocket(const SocketAddress addr) {
2332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncSocket* socket =
2340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        virtual_socket_server_->CreateAsyncSocket(SOCK_DGRAM);
2352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncUDPSocket* packet_socket =
2362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::AsyncUDPSocket::Create(socket, addr);
2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE(packet_socket != NULL);
2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    packet_socket->SignalReadPacket.connect(this, &RelayPortTest::OnReadPacket);
2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return packet_socket;
2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
2432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncSocket* socket =
2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        virtual_socket_server_->CreateAsyncSocket(SOCK_STREAM);
2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_GE(socket->Bind(addr), 0);
2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_GE(socket->Listen(5), 0);
2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return socket;
2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool HasFailed(cricket::ProtocolAddress* addr) {
2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (size_t i = 0; i < failed_connections_.size(); i++) {
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (failed_connections_[i].address == addr->address &&
2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          failed_connections_[i].proto == addr->proto) {
2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return true;
2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool HasTimedOut(cricket::ProtocolAddress* addr) {
2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (size_t i = 0; i < soft_timedout_connections_.size(); i++) {
2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (soft_timedout_connections_[i].address == addr->address &&
2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          soft_timedout_connections_[i].proto == addr->proto) {
2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return true;
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2702a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  typedef std::map<rtc::AsyncPacketSocket*, int> PacketMap;
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2722a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Thread* main_;
2732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::PhysicalSocketServer>
2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      physical_socket_server_;
2752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::VirtualSocketServer> virtual_socket_server_;
2762a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SocketServerScope ss_scope_;
2772a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Network network_;
2782a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::BasicPacketSocketFactory socket_factory_;
2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string username_;
2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string password_;
2812a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::RelayPort> relay_port_;
2822a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::RelayServer> relay_server_;
2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::vector<cricket::ProtocolAddress> failed_connections_;
2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::vector<cricket::ProtocolAddress> soft_timedout_connections_;
2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PacketMap received_packet_count_;
2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(RelayPortTest, ConnectUdp) {
2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestConnectUdp();
2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(RelayPortTest, ConnectTcp) {
2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestConnectTcp();
2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(RelayPortTest, ConnectSslTcp) {
2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestConnectSslTcp();
2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
299