10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2012, 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 */
271b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org#if defined(POSIX)
281b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org#include <dirent.h>
291b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org#endif
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
31cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/basicpacketsocketfactory.h"
32cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/constants.h"
33cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/tcpport.h"
34cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/testturnserver.h"
35cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/turnport.h"
36cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/udpport.h"
372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/asynctcpsocket.h"
382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/buffer.h"
392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/dscp.h"
402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/firewallsocketserver.h"
412a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/gunit.h"
422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/helpers.h"
43cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/logging.h"
442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/physicalsocketserver.h"
452a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/scoped_ptr.h"
462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/socketaddress.h"
472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/ssladapter.h"
482a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/thread.h"
492a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/virtualsocketserver.h"
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
512a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgusing rtc::SocketAddress;
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::Connection;
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::Port;
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::PortInterface;
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::TurnPort;
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::UDPPort;
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kLocalAddr1("11.11.11.11", 0);
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kLocalAddr2("22.22.22.22", 0);
605c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgstatic const SocketAddress kLocalIPv6Addr(
615c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kTurnUdpIntAddr("99.99.99.3",
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                           cricket::TURN_SERVER_PORT);
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kTurnTcpIntAddr("99.99.99.4",
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                           cricket::TURN_SERVER_PORT);
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
6799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.orgstatic const SocketAddress kTurnAlternateUdpIntAddr(
6899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org    "99.99.99.6", cricket::TURN_SERVER_PORT);
695c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgstatic const SocketAddress kTurnUdpIPv6IntAddr(
705c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    "2400:4030:1:2c00:be30:abcd:efab:cdef", cricket::TURN_SERVER_PORT);
715c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgstatic const SocketAddress kTurnUdpIPv6ExtAddr(
725c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  "2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0);
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kIceUfrag1[] = "TESTICEUFRAG0001";
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kIceUfrag2[] = "TESTICEUFRAG0002";
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kIcePwd1[] = "TESTICEPWD00000000000001";
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kIcePwd2[] = "TESTICEPWD00000000000002";
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kTurnUsername[] = "test";
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const char kTurnPassword[] = "test";
801b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.orgstatic const unsigned int kTimeout = 1000;
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
825aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgstatic const cricket::ProtocolAddress kTurnUdpProtoAddr(
835aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    kTurnUdpIntAddr, cricket::PROTO_UDP);
845aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgstatic const cricket::ProtocolAddress kTurnTcpProtoAddr(
855aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    kTurnTcpIntAddr, cricket::PROTO_TCP);
865c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgstatic const cricket::ProtocolAddress kTurnUdpIPv6ProtoAddr(
875c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
891b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.orgstatic const unsigned int MSG_TESTFINISH = 0;
901b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org
911b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org#if defined(LINUX)
921b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.orgstatic int GetFDCount() {
931b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  struct dirent *dp;
941b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  int fd_count = 0;
951b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  DIR *dir = opendir("/proc/self/fd/");
961b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  while ((dp = readdir(dir)) != NULL) {
971b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org    if (dp->d_name[0] == '.')
981b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org      continue;
991b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org    ++fd_count;
1001b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  }
1011b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  closedir(dir);
1021b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  return fd_count;
1031b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org}
1041b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org#endif
1051b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass TurnPortTest : public testing::Test,
1071b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org                     public sigslot::has_slots<>,
1082a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                     public rtc::MessageHandler {
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TurnPortTest()
1112a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      : main_(rtc::Thread::Current()),
1122a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        pss_(new rtc::PhysicalSocketServer),
1132a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        ss_(new rtc::VirtualSocketServer(pss_.get())),
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ss_scope_(ss_.get()),
1152a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
1162a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        socket_factory_(rtc::Thread::Current()),
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        turn_ready_(false),
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        turn_error_(false),
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        turn_unknown_address_(false),
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        turn_create_permission_success_(false),
1221b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org        udp_ready_(false),
1231b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org        test_finish_(false) {
1242a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    network_.AddIP(rtc::IPAddress(INADDR_ANY));
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
127d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  static void SetUpTestCase() {
1282a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::InitializeSSL();
129d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  }
130d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org
131d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  static void TearDownTestCase() {
1322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::CleanupSSL();
133d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  }
134d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org
1352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  virtual void OnMessage(rtc::Message* msg) {
1361b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org    ASSERT(msg->message_id == MSG_TESTFINISH);
1371b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org    if (msg->message_id == MSG_TESTFINISH)
1381b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org      test_finish_ = true;
1391b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  }
1401b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnTurnPortComplete(Port* port) {
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_ready_ = true;
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnTurnPortError(Port* port) {
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_error_ = true;
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnTurnUnknownAddress(PortInterface* port, const SocketAddress& addr,
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            cricket::ProtocolType proto,
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            cricket::IceMessage* msg, const std::string& rf,
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            bool /*port_muxed*/) {
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_unknown_address_ = true;
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnTurnCreatePermissionResult(TurnPort* port, const SocketAddress& addr,
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                     int code) {
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Ignoring the address.
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (code == 0) {
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      turn_create_permission_success_ = true;
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
160f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org  void OnTurnReadPacket(Connection* conn, const char* data, size_t size,
1612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                        const rtc::PacketTime& packet_time) {
1622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    turn_packets_.push_back(rtc::Buffer(data, size));
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnUdpPortComplete(Port* port) {
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    udp_ready_ = true;
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
167f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org  void OnUdpReadPacket(Connection* conn, const char* data, size_t size,
1682a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                       const rtc::PacketTime& packet_time) {
1692a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    udp_packets_.push_back(rtc::Buffer(data, size));
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void OnSocketReadPacket(rtc::AsyncPacketSocket* socket,
172afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org                          const char* data, size_t size,
1732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                          const rtc::SocketAddress& remote_addr,
1742a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                          const rtc::PacketTime& packet_time) {
175afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    turn_port_->HandleIncomingPacket(socket, data, size, remote_addr,
176afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org                                     packet_time);
177afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  }
1782a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
1792a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_STREAM);
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_GE(socket->Bind(addr), 0);
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_GE(socket->Listen(5), 0);
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return socket;
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CreateTurnPort(const std::string& username,
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      const std::string& password,
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      const cricket::ProtocolAddress& server_address) {
1885c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    CreateTurnPort(kLocalAddr1, username, password, server_address);
1895c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  }
1902a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void CreateTurnPort(const rtc::SocketAddress& local_address,
1915c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                      const std::string& username,
1925c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                      const std::string& password,
1935c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                      const cricket::ProtocolAddress& server_address) {
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::RelayCredentials credentials(username, password);
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_port_.reset(TurnPort::Create(main_, &socket_factory_, &network_,
1965c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                                 local_address.ipaddr(), 0, 0,
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 kIceUfrag1, kIcePwd1,
19888853c77c292bbaeb93f79bfe1dee6f95f70b384mallinath@webrtc.org                                 server_address, credentials, 0));
199b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
200b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    // in Hybrid mode. Protocol type is necessary to send correct type STUN ping
201b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    // messages.
202b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    // This TURN port will be the controlling.
203b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    turn_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
204b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    turn_port_->SetIceRole(cricket::ICEROLE_CONTROLLING);
205afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    ConnectSignals();
206afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  }
207afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org
208afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  void CreateSharedTurnPort(const std::string& username,
209afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org                            const std::string& password,
210afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org                            const cricket::ProtocolAddress& server_address) {
211005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org    ASSERT(server_address.proto == cricket::PROTO_UDP);
212005164e2d795e55bbadcce1be828bd39f04c07fdbuildbot@webrtc.org
2135d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org    if (!socket_) {
2145d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org      socket_.reset(socket_factory_.CreateUdpSocket(
2155d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org          rtc::SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0));
2165d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org      ASSERT_TRUE(socket_ != NULL);
2175d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org      socket_->SignalReadPacket.connect(
2185d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org          this, &TurnPortTest::OnSocketReadPacket);
2195d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org    }
220afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org
221afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    cricket::RelayCredentials credentials(username, password);
222afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    turn_port_.reset(cricket::TurnPort::Create(
223ba4b69f4755d1bfb1a956f390cb3ce2713189cf2buildbot@webrtc.org        main_, &socket_factory_, &network_, socket_.get(),
22488853c77c292bbaeb93f79bfe1dee6f95f70b384mallinath@webrtc.org        kIceUfrag1, kIcePwd1, server_address, credentials, 0));
225afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
226afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    // in Hybrid mode. Protocol type is necessary to send correct type STUN ping
227afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    // messages.
228afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    // This TURN port will be the controlling.
229afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    turn_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
230afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    turn_port_->SetIceRole(cricket::ICEROLE_CONTROLLING);
231afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org    ConnectSignals();
232afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  }
233afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org
234afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  void ConnectSignals() {
2350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_port_->SignalPortComplete.connect(this,
2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &TurnPortTest::OnTurnPortComplete);
2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_port_->SignalPortError.connect(this,
2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &TurnPortTest::OnTurnPortError);
2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_port_->SignalUnknownAddress.connect(this,
2400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &TurnPortTest::OnTurnUnknownAddress);
2410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_port_->SignalCreatePermissionResult.connect(this,
2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &TurnPortTest::OnTurnCreatePermissionResult);
2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CreateUdpPort() {
2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    udp_port_.reset(UDPPort::Create(main_, &socket_factory_, &network_,
2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    kLocalAddr2.ipaddr(), 0, 0,
2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    kIceUfrag2, kIcePwd2));
248b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    // Set protocol type to RFC5245, as turn port is also in same mode.
249b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    // UDP port will be controlled.
250b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    udp_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
251b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org    udp_port_->SetIceRole(cricket::ICEROLE_CONTROLLED);
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    udp_port_->SignalPortComplete.connect(
2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        this, &TurnPortTest::OnUdpPortComplete);
2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void TestTurnConnection() {
2570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create ports and prepare addresses.
2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(turn_port_ != NULL);
2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_port_->PrepareAddress();
2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE_WAIT(turn_ready_, kTimeout);
2610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    CreateUdpPort();
2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    udp_port_->PrepareAddress();
2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE_WAIT(udp_ready_, kTimeout);
2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Send ping from UDP to TURN.
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    Connection* conn1 = udp_port_->CreateConnection(
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(conn1 != NULL);
2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    conn1->Ping(0);
2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    WAIT(!turn_unknown_address_, kTimeout);
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_FALSE(turn_unknown_address_);
2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(Connection::STATE_READ_INIT, conn1->read_state());
2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Send ping from TURN to UDP.
2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    Connection* conn2 = turn_port_->CreateConnection(
2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(conn2 != NULL);
2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE_WAIT(turn_create_permission_success_, kTimeout);
2800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    conn2->Ping(0);
2810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(Connection::STATE_READABLE, conn1->read_state());
2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(Connection::STATE_READ_INIT, conn2->read_state());
2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Send another ping from UDP to TURN.
2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    conn1->Ping(0);
2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ(Connection::STATE_READABLE, conn2->read_state());
2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void TestTurnSendData() {
2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    turn_port_->PrepareAddress();
2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
2960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    CreateUdpPort();
2970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    udp_port_->PrepareAddress();
2980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_TRUE_WAIT(udp_ready_, kTimeout);
2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Create connections and send pings.
3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    Connection* conn1 = turn_port_->CreateConnection(
3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    Connection* conn2 = udp_port_->CreateConnection(
3030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(conn1 != NULL);
3050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_TRUE(conn2 != NULL);
3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    &TurnPortTest::OnTurnReadPacket);
3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    &TurnPortTest::OnUdpReadPacket);
3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    conn1->Ping(0);
3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    conn2->Ping(0);
3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Send some data.
3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    size_t num_packets = 256;
3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (size_t i = 0; i < num_packets; ++i) {
318d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org      unsigned char buf[256] = { 0 };
3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (size_t j = 0; j < i + 1; ++j) {
320d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org        buf[j] = 0xFF - static_cast<unsigned char>(j);
3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
322f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org      conn1->Send(buf, i + 1, options);
323f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org      conn2->Send(buf, i + 1, options);
3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      main_->ProcessMessages(0);
3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Check the data.
3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_EQ_WAIT(num_packets, turn_packets_.size(), kTimeout);
3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT_EQ_WAIT(num_packets, udp_packets_.size(), kTimeout);
3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (size_t i = 0; i < num_packets; ++i) {
3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(i + 1, turn_packets_[i].length());
3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(i + 1, udp_packets_[i].length());
3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      EXPECT_EQ(turn_packets_[i], udp_packets_[i]);
3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected:
3382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Thread* main_;
3392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
3402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
3412a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SocketServerScope ss_scope_;
3422a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Network network_;
3432a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::BasicPacketSocketFactory socket_factory_;
3442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::AsyncPacketSocket> socket_;
3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::TestTurnServer turn_server_;
3462a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<TurnPort> turn_port_;
3472a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<UDPPort> udp_port_;
3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool turn_ready_;
3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool turn_error_;
3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool turn_unknown_address_;
3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool turn_create_permission_success_;
3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool udp_ready_;
3531b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  bool test_finish_;
3542a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  std::vector<rtc::Buffer> turn_packets_;
3552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  std::vector<rtc::Buffer> udp_packets_;
3562a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::PacketOptions options;
3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Do a normal TURN allocation.
3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnAllocate) {
3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
3622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10*1024));
3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  turn_port_->PrepareAddress();
3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_EQ(1U, turn_port_->Candidates().size());
3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            turn_port_->Candidates()[0].address().ipaddr());
3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
371d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org// Testing a normal UDP allocation using TCP connection.
3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnTcpAllocate) {
3735c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
3752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  EXPECT_EQ(0, turn_port_->SetOption(rtc::Socket::OPT_SNDBUF, 10*1024));
3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  turn_port_->PrepareAddress();
3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_EQ(1U, turn_port_->Candidates().size());
3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            turn_port_->Candidates()[0].address().ipaddr());
3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
384d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org// Testing turn port will attempt to create TCP socket on address resolution
385d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org// failure.
3862b324350bd7d310a7ce8ebdaffc06c849b63ac3fhenrik.lundin@webrtc.orgTEST_F(TurnPortTest, DISABLED_TestTurnTcpOnAddressResolveFailure) {
387d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
388d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, cricket::ProtocolAddress(
3892a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::SocketAddress("www.webrtc-blah-blah.com", 3478),
390d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org      cricket::PROTO_TCP));
391d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  turn_port_->PrepareAddress();
392d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
393d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  // As VSS doesn't provide a DNS resolution, name resolve will fail. TurnPort
394d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  // will proceed in creating a TCP socket which will fail as there is no
395d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  // server on the above domain and error will be set to SOCKET_ERROR.
396d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  EXPECT_EQ(SOCKET_ERROR, turn_port_->error());
397d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org}
398d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org
399d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org// In case of UDP on address resolve failure, TurnPort will not create socket
400d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org// and return allocate failure.
4012b324350bd7d310a7ce8ebdaffc06c849b63ac3fhenrik.lundin@webrtc.orgTEST_F(TurnPortTest, DISABLED_TestTurnUdpOnAdressResolveFailure) {
402d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, cricket::ProtocolAddress(
4032a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::SocketAddress("www.webrtc-blah-blah.com", 3478),
404d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org      cricket::PROTO_UDP));
405d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  turn_port_->PrepareAddress();
406d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
407d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  // Error from turn port will not be socket error.
408d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org  EXPECT_NE(SOCKET_ERROR, turn_port_->error());
409d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org}
410d5c92b85d9cfde61d23274053885bad591f0b6f1mallinath@webrtc.org
4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Try to do a TURN allocation with an invalid password.
4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  turn_port_->PrepareAddress();
4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
4160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_EQ(0U, turn_port_->Candidates().size());
4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4195d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org// Tests that a new local address is created after
4205d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org// STUN_ERROR_ALLOCATION_MISMATCH.
4215d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.orgTEST_F(TurnPortTest, TestTurnAllocateMismatch) {
4225d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Do a normal allocation first.
4235d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
4245d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_port_->PrepareAddress();
4255d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
4265d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
4275d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4285d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Forces the socket server to assign the same port.
4295d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  ss_->SetNextPortForTesting(first_addr.port());
4305d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4315d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_ready_ = false;
4325d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
4335d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_port_->PrepareAddress();
4345d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4355d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Verifies that the new port has the same address.
4365d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
4375d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4385d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
4395d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4405d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Verifies that the new port has a different address now.
4415d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
4425d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org}
4435d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4445d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org// Tests that a shared-socket-TurnPort creates its own socket after
4455d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org// STUN_ERROR_ALLOCATION_MISMATCH.
4465d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.orgTEST_F(TurnPortTest, TestSharedSocketAllocateMismatch) {
4475d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Do a normal allocation first.
4485d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
4495d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_port_->PrepareAddress();
4505d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
4515d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
4525d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4535d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_ready_ = false;
4545d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
4555d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4565d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Verifies that the new port has the same address.
4575d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
4585d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_TRUE(turn_port_->SharedSocket());
4595d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4605d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_port_->PrepareAddress();
4615d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
4625d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4635d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Verifies that the new port has a different address now.
4645d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
4655d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_FALSE(turn_port_->SharedSocket());
4665d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org}
4675d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4685d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.orgTEST_F(TurnPortTest, TestTurnTcpAllocateMismatch) {
4695d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
4705d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
4715d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4725d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Do a normal allocation first.
4735d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_port_->PrepareAddress();
4745d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
4755d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  rtc::SocketAddress first_addr(turn_port_->socket()->GetLocalAddress());
4765d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4775d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Forces the socket server to assign the same port.
4785d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  ss_->SetNextPortForTesting(first_addr.port());
4795d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4805d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_ready_ = false;
4815d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
4825d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  turn_port_->PrepareAddress();
4835d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4845d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Verifies that the new port has the same address.
4855d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_EQ(first_addr, turn_port_->socket()->GetLocalAddress());
4865d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4875d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
4885d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4895d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  // Verifies that the new port has a different address now.
4905d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org  EXPECT_NE(first_addr, turn_port_->socket()->GetLocalAddress());
4915d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org}
4925d22694815f501a07eaf1109724c10bca6f29db8jiayl@webrtc.org
4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Do a TURN allocation and try to send a packet to it from the outside.
4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// The packet should be dropped. Then, try to send a packet from TURN to the
4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// outside. It should reach its destination. Finally, try again from the
4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// outside. It should now work as well.
4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnConnection) {
4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTurnConnection();
5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
502afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org// Similar to above, except that this test will use the shared socket.
503afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.orgTEST_F(TurnPortTest, TestTurnConnectionUsingSharedSocket) {
504afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
505afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  TestTurnConnection();
506afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org}
507afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org
5085aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org// Test that we can establish a TCP connection with TURN server.
5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnTcpConnection) {
5105c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTurnConnection();
5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5155aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org// Test that we fail to create a connection when we want to use TLS over TCP.
5165aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org// This test should be removed once we have TLS support.
5175aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgTEST_F(TurnPortTest, TestTurnTlsTcpConnectionFails) {
5185aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  cricket::ProtocolAddress secure_addr(kTurnTcpProtoAddr.address,
5195aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org                                       kTurnTcpProtoAddr.proto,
5205aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org                                       true);
5215aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, secure_addr);
5225aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  turn_port_->PrepareAddress();
5235aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
5245aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  ASSERT_EQ(0U, turn_port_->Candidates().size());
5255aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
5265aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
52799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org// Test try-alternate-server feature.
52899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.orgTEST_F(TurnPortTest, TestTurnAlternateServer) {
52999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  std::vector<rtc::SocketAddress> redirect_addresses;
53099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
53199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
53299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  cricket::TestTurnRedirector redirector(redirect_addresses);
53399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
53499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org                                 cricket::PROTO_UDP);
53599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.set_redirect_hook(&redirector);
53699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
53799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
53899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  // Retrieve the address before we run the state machine.
53999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  const SocketAddress old_addr = turn_port_->server_address().address;
54099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
54199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_port_->PrepareAddress();
54299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
54399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  // Retrieve the address again, the turn port's address should be
54499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  // changed.
54599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  const SocketAddress new_addr = turn_port_->server_address().address;
54699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_NE(old_addr, new_addr);
54799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  ASSERT_EQ(1U, turn_port_->Candidates().size());
54899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
54999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org            turn_port_->Candidates()[0].address().ipaddr());
55099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
55199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org}
55299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
55399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org// Test that we fail when we redirect to an address different from
55499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org// current IP family.
55599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.orgTEST_F(TurnPortTest, TestTurnAlternateServerV4toV6) {
55699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  std::vector<rtc::SocketAddress> redirect_addresses;
55799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  redirect_addresses.push_back(kTurnUdpIPv6IntAddr);
55899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
55999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  cricket::TestTurnRedirector redirector(redirect_addresses);
56099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
56199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org                                 cricket::PROTO_UDP);
56299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.set_redirect_hook(&redirector);
56399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
56499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_port_->PrepareAddress();
56599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
56699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org}
56799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
56899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org// Test that we fail to handle alternate-server response over TCP protocol.
56999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.orgTEST_F(TurnPortTest, TestTurnAlternateServerTcp) {
57099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  std::vector<rtc::SocketAddress> redirect_addresses;
57199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
57299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
57399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  cricket::TestTurnRedirector redirector(redirect_addresses);
57499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.set_redirect_hook(&redirector);
57599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
57699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
57799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
57899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr, cricket::PROTO_TCP);
57999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_port_->PrepareAddress();
58099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
58199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org}
58299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
58399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org// Test try-alternate-server catches the case of pingpong.
58499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.orgTEST_F(TurnPortTest, TestTurnAlternateServerPingPong) {
58599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  std::vector<rtc::SocketAddress> redirect_addresses;
58699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
58799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  redirect_addresses.push_back(kTurnUdpIntAddr);
58899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
58999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  cricket::TestTurnRedirector redirector(redirect_addresses);
59099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
59199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
59299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org                                 cricket::PROTO_UDP);
59399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.set_redirect_hook(&redirector);
59499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
59599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
59699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_port_->PrepareAddress();
59799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
59899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  ASSERT_EQ(0U, turn_port_->Candidates().size());
59999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  rtc::SocketAddress address;
60099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  // Verify that we have exhausted all alternate servers instead of
60199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  // failure caused by other errors.
60299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_FALSE(redirector.ShouldRedirect(address, &address));
60399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org}
60499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
60599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org// Test try-alternate-server catch the case of repeated server.
60699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.orgTEST_F(TurnPortTest, TestTurnAlternateServerDetectRepetition) {
60799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  std::vector<rtc::SocketAddress> redirect_addresses;
60899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
60999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  redirect_addresses.push_back(kTurnAlternateUdpIntAddr);
61099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
61199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  cricket::TestTurnRedirector redirector(redirect_addresses);
61299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
61399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.AddInternalSocket(kTurnAlternateUdpIntAddr,
61499a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org                                 cricket::PROTO_UDP);
61599a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_server_.set_redirect_hook(&redirector);
61699a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
61799a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
61899a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  turn_port_->PrepareAddress();
61999a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  EXPECT_TRUE_WAIT(turn_error_, kTimeout);
62099a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org  ASSERT_EQ(0U, turn_port_->Candidates().size());
62199a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org}
62299a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
62399a17fdd47621fec9dc34b80409579b6c210ab44guoweis@webrtc.org
6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Run TurnConnectionTest with one-time-use nonce feature.
6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Here server will send a 438 STALE_NONCE error message for
6260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// every TURN transaction.
6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  turn_server_.set_enable_otu_nonce(true);
6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTurnConnection();
6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6335c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org// Do a TURN allocation, establish a UDP connection, and send some data.
6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Create ports and prepare addresses.
6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTurnSendData();
6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6405c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org// Do a TURN allocation, establish a TCP connection, and send some data.
6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
6425c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
6430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Create ports and prepare addresses.
6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TestTurnSendData();
6460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6475c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
6485c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org// Test TURN fails to make a connection from IPv6 address to a server which has
6495c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org// IPv4 address.
6505c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgTEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
6515c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
6525c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
6535c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                 kTurnUdpProtoAddr);
6545c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  turn_port_->PrepareAddress();
6555c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  ASSERT_TRUE_WAIT(turn_error_, kTimeout);
6565c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  EXPECT_TRUE(turn_port_->Candidates().empty());
6575c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org}
6585c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
6595c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org// Test TURN make a connection from IPv6 address to a server which has
6605c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org// IPv6 intenal address. But in this test external address is a IPv4 address,
6615c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org// hence allocated address will be a IPv4 address.
6625c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgTEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
6635c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
6645c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
6655c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                 kTurnUdpIPv6ProtoAddr);
6665c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  turn_port_->PrepareAddress();
6675c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
6685c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  ASSERT_EQ(1U, turn_port_->Candidates().size());
6695c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
6705c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org            turn_port_->Candidates()[0].address().ipaddr());
6715c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
6725c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org}
6735c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
6741b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org// This test verifies any FD's are not leaked after TurnPort is destroyed.
6751b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org// https://code.google.com/p/webrtc/issues/detail?id=2651
6761b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org#if defined(LINUX)
6771b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.orgTEST_F(TurnPortTest, TestResolverShutdown) {
6781b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
6791b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  int last_fd_count = GetFDCount();
6801b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  // Need to supply unresolved address to kick off resolver.
6811b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
6822a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                 cricket::ProtocolAddress(rtc::SocketAddress(
6831b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org                    "stun.l.google.com", 3478), cricket::PROTO_UDP));
6841b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  turn_port_->PrepareAddress();
6851b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  ASSERT_TRUE_WAIT(turn_error_, kTimeout);
6861b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  EXPECT_TRUE(turn_port_->Candidates().empty());
6871b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  turn_port_.reset();
6882a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Thread::Current()->Post(this, MSG_TESTFINISH);
6891b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  // Waiting for above message to be processed.
6901b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  ASSERT_TRUE_WAIT(test_finish_, kTimeout);
6911b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org  EXPECT_EQ(last_fd_count, GetFDCount());
6921b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org}
6931b5713169ff3f21791214c4500e5d775048c3ba9wu@webrtc.org#endif
694