Home | History | Annotate | Download | only in stunprober
      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