10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2009 Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
28cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/basicpacketsocketfactory.h"
29cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/stunport.h"
30cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/p2p/base/teststunserver.h"
312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/gunit.h"
322a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/helpers.h"
332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/physicalsocketserver.h"
342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/scoped_ptr.h"
352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/socketaddress.h"
362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/ssladapter.h"
372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/virtualsocketserver.h"
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
39459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.orgusing cricket::ServerAddresses;
402a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgusing rtc::SocketAddress;
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kLocalAddr("127.0.0.1", 0);
43459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.orgstatic const SocketAddress kStunAddr1("127.0.0.1", 5000);
44459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.orgstatic const SocketAddress kStunAddr2("127.0.0.1", 4000);
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kBadAddr("0.0.0.1", 5000);
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kStunHostnameAddr("localhost", 5000);
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const SocketAddress kBadHostnameAddr("not-a-real-hostname", 5000);
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kTimeoutMs = 10000;
49afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org// stun prio = 100 << 24 | 30 (IPV4) << 8 | 256 - 0
50afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.orgstatic const uint32 kStunCandidatePriority = 1677729535;
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Tests connecting a StunPort to a fake STUN server (cricket::StunServer)
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// TODO: Use a VirtualSocketServer here. We have to use a
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// PhysicalSocketServer right now since DNS is not part of SocketServer yet.
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass StunPortTest : public testing::Test,
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                     public sigslot::has_slots<> {
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  StunPortTest()
592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      : pss_(new rtc::PhysicalSocketServer),
602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        ss_(new rtc::VirtualSocketServer(pss_.get())),
6119da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org        ss_scope_(ss_.get()),
622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        network_("unittest", "unittest", rtc::IPAddress(INADDR_ANY), 32),
632a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        socket_factory_(rtc::Thread::Current()),
64459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org        stun_server_1_(new cricket::TestStunServer(
652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org          rtc::Thread::Current(), kStunAddr1)),
66459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org        stun_server_2_(new cricket::TestStunServer(
672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org          rtc::Thread::Current(), kStunAddr2)),
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        done_(false), error_(false), stun_keepalive_delay_(0) {
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::Port* port() const { return stun_port_.get(); }
720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool done() const { return done_; }
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool error() const { return error_; }
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
752a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void CreateStunPort(const rtc::SocketAddress& server_addr) {
76459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org    ServerAddresses stun_servers;
77459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org    stun_servers.insert(server_addr);
78459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org    CreateStunPort(stun_servers);
79459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  }
80459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org
81459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  void CreateStunPort(const ServerAddresses& stun_servers) {
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stun_port_.reset(cricket::StunPort::Create(
832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::Thread::Current(), &socket_factory_, &network_,
842a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        kLocalAddr.ipaddr(), 0, 0, rtc::CreateRandomString(16),
852a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::CreateRandomString(22), stun_servers));
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stun_port_->set_stun_keepalive_delay(stun_keepalive_delay_);
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stun_port_->SignalPortComplete.connect(this,
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &StunPortTest::OnPortComplete);
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stun_port_->SignalPortError.connect(this,
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        &StunPortTest::OnPortError);
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
932a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void CreateSharedStunPort(const rtc::SocketAddress& server_addr) {
94a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    socket_.reset(socket_factory_.CreateUdpSocket(
952a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::SocketAddress(kLocalAddr.ipaddr(), 0), 0, 0));
96a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    ASSERT_TRUE(socket_ != NULL);
97a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    socket_->SignalReadPacket.connect(this, &StunPortTest::OnReadPacket);
98a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    stun_port_.reset(cricket::UDPPort::Create(
992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::Thread::Current(), &socket_factory_,
10019da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org        &network_, socket_.get(),
1012a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::CreateRandomString(16), rtc::CreateRandomString(22)));
102a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    ASSERT_TRUE(stun_port_ != NULL);
103459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org    ServerAddresses stun_servers;
104459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org    stun_servers.insert(server_addr);
105459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org    stun_port_->set_server_addresses(stun_servers);
106a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    stun_port_->SignalPortComplete.connect(this,
107a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org        &StunPortTest::OnPortComplete);
108a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    stun_port_->SignalPortError.connect(this,
109a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org        &StunPortTest::OnPortError);
110a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
111a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void PrepareAddress() {
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stun_port_->PrepareAddress();
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1162a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  void OnReadPacket(rtc::AsyncPacketSocket* socket, const char* data,
1172a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                    size_t size, const rtc::SocketAddress& remote_addr,
1182a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                    const rtc::PacketTime& packet_time) {
119f89a403cd8db88001322bbb0765c4636fd123700wu@webrtc.org    stun_port_->HandleIncomingPacket(
1202a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        socket, data, size, remote_addr, rtc::PacketTime());
121a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
122a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
123a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  void SendData(const char* data, size_t len) {
124a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    stun_port_->HandleIncomingPacket(
1252a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        socket_.get(), data, len, rtc::SocketAddress("22.22.22.22", 0),
1262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org        rtc::PacketTime());
127a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
128a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org protected:
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  static void SetUpTestCase() {
1312a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::InitializeSSL();
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Ensure the RNG is inited.
1332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::InitRandom(NULL, 0);
134459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org
135459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  }
136459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  static void TearDownTestCase() {
1372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::CleanupSSL();
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnPortComplete(cricket::Port* port) {
141459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org    ASSERT_FALSE(done_);
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    done_ = true;
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    error_ = false;
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void OnPortError(cricket::Port* port) {
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    done_ = true;
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    error_ = true;
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void SetKeepaliveDelay(int delay) {
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    stun_keepalive_delay_ = delay;
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private:
1542a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_;
1552a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::VirtualSocketServer> ss_;
1562a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SocketServerScope ss_scope_;
1572a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Network network_;
1582a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::BasicPacketSocketFactory socket_factory_;
1592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::UDPPort> stun_port_;
1602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::TestStunServer> stun_server_1_;
1612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<cricket::TestStunServer> stun_server_2_;
1622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::AsyncPacketSocket> socket_;
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool done_;
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool error_;
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int stun_keepalive_delay_;
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Test that we can create a STUN port
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(StunPortTest, TestBasic) {
170459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  CreateStunPort(kStunAddr1);
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ("stun", port()->Type());
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(0U, port()->Candidates().size());
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Test that we can get an address from a STUN server.
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(StunPortTest, TestPrepareAddress) {
177459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  CreateStunPort(kStunAddr1);
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareAddress();
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_EQ(1U, port()->Candidates().size());
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO: Add IPv6 tests here, once either physicalsocketserver supports
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // IPv6, or this test is changed to use VirtualSocketServer.
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Test that we fail properly if we can't get an address.
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(StunPortTest, TestPrepareAddressFail) {
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateStunPort(kBadAddr);
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareAddress();
1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(error());
1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(0U, port()->Candidates().size());
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Test that we can get an address from a STUN server specified by a hostname.
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(StunPortTest, TestPrepareAddressHostname) {
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateStunPort(kStunHostnameAddr);
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareAddress();
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_EQ(1U, port()->Candidates().size());
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
203afaf4d10603cf012a13d43a62fbc43c0757ec3b9buildbot@webrtc.org  EXPECT_EQ(kStunCandidatePriority, port()->Candidates()[0].priority());
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Test that we handle hostname lookup failures properly.
2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(StunPortTest, TestPrepareAddressHostnameFail) {
2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateStunPort(kBadHostnameAddr);
2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareAddress();
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(error());
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_EQ(0U, port()->Candidates().size());
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This test verifies keepalive response messages don't result in
2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// additional candidate generation.
2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTEST_F(StunPortTest, TestKeepAliveResponse) {
2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetKeepaliveDelay(500);  // 500ms of keepalive delay.
2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateStunPort(kStunHostnameAddr);
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  PrepareAddress();
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_EQ(1U, port()->Candidates().size());
2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Waiting for 1 seond, which will allow us to process
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // response for keepalive binding request. 500 ms is the keepalive delay.
2262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Thread::Current()->ProcessMessages(1000);
2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT_EQ(1U, port()->Candidates().size());
2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
230a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Test that a local candidate can be generated using a shared socket.
231a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(StunPortTest, TestSharedSocketPrepareAddress) {
232459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  CreateSharedStunPort(kStunAddr1);
233a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareAddress();
234a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
235a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  ASSERT_EQ(1U, port()->Candidates().size());
236a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
237a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
238a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
239a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Test that we still a get a local candidate with invalid stun server hostname.
240a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// Also verifing that UDPPort can receive packets when stun address can't be
241a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org// resolved.
242a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgTEST_F(StunPortTest, TestSharedSocketPrepareAddressInvalidHostname) {
243a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  CreateSharedStunPort(kBadHostnameAddr);
244a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  PrepareAddress();
245a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
246a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  ASSERT_EQ(1U, port()->Candidates().size());
247a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  EXPECT_TRUE(kLocalAddr.EqualIPs(port()->Candidates()[0].address()));
248a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
249a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Send data to port after it's ready. This is to make sure, UDP port can
250a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // handle data with unresolved stun server address.
251a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  std::string data = "some random data, sending to cricket::Port.";
252a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  SendData(data.c_str(), data.length());
253a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // No crash is success.
254a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
255459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org
256459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org// Test that candidates can be allocated for multiple STUN servers.
257459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.orgTEST_F(StunPortTest, TestMultipleGoodStunServers) {
258459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  ServerAddresses stun_servers;
259459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  stun_servers.insert(kStunAddr1);
260459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  stun_servers.insert(kStunAddr2);
261459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  CreateStunPort(stun_servers);
262459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  EXPECT_EQ("stun", port()->Type());
263459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  PrepareAddress();
264459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
265459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  EXPECT_EQ(2U, port()->Candidates().size());
266459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org}
267459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org
268459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org// Test that candidates can be allocated for multiple STUN servers, one of which
269459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org// is not reachable.
270459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.orgTEST_F(StunPortTest, TestMultipleStunServersWithBadServer) {
271459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  ServerAddresses stun_servers;
272459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  stun_servers.insert(kStunAddr1);
273459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  stun_servers.insert(kBadAddr);
274459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  CreateStunPort(stun_servers);
275459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  EXPECT_EQ("stun", port()->Type());
276459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  PrepareAddress();
277459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  EXPECT_TRUE_WAIT(done(), kTimeoutMs);
278459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org  EXPECT_EQ(1U, port()->Candidates().size());
279459f356846e5dc1e9b2c5182568660f5eaacfe3ebuildbot@webrtc.org}
280