1 /* 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/base/asyncresolverinterface.h" 12 #include "webrtc/base/basictypes.h" 13 #include "webrtc/base/bind.h" 14 #include "webrtc/base/checks.h" 15 #include "webrtc/base/gunit.h" 16 #include "webrtc/base/physicalsocketserver.h" 17 #include "webrtc/base/scoped_ptr.h" 18 #include "webrtc/base/ssladapter.h" 19 #include "webrtc/base/virtualsocketserver.h" 20 #include "webrtc/p2p/base/basicpacketsocketfactory.h" 21 #include "webrtc/p2p/base/teststunserver.h" 22 #include "webrtc/p2p/stunprober/stunprober.h" 23 24 using stunprober::StunProber; 25 using stunprober::AsyncCallback; 26 27 namespace stunprober { 28 29 namespace { 30 31 const rtc::SocketAddress kLocalAddr("192.168.0.1", 0); 32 const rtc::SocketAddress kStunAddr1("1.1.1.1", 3478); 33 const rtc::SocketAddress kStunAddr2("1.1.1.2", 3478); 34 const rtc::SocketAddress kFailedStunAddr("1.1.1.3", 3478); 35 const rtc::SocketAddress kStunMappedAddr("77.77.77.77", 0); 36 37 } // namespace 38 39 class StunProberTest : public testing::Test { 40 public: 41 StunProberTest() 42 : main_(rtc::Thread::Current()), 43 pss_(new rtc::PhysicalSocketServer), 44 ss_(new rtc::VirtualSocketServer(pss_.get())), 45 ss_scope_(ss_.get()), 46 result_(StunProber::SUCCESS), 47 stun_server_1_(cricket::TestStunServer::Create(rtc::Thread::Current(), 48 kStunAddr1)), 49 stun_server_2_(cricket::TestStunServer::Create(rtc::Thread::Current(), 50 kStunAddr2)) { 51 stun_server_1_->set_fake_stun_addr(kStunMappedAddr); 52 stun_server_2_->set_fake_stun_addr(kStunMappedAddr); 53 rtc::InitializeSSL(); 54 } 55 56 void set_expected_result(int result) { result_ = result; } 57 58 void StartProbing(rtc::PacketSocketFactory* socket_factory, 59 const std::vector<rtc::SocketAddress>& addrs, 60 const rtc::NetworkManager::NetworkList& networks, 61 bool shared_socket, 62 uint16_t interval, 63 uint16_t pings_per_ip) { 64 prober.reset( 65 new StunProber(socket_factory, rtc::Thread::Current(), networks)); 66 prober->Start(addrs, shared_socket, interval, pings_per_ip, 67 100 /* timeout_ms */, [this](StunProber* prober, int result) { 68 this->StopCallback(prober, result); 69 }); 70 } 71 72 void RunProber(bool shared_mode) { 73 const int pings_per_ip = 3; 74 std::vector<rtc::SocketAddress> addrs; 75 addrs.push_back(kStunAddr1); 76 addrs.push_back(kStunAddr2); 77 // Add a non-existing server. This shouldn't pollute the result. 78 addrs.push_back(kFailedStunAddr); 79 80 rtc::Network ipv4_network1("test_eth0", "Test Network Adapter 1", 81 rtc::IPAddress(0x12345600U), 24); 82 ipv4_network1.AddIP(rtc::IPAddress(0x12345678)); 83 rtc::NetworkManager::NetworkList networks; 84 networks.push_back(&ipv4_network1); 85 86 rtc::scoped_ptr<rtc::BasicPacketSocketFactory> socket_factory( 87 new rtc::BasicPacketSocketFactory()); 88 89 // Set up the expected results for verification. 90 std::set<std::string> srflx_addresses; 91 srflx_addresses.insert(kStunMappedAddr.ToString()); 92 const uint32_t total_pings_tried = 93 static_cast<uint32_t>(pings_per_ip * addrs.size()); 94 95 // The reported total_pings should not count for pings sent to the 96 // kFailedStunAddr. 97 const uint32_t total_pings_reported = total_pings_tried - pings_per_ip; 98 99 StartProbing(socket_factory.get(), addrs, networks, shared_mode, 3, 100 pings_per_ip); 101 102 WAIT(stopped_, 1000); 103 104 StunProber::Stats stats; 105 EXPECT_TRUE(prober->GetStats(&stats)); 106 EXPECT_EQ(stats.success_percent, 100); 107 EXPECT_TRUE(stats.nat_type > stunprober::NATTYPE_NONE); 108 EXPECT_EQ(stats.srflx_addrs, srflx_addresses); 109 EXPECT_EQ(static_cast<uint32_t>(stats.num_request_sent), 110 total_pings_reported); 111 EXPECT_EQ(static_cast<uint32_t>(stats.num_response_received), 112 total_pings_reported); 113 } 114 115 private: 116 void StopCallback(StunProber* prober, int result) { 117 EXPECT_EQ(result, result_); 118 stopped_ = true; 119 } 120 121 rtc::Thread* main_; 122 rtc::scoped_ptr<rtc::PhysicalSocketServer> pss_; 123 rtc::scoped_ptr<rtc::VirtualSocketServer> ss_; 124 rtc::SocketServerScope ss_scope_; 125 rtc::scoped_ptr<StunProber> prober; 126 int result_ = 0; 127 bool stopped_ = false; 128 rtc::scoped_ptr<cricket::TestStunServer> stun_server_1_; 129 rtc::scoped_ptr<cricket::TestStunServer> stun_server_2_; 130 }; 131 132 TEST_F(StunProberTest, NonSharedMode) { 133 RunProber(false); 134 } 135 136 TEST_F(StunProberTest, SharedMode) { 137 RunProber(true); 138 } 139 140 } // namespace stunprober 141