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:
StunProberTest()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
set_expected_result(int result)56 void set_expected_result(int result) { result_ = result; }
57
StartProbing(rtc::PacketSocketFactory * socket_factory,const std::vector<rtc::SocketAddress> & addrs,const rtc::NetworkManager::NetworkList & networks,bool shared_socket,uint16_t interval,uint16_t pings_per_ip)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
RunProber(bool shared_mode)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:
StopCallback(StunProber * prober,int result)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
TEST_F(StunProberTest,NonSharedMode)132 TEST_F(StunProberTest, NonSharedMode) {
133 RunProber(false);
134 }
135
TEST_F(StunProberTest,SharedMode)136 TEST_F(StunProberTest, SharedMode) {
137 RunProber(true);
138 }
139
140 } // namespace stunprober
141