/* * Copyright 2015 The WebRTC Project Authors. All rights reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include #include "webrtc/base/asyncresolverinterface.h" #include "webrtc/base/basictypes.h" #include "webrtc/base/bind.h" #include "webrtc/base/checks.h" #include "webrtc/base/gunit.h" #include "webrtc/base/physicalsocketserver.h" #include "webrtc/base/ssladapter.h" #include "webrtc/base/virtualsocketserver.h" #include "webrtc/p2p/base/basicpacketsocketfactory.h" #include "webrtc/p2p/base/teststunserver.h" #include "webrtc/p2p/stunprober/stunprober.h" using stunprober::StunProber; using stunprober::AsyncCallback; namespace stunprober { namespace { const rtc::SocketAddress kLocalAddr("192.168.0.1", 0); const rtc::SocketAddress kStunAddr1("1.1.1.1", 3478); const rtc::SocketAddress kStunAddr2("1.1.1.2", 3478); const rtc::SocketAddress kFailedStunAddr("1.1.1.3", 3478); const rtc::SocketAddress kStunMappedAddr("77.77.77.77", 0); } // namespace class StunProberTest : public testing::Test { public: StunProberTest() : main_(rtc::Thread::Current()), pss_(new rtc::PhysicalSocketServer), ss_(new rtc::VirtualSocketServer(pss_.get())), ss_scope_(ss_.get()), result_(StunProber::SUCCESS), stun_server_1_(cricket::TestStunServer::Create(rtc::Thread::Current(), kStunAddr1)), stun_server_2_(cricket::TestStunServer::Create(rtc::Thread::Current(), kStunAddr2)) { stun_server_1_->set_fake_stun_addr(kStunMappedAddr); stun_server_2_->set_fake_stun_addr(kStunMappedAddr); rtc::InitializeSSL(); } void set_expected_result(int result) { result_ = result; } void StartProbing(rtc::PacketSocketFactory* socket_factory, const std::vector& addrs, const rtc::NetworkManager::NetworkList& networks, bool shared_socket, uint16_t interval, uint16_t pings_per_ip) { prober.reset( new StunProber(socket_factory, rtc::Thread::Current(), networks)); prober->Start(addrs, shared_socket, interval, pings_per_ip, 100 /* timeout_ms */, [this](StunProber* prober, int result) { this->StopCallback(prober, result); }); } void RunProber(bool shared_mode) { const int pings_per_ip = 3; std::vector addrs; addrs.push_back(kStunAddr1); addrs.push_back(kStunAddr2); // Add a non-existing server. This shouldn't pollute the result. addrs.push_back(kFailedStunAddr); rtc::Network ipv4_network1("test_eth0", "Test Network Adapter 1", rtc::IPAddress(0x12345600U), 24); ipv4_network1.AddIP(rtc::IPAddress(0x12345678)); rtc::NetworkManager::NetworkList networks; networks.push_back(&ipv4_network1); std::unique_ptr socket_factory( new rtc::BasicPacketSocketFactory()); // Set up the expected results for verification. std::set srflx_addresses; srflx_addresses.insert(kStunMappedAddr.ToString()); const uint32_t total_pings_tried = static_cast(pings_per_ip * addrs.size()); // The reported total_pings should not count for pings sent to the // kFailedStunAddr. const uint32_t total_pings_reported = total_pings_tried - pings_per_ip; StartProbing(socket_factory.get(), addrs, networks, shared_mode, 3, pings_per_ip); WAIT(stopped_, 1000); StunProber::Stats stats; EXPECT_TRUE(prober->GetStats(&stats)); EXPECT_EQ(stats.success_percent, 100); EXPECT_TRUE(stats.nat_type > stunprober::NATTYPE_NONE); EXPECT_EQ(stats.srflx_addrs, srflx_addresses); EXPECT_EQ(static_cast(stats.num_request_sent), total_pings_reported); EXPECT_EQ(static_cast(stats.num_response_received), total_pings_reported); } private: void StopCallback(StunProber* prober, int result) { EXPECT_EQ(result, result_); stopped_ = true; } rtc::Thread* main_; std::unique_ptr pss_; std::unique_ptr ss_; rtc::SocketServerScope ss_scope_; std::unique_ptr prober; int result_ = 0; bool stopped_ = false; std::unique_ptr stun_server_1_; std::unique_ptr stun_server_2_; }; TEST_F(StunProberTest, NonSharedMode) { RunProber(false); } TEST_F(StunProberTest, SharedMode) { RunProber(true); } } // namespace stunprober