Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2012, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 #if defined(POSIX)
     28 #include <dirent.h>
     29 #endif
     30 
     31 #include "talk/base/asynctcpsocket.h"
     32 #include "talk/base/buffer.h"
     33 #include "talk/base/dscp.h"
     34 #include "talk/base/firewallsocketserver.h"
     35 #include "talk/base/logging.h"
     36 #include "talk/base/gunit.h"
     37 #include "talk/base/helpers.h"
     38 #include "talk/base/physicalsocketserver.h"
     39 #include "talk/base/scoped_ptr.h"
     40 #include "talk/base/socketaddress.h"
     41 #include "talk/base/thread.h"
     42 #include "talk/base/virtualsocketserver.h"
     43 #include "talk/p2p/base/basicpacketsocketfactory.h"
     44 #include "talk/p2p/base/constants.h"
     45 #include "talk/p2p/base/tcpport.h"
     46 #include "talk/p2p/base/testturnserver.h"
     47 #include "talk/p2p/base/turnport.h"
     48 #include "talk/p2p/base/udpport.h"
     49 
     50 using talk_base::SocketAddress;
     51 using cricket::Connection;
     52 using cricket::Port;
     53 using cricket::PortInterface;
     54 using cricket::TurnPort;
     55 using cricket::UDPPort;
     56 
     57 static const SocketAddress kLocalAddr1("11.11.11.11", 0);
     58 static const SocketAddress kLocalAddr2("22.22.22.22", 0);
     59 static const SocketAddress kLocalIPv6Addr(
     60     "2401:fa00:4:1000:be30:5bff:fee5:c3", 0);
     61 static const SocketAddress kTurnUdpIntAddr("99.99.99.3",
     62                                            cricket::TURN_SERVER_PORT);
     63 static const SocketAddress kTurnTcpIntAddr("99.99.99.4",
     64                                            cricket::TURN_SERVER_PORT);
     65 static const SocketAddress kTurnUdpExtAddr("99.99.99.5", 0);
     66 static const SocketAddress kTurnUdpIPv6IntAddr(
     67     "2400:4030:1:2c00:be30:abcd:efab:cdef", cricket::TURN_SERVER_PORT);
     68 static const SocketAddress kTurnUdpIPv6ExtAddr(
     69   "2620:0:1000:1b03:2e41:38ff:fea6:f2a4", 0);
     70 
     71 static const char kIceUfrag1[] = "TESTICEUFRAG0001";
     72 static const char kIceUfrag2[] = "TESTICEUFRAG0002";
     73 static const char kIcePwd1[] = "TESTICEPWD00000000000001";
     74 static const char kIcePwd2[] = "TESTICEPWD00000000000002";
     75 static const char kTurnUsername[] = "test";
     76 static const char kTurnPassword[] = "test";
     77 static const unsigned int kTimeout = 1000;
     78 
     79 static const cricket::ProtocolAddress kTurnUdpProtoAddr(
     80     kTurnUdpIntAddr, cricket::PROTO_UDP);
     81 static const cricket::ProtocolAddress kTurnTcpProtoAddr(
     82     kTurnTcpIntAddr, cricket::PROTO_TCP);
     83 static const cricket::ProtocolAddress kTurnUdpIPv6ProtoAddr(
     84     kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
     85 
     86 static const unsigned int MSG_TESTFINISH = 0;
     87 
     88 #if defined(LINUX)
     89 static int GetFDCount() {
     90   struct dirent *dp;
     91   int fd_count = 0;
     92   DIR *dir = opendir("/proc/self/fd/");
     93   while ((dp = readdir(dir)) != NULL) {
     94     if (dp->d_name[0] == '.')
     95       continue;
     96     ++fd_count;
     97   }
     98   closedir(dir);
     99   return fd_count;
    100 }
    101 #endif
    102 
    103 class TurnPortTest : public testing::Test,
    104                      public sigslot::has_slots<>,
    105                      public talk_base::MessageHandler {
    106  public:
    107   TurnPortTest()
    108       : main_(talk_base::Thread::Current()),
    109         pss_(new talk_base::PhysicalSocketServer),
    110         ss_(new talk_base::VirtualSocketServer(pss_.get())),
    111         ss_scope_(ss_.get()),
    112         network_("unittest", "unittest", talk_base::IPAddress(INADDR_ANY), 32),
    113         socket_factory_(talk_base::Thread::Current()),
    114         turn_server_(main_, kTurnUdpIntAddr, kTurnUdpExtAddr),
    115         turn_ready_(false),
    116         turn_error_(false),
    117         turn_unknown_address_(false),
    118         turn_create_permission_success_(false),
    119         udp_ready_(false),
    120         test_finish_(false) {
    121     network_.AddIP(talk_base::IPAddress(INADDR_ANY));
    122   }
    123 
    124   virtual void OnMessage(talk_base::Message* msg) {
    125     ASSERT(msg->message_id == MSG_TESTFINISH);
    126     if (msg->message_id == MSG_TESTFINISH)
    127       test_finish_ = true;
    128   }
    129 
    130   void OnTurnPortComplete(Port* port) {
    131     turn_ready_ = true;
    132   }
    133   void OnTurnPortError(Port* port) {
    134     turn_error_ = true;
    135   }
    136   void OnTurnUnknownAddress(PortInterface* port, const SocketAddress& addr,
    137                             cricket::ProtocolType proto,
    138                             cricket::IceMessage* msg, const std::string& rf,
    139                             bool /*port_muxed*/) {
    140     turn_unknown_address_ = true;
    141   }
    142   void OnTurnCreatePermissionResult(TurnPort* port, const SocketAddress& addr,
    143                                      int code) {
    144     // Ignoring the address.
    145     if (code == 0) {
    146       turn_create_permission_success_ = true;
    147     }
    148   }
    149   void OnTurnReadPacket(Connection* conn, const char* data, size_t size,
    150                         const talk_base::PacketTime& packet_time) {
    151     turn_packets_.push_back(talk_base::Buffer(data, size));
    152   }
    153   void OnUdpPortComplete(Port* port) {
    154     udp_ready_ = true;
    155   }
    156   void OnUdpReadPacket(Connection* conn, const char* data, size_t size,
    157                        const talk_base::PacketTime& packet_time) {
    158     udp_packets_.push_back(talk_base::Buffer(data, size));
    159   }
    160   void OnSocketReadPacket(talk_base::AsyncPacketSocket* socket,
    161                           const char* data, size_t size,
    162                           const talk_base::SocketAddress& remote_addr,
    163                           const talk_base::PacketTime& packet_time) {
    164     turn_port_->HandleIncomingPacket(socket, data, size, remote_addr,
    165                                      packet_time);
    166   }
    167   talk_base::AsyncSocket* CreateServerSocket(const SocketAddress addr) {
    168     talk_base::AsyncSocket* socket = ss_->CreateAsyncSocket(SOCK_STREAM);
    169     EXPECT_GE(socket->Bind(addr), 0);
    170     EXPECT_GE(socket->Listen(5), 0);
    171     return socket;
    172   }
    173 
    174   void CreateTurnPort(const std::string& username,
    175                       const std::string& password,
    176                       const cricket::ProtocolAddress& server_address) {
    177     CreateTurnPort(kLocalAddr1, username, password, server_address);
    178   }
    179   void CreateTurnPort(const talk_base::SocketAddress& local_address,
    180                       const std::string& username,
    181                       const std::string& password,
    182                       const cricket::ProtocolAddress& server_address) {
    183     cricket::RelayCredentials credentials(username, password);
    184     turn_port_.reset(TurnPort::Create(main_, &socket_factory_, &network_,
    185                                  local_address.ipaddr(), 0, 0,
    186                                  kIceUfrag1, kIcePwd1,
    187                                  server_address, credentials));
    188     // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
    189     // in Hybrid mode. Protocol type is necessary to send correct type STUN ping
    190     // messages.
    191     // This TURN port will be the controlling.
    192     turn_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
    193     turn_port_->SetIceRole(cricket::ICEROLE_CONTROLLING);
    194     ConnectSignals();
    195   }
    196 
    197   void CreateSharedTurnPort(const std::string& username,
    198                             const std::string& password,
    199                             const cricket::ProtocolAddress& server_address) {
    200     ASSERT(server_address.proto == cricket::PROTO_UDP);
    201 
    202     socket_.reset(socket_factory_.CreateUdpSocket(
    203         talk_base::SocketAddress(kLocalAddr1.ipaddr(), 0), 0, 0));
    204     ASSERT_TRUE(socket_ != NULL);
    205     socket_->SignalReadPacket.connect(this, &TurnPortTest::OnSocketReadPacket);
    206 
    207     cricket::RelayCredentials credentials(username, password);
    208     turn_port_.reset(cricket::TurnPort::Create(
    209         main_, &socket_factory_, &network_, socket_.get(),
    210         kIceUfrag1, kIcePwd1, server_address, credentials));
    211     // Set ICE protocol type to ICEPROTO_RFC5245, as port by default will be
    212     // in Hybrid mode. Protocol type is necessary to send correct type STUN ping
    213     // messages.
    214     // This TURN port will be the controlling.
    215     turn_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
    216     turn_port_->SetIceRole(cricket::ICEROLE_CONTROLLING);
    217     ConnectSignals();
    218   }
    219 
    220   void ConnectSignals() {
    221     turn_port_->SignalPortComplete.connect(this,
    222         &TurnPortTest::OnTurnPortComplete);
    223     turn_port_->SignalPortError.connect(this,
    224         &TurnPortTest::OnTurnPortError);
    225     turn_port_->SignalUnknownAddress.connect(this,
    226         &TurnPortTest::OnTurnUnknownAddress);
    227     turn_port_->SignalCreatePermissionResult.connect(this,
    228         &TurnPortTest::OnTurnCreatePermissionResult);
    229   }
    230   void CreateUdpPort() {
    231     udp_port_.reset(UDPPort::Create(main_, &socket_factory_, &network_,
    232                                     kLocalAddr2.ipaddr(), 0, 0,
    233                                     kIceUfrag2, kIcePwd2));
    234     // Set protocol type to RFC5245, as turn port is also in same mode.
    235     // UDP port will be controlled.
    236     udp_port_->SetIceProtocolType(cricket::ICEPROTO_RFC5245);
    237     udp_port_->SetIceRole(cricket::ICEROLE_CONTROLLED);
    238     udp_port_->SignalPortComplete.connect(
    239         this, &TurnPortTest::OnUdpPortComplete);
    240   }
    241 
    242   void TestTurnConnection() {
    243     // Create ports and prepare addresses.
    244     ASSERT_TRUE(turn_port_ != NULL);
    245     turn_port_->PrepareAddress();
    246     ASSERT_TRUE_WAIT(turn_ready_, kTimeout);
    247     CreateUdpPort();
    248     udp_port_->PrepareAddress();
    249     ASSERT_TRUE_WAIT(udp_ready_, kTimeout);
    250 
    251     // Send ping from UDP to TURN.
    252     Connection* conn1 = udp_port_->CreateConnection(
    253                     turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
    254     ASSERT_TRUE(conn1 != NULL);
    255     conn1->Ping(0);
    256     WAIT(!turn_unknown_address_, kTimeout);
    257     EXPECT_FALSE(turn_unknown_address_);
    258     EXPECT_EQ(Connection::STATE_READ_INIT, conn1->read_state());
    259     EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
    260 
    261     // Send ping from TURN to UDP.
    262     Connection* conn2 = turn_port_->CreateConnection(
    263                     udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
    264     ASSERT_TRUE(conn2 != NULL);
    265     ASSERT_TRUE_WAIT(turn_create_permission_success_, kTimeout);
    266     conn2->Ping(0);
    267 
    268     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
    269     EXPECT_EQ(Connection::STATE_READABLE, conn1->read_state());
    270     EXPECT_EQ(Connection::STATE_READ_INIT, conn2->read_state());
    271     EXPECT_EQ(Connection::STATE_WRITE_INIT, conn1->write_state());
    272 
    273     // Send another ping from UDP to TURN.
    274     conn1->Ping(0);
    275     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
    276     EXPECT_EQ(Connection::STATE_READABLE, conn2->read_state());
    277   }
    278 
    279   void TestTurnSendData() {
    280     turn_port_->PrepareAddress();
    281     EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
    282     CreateUdpPort();
    283     udp_port_->PrepareAddress();
    284     EXPECT_TRUE_WAIT(udp_ready_, kTimeout);
    285     // Create connections and send pings.
    286     Connection* conn1 = turn_port_->CreateConnection(
    287         udp_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
    288     Connection* conn2 = udp_port_->CreateConnection(
    289         turn_port_->Candidates()[0], Port::ORIGIN_MESSAGE);
    290     ASSERT_TRUE(conn1 != NULL);
    291     ASSERT_TRUE(conn2 != NULL);
    292     conn1->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
    293                                     &TurnPortTest::OnTurnReadPacket);
    294     conn2->SignalReadPacket.connect(static_cast<TurnPortTest*>(this),
    295                                     &TurnPortTest::OnUdpReadPacket);
    296     conn1->Ping(0);
    297     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn1->write_state(), kTimeout);
    298     conn2->Ping(0);
    299     EXPECT_EQ_WAIT(Connection::STATE_WRITABLE, conn2->write_state(), kTimeout);
    300 
    301     // Send some data.
    302     size_t num_packets = 256;
    303     for (size_t i = 0; i < num_packets; ++i) {
    304       char buf[256];
    305       for (size_t j = 0; j < i + 1; ++j) {
    306         buf[j] = 0xFF - j;
    307       }
    308       conn1->Send(buf, i + 1, options);
    309       conn2->Send(buf, i + 1, options);
    310       main_->ProcessMessages(0);
    311     }
    312 
    313     // Check the data.
    314     ASSERT_EQ_WAIT(num_packets, turn_packets_.size(), kTimeout);
    315     ASSERT_EQ_WAIT(num_packets, udp_packets_.size(), kTimeout);
    316     for (size_t i = 0; i < num_packets; ++i) {
    317       EXPECT_EQ(i + 1, turn_packets_[i].length());
    318       EXPECT_EQ(i + 1, udp_packets_[i].length());
    319       EXPECT_EQ(turn_packets_[i], udp_packets_[i]);
    320     }
    321   }
    322 
    323  protected:
    324   talk_base::Thread* main_;
    325   talk_base::scoped_ptr<talk_base::PhysicalSocketServer> pss_;
    326   talk_base::scoped_ptr<talk_base::VirtualSocketServer> ss_;
    327   talk_base::SocketServerScope ss_scope_;
    328   talk_base::Network network_;
    329   talk_base::BasicPacketSocketFactory socket_factory_;
    330   talk_base::scoped_ptr<talk_base::AsyncPacketSocket> socket_;
    331   cricket::TestTurnServer turn_server_;
    332   talk_base::scoped_ptr<TurnPort> turn_port_;
    333   talk_base::scoped_ptr<UDPPort> udp_port_;
    334   bool turn_ready_;
    335   bool turn_error_;
    336   bool turn_unknown_address_;
    337   bool turn_create_permission_success_;
    338   bool udp_ready_;
    339   bool test_finish_;
    340   std::vector<talk_base::Buffer> turn_packets_;
    341   std::vector<talk_base::Buffer> udp_packets_;
    342   talk_base::PacketOptions options;
    343 };
    344 
    345 // Do a normal TURN allocation.
    346 TEST_F(TurnPortTest, TestTurnAllocate) {
    347   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
    348   EXPECT_EQ(0, turn_port_->SetOption(talk_base::Socket::OPT_SNDBUF, 10*1024));
    349   turn_port_->PrepareAddress();
    350   EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
    351   ASSERT_EQ(1U, turn_port_->Candidates().size());
    352   EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
    353             turn_port_->Candidates()[0].address().ipaddr());
    354   EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
    355 }
    356 
    357 TEST_F(TurnPortTest, TestTurnTcpAllocate) {
    358   turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
    359   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
    360   EXPECT_EQ(0, turn_port_->SetOption(talk_base::Socket::OPT_SNDBUF, 10*1024));
    361   turn_port_->PrepareAddress();
    362   EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
    363   ASSERT_EQ(1U, turn_port_->Candidates().size());
    364   EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
    365             turn_port_->Candidates()[0].address().ipaddr());
    366   EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
    367 }
    368 
    369 // Try to do a TURN allocation with an invalid password.
    370 TEST_F(TurnPortTest, TestTurnAllocateBadPassword) {
    371   CreateTurnPort(kTurnUsername, "bad", kTurnUdpProtoAddr);
    372   turn_port_->PrepareAddress();
    373   EXPECT_TRUE_WAIT(turn_error_, kTimeout);
    374   ASSERT_EQ(0U, turn_port_->Candidates().size());
    375 }
    376 
    377 // Do a TURN allocation and try to send a packet to it from the outside.
    378 // The packet should be dropped. Then, try to send a packet from TURN to the
    379 // outside. It should reach its destination. Finally, try again from the
    380 // outside. It should now work as well.
    381 TEST_F(TurnPortTest, TestTurnConnection) {
    382   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
    383   TestTurnConnection();
    384 }
    385 
    386 // Similar to above, except that this test will use the shared socket.
    387 TEST_F(TurnPortTest, TestTurnConnectionUsingSharedSocket) {
    388   CreateSharedTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
    389   TestTurnConnection();
    390 }
    391 
    392 // Test that we can establish a TCP connection with TURN server.
    393 TEST_F(TurnPortTest, TestTurnTcpConnection) {
    394   turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
    395   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
    396   TestTurnConnection();
    397 }
    398 
    399 // Test that we fail to create a connection when we want to use TLS over TCP.
    400 // This test should be removed once we have TLS support.
    401 TEST_F(TurnPortTest, TestTurnTlsTcpConnectionFails) {
    402   cricket::ProtocolAddress secure_addr(kTurnTcpProtoAddr.address,
    403                                        kTurnTcpProtoAddr.proto,
    404                                        true);
    405   CreateTurnPort(kTurnUsername, kTurnPassword, secure_addr);
    406   turn_port_->PrepareAddress();
    407   EXPECT_TRUE_WAIT(turn_error_, kTimeout);
    408   ASSERT_EQ(0U, turn_port_->Candidates().size());
    409 }
    410 
    411 // Run TurnConnectionTest with one-time-use nonce feature.
    412 // Here server will send a 438 STALE_NONCE error message for
    413 // every TURN transaction.
    414 TEST_F(TurnPortTest, TestTurnConnectionUsingOTUNonce) {
    415   turn_server_.set_enable_otu_nonce(true);
    416   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
    417   TestTurnConnection();
    418 }
    419 
    420 // Do a TURN allocation, establish a UDP connection, and send some data.
    421 TEST_F(TurnPortTest, TestTurnSendDataTurnUdpToUdp) {
    422   // Create ports and prepare addresses.
    423   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnUdpProtoAddr);
    424   TestTurnSendData();
    425 }
    426 
    427 // Do a TURN allocation, establish a TCP connection, and send some data.
    428 TEST_F(TurnPortTest, TestTurnSendDataTurnTcpToUdp) {
    429   turn_server_.AddInternalSocket(kTurnTcpIntAddr, cricket::PROTO_TCP);
    430   // Create ports and prepare addresses.
    431   CreateTurnPort(kTurnUsername, kTurnPassword, kTurnTcpProtoAddr);
    432   TestTurnSendData();
    433 }
    434 
    435 // Test TURN fails to make a connection from IPv6 address to a server which has
    436 // IPv4 address.
    437 TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv4) {
    438   turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
    439   CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
    440                  kTurnUdpProtoAddr);
    441   turn_port_->PrepareAddress();
    442   ASSERT_TRUE_WAIT(turn_error_, kTimeout);
    443   EXPECT_TRUE(turn_port_->Candidates().empty());
    444 }
    445 
    446 // Test TURN make a connection from IPv6 address to a server which has
    447 // IPv6 intenal address. But in this test external address is a IPv4 address,
    448 // hence allocated address will be a IPv4 address.
    449 TEST_F(TurnPortTest, TestTurnLocalIPv6AddressServerIPv6ExtenalIPv4) {
    450   turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
    451   CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
    452                  kTurnUdpIPv6ProtoAddr);
    453   turn_port_->PrepareAddress();
    454   EXPECT_TRUE_WAIT(turn_ready_, kTimeout);
    455   ASSERT_EQ(1U, turn_port_->Candidates().size());
    456   EXPECT_EQ(kTurnUdpExtAddr.ipaddr(),
    457             turn_port_->Candidates()[0].address().ipaddr());
    458   EXPECT_NE(0, turn_port_->Candidates()[0].address().port());
    459 }
    460 
    461 // This test verifies any FD's are not leaked after TurnPort is destroyed.
    462 // https://code.google.com/p/webrtc/issues/detail?id=2651
    463 #if defined(LINUX)
    464 TEST_F(TurnPortTest, TestResolverShutdown) {
    465   turn_server_.AddInternalSocket(kTurnUdpIPv6IntAddr, cricket::PROTO_UDP);
    466   int last_fd_count = GetFDCount();
    467   // Need to supply unresolved address to kick off resolver.
    468   CreateTurnPort(kLocalIPv6Addr, kTurnUsername, kTurnPassword,
    469                  cricket::ProtocolAddress(talk_base::SocketAddress(
    470                     "stun.l.google.com", 3478), cricket::PROTO_UDP));
    471   turn_port_->PrepareAddress();
    472   ASSERT_TRUE_WAIT(turn_error_, kTimeout);
    473   EXPECT_TRUE(turn_port_->Candidates().empty());
    474   turn_port_.reset();
    475   talk_base::Thread::Current()->Post(this, MSG_TESTFINISH);
    476   // Waiting for above message to be processed.
    477   ASSERT_TRUE_WAIT(test_finish_, kTimeout);
    478   EXPECT_EQ(last_fd_count, GetFDCount());
    479 }
    480 #endif
    481 
    482