xref: /aosp_15_r20/external/webrtc/examples/stunprober/main.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker 
11*d9f75844SAndroid Build Coastguard Worker #include <memory>
12*d9f75844SAndroid Build Coastguard Worker #include <set>
13*d9f75844SAndroid Build Coastguard Worker #include <sstream>
14*d9f75844SAndroid Build Coastguard Worker #include <string>
15*d9f75844SAndroid Build Coastguard Worker #include <vector>
16*d9f75844SAndroid Build Coastguard Worker 
17*d9f75844SAndroid Build Coastguard Worker #include "absl/flags/flag.h"
18*d9f75844SAndroid Build Coastguard Worker #include "absl/flags/parse.h"
19*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/basic_packet_socket_factory.h"
20*d9f75844SAndroid Build Coastguard Worker #include "p2p/stunprober/stun_prober.h"
21*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/helpers.h"
22*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
23*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/network.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/physical_socket_server.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/socket_address.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/ssl_adapter.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
29*d9f75844SAndroid Build Coastguard Worker #include "test/scoped_key_value_config.h"
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker using stunprober::AsyncCallback;
32*d9f75844SAndroid Build Coastguard Worker using stunprober::StunProber;
33*d9f75844SAndroid Build Coastguard Worker 
34*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(int,
35*d9f75844SAndroid Build Coastguard Worker           interval,
36*d9f75844SAndroid Build Coastguard Worker           10,
37*d9f75844SAndroid Build Coastguard Worker           "Interval of consecutive stun pings in milliseconds");
38*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(bool,
39*d9f75844SAndroid Build Coastguard Worker           shared_socket,
40*d9f75844SAndroid Build Coastguard Worker           false,
41*d9f75844SAndroid Build Coastguard Worker           "Share socket mode for different remote IPs");
42*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(int,
43*d9f75844SAndroid Build Coastguard Worker           pings_per_ip,
44*d9f75844SAndroid Build Coastguard Worker           10,
45*d9f75844SAndroid Build Coastguard Worker           "Number of consecutive stun pings to send for each IP");
46*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(int,
47*d9f75844SAndroid Build Coastguard Worker           timeout,
48*d9f75844SAndroid Build Coastguard Worker           1000,
49*d9f75844SAndroid Build Coastguard Worker           "Milliseconds of wait after the last ping sent before exiting");
50*d9f75844SAndroid Build Coastguard Worker ABSL_FLAG(
51*d9f75844SAndroid Build Coastguard Worker     std::string,
52*d9f75844SAndroid Build Coastguard Worker     servers,
53*d9f75844SAndroid Build Coastguard Worker     "stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302",
54*d9f75844SAndroid Build Coastguard Worker     "Comma separated STUN server addresses with ports");
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker namespace {
57*d9f75844SAndroid Build Coastguard Worker 
PrintNatType(stunprober::NatType type)58*d9f75844SAndroid Build Coastguard Worker const char* PrintNatType(stunprober::NatType type) {
59*d9f75844SAndroid Build Coastguard Worker   switch (type) {
60*d9f75844SAndroid Build Coastguard Worker     case stunprober::NATTYPE_NONE:
61*d9f75844SAndroid Build Coastguard Worker       return "Not behind a NAT";
62*d9f75844SAndroid Build Coastguard Worker     case stunprober::NATTYPE_UNKNOWN:
63*d9f75844SAndroid Build Coastguard Worker       return "Unknown NAT type";
64*d9f75844SAndroid Build Coastguard Worker     case stunprober::NATTYPE_SYMMETRIC:
65*d9f75844SAndroid Build Coastguard Worker       return "Symmetric NAT";
66*d9f75844SAndroid Build Coastguard Worker     case stunprober::NATTYPE_NON_SYMMETRIC:
67*d9f75844SAndroid Build Coastguard Worker       return "Non-Symmetric NAT";
68*d9f75844SAndroid Build Coastguard Worker     default:
69*d9f75844SAndroid Build Coastguard Worker       return "Invalid";
70*d9f75844SAndroid Build Coastguard Worker   }
71*d9f75844SAndroid Build Coastguard Worker }
72*d9f75844SAndroid Build Coastguard Worker 
PrintStats(StunProber * prober)73*d9f75844SAndroid Build Coastguard Worker void PrintStats(StunProber* prober) {
74*d9f75844SAndroid Build Coastguard Worker   StunProber::Stats stats;
75*d9f75844SAndroid Build Coastguard Worker   if (!prober->GetStats(&stats)) {
76*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_WARNING) << "Results are inconclusive.";
77*d9f75844SAndroid Build Coastguard Worker     return;
78*d9f75844SAndroid Build Coastguard Worker   }
79*d9f75844SAndroid Build Coastguard Worker 
80*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Shared Socket Mode: " << stats.shared_socket_mode;
81*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Requests sent: " << stats.num_request_sent;
82*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Responses received: " << stats.num_response_received;
83*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Target interval (ns): "
84*d9f75844SAndroid Build Coastguard Worker                    << stats.target_request_interval_ns;
85*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Actual interval (ns): "
86*d9f75844SAndroid Build Coastguard Worker                    << stats.actual_request_interval_ns;
87*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "NAT Type: " << PrintNatType(stats.nat_type);
88*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Host IP: " << stats.host_ip;
89*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Server-reflexive ips: ";
90*d9f75844SAndroid Build Coastguard Worker   for (auto& ip : stats.srflx_addrs) {
91*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "\t" << ip;
92*d9f75844SAndroid Build Coastguard Worker   }
93*d9f75844SAndroid Build Coastguard Worker 
94*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Success Precent: " << stats.success_percent;
95*d9f75844SAndroid Build Coastguard Worker   RTC_LOG(LS_INFO) << "Response Latency:" << stats.average_rtt_ms;
96*d9f75844SAndroid Build Coastguard Worker }
97*d9f75844SAndroid Build Coastguard Worker 
StopTrial(rtc::Thread * thread,StunProber * prober,int result)98*d9f75844SAndroid Build Coastguard Worker void StopTrial(rtc::Thread* thread, StunProber* prober, int result) {
99*d9f75844SAndroid Build Coastguard Worker   thread->Quit();
100*d9f75844SAndroid Build Coastguard Worker   if (prober) {
101*d9f75844SAndroid Build Coastguard Worker     RTC_LOG(LS_INFO) << "Result: " << result;
102*d9f75844SAndroid Build Coastguard Worker     if (result == StunProber::SUCCESS) {
103*d9f75844SAndroid Build Coastguard Worker       PrintStats(prober);
104*d9f75844SAndroid Build Coastguard Worker     }
105*d9f75844SAndroid Build Coastguard Worker   }
106*d9f75844SAndroid Build Coastguard Worker }
107*d9f75844SAndroid Build Coastguard Worker 
108*d9f75844SAndroid Build Coastguard Worker }  // namespace
109*d9f75844SAndroid Build Coastguard Worker 
main(int argc,char * argv[])110*d9f75844SAndroid Build Coastguard Worker int main(int argc, char* argv[]) {
111*d9f75844SAndroid Build Coastguard Worker   absl::ParseCommandLine(argc, argv);
112*d9f75844SAndroid Build Coastguard Worker 
113*d9f75844SAndroid Build Coastguard Worker   std::vector<rtc::SocketAddress> server_addresses;
114*d9f75844SAndroid Build Coastguard Worker   std::istringstream servers(absl::GetFlag(FLAGS_servers));
115*d9f75844SAndroid Build Coastguard Worker   std::string server;
116*d9f75844SAndroid Build Coastguard Worker   while (getline(servers, server, ',')) {
117*d9f75844SAndroid Build Coastguard Worker     rtc::SocketAddress addr;
118*d9f75844SAndroid Build Coastguard Worker     if (!addr.FromString(server)) {
119*d9f75844SAndroid Build Coastguard Worker       RTC_LOG(LS_ERROR) << "Parsing " << server << " failed.";
120*d9f75844SAndroid Build Coastguard Worker       return -1;
121*d9f75844SAndroid Build Coastguard Worker     }
122*d9f75844SAndroid Build Coastguard Worker     server_addresses.push_back(addr);
123*d9f75844SAndroid Build Coastguard Worker   }
124*d9f75844SAndroid Build Coastguard Worker 
125*d9f75844SAndroid Build Coastguard Worker   rtc::InitializeSSL();
126*d9f75844SAndroid Build Coastguard Worker   rtc::InitRandom(rtc::Time32());
127*d9f75844SAndroid Build Coastguard Worker   webrtc::test::ScopedKeyValueConfig field_trials;
128*d9f75844SAndroid Build Coastguard Worker   rtc::PhysicalSocketServer socket_server;
129*d9f75844SAndroid Build Coastguard Worker   rtc::AutoSocketServerThread thread(&socket_server);
130*d9f75844SAndroid Build Coastguard Worker   auto socket_factory =
131*d9f75844SAndroid Build Coastguard Worker       std::make_unique<rtc::BasicPacketSocketFactory>(&socket_server);
132*d9f75844SAndroid Build Coastguard Worker   std::unique_ptr<rtc::BasicNetworkManager> network_manager(
133*d9f75844SAndroid Build Coastguard Worker       new rtc::BasicNetworkManager(&socket_server, &field_trials));
134*d9f75844SAndroid Build Coastguard Worker   std::vector<const rtc::Network*> networks = network_manager->GetNetworks();
135*d9f75844SAndroid Build Coastguard Worker   auto prober = std::make_unique<StunProber>(socket_factory.get(),
136*d9f75844SAndroid Build Coastguard Worker                                              rtc::Thread::Current(), networks);
137*d9f75844SAndroid Build Coastguard Worker   auto finish_callback = [&thread](StunProber* prober, int result) {
138*d9f75844SAndroid Build Coastguard Worker     StopTrial(&thread, prober, result);
139*d9f75844SAndroid Build Coastguard Worker   };
140*d9f75844SAndroid Build Coastguard Worker   prober->Start(server_addresses, absl::GetFlag(FLAGS_shared_socket),
141*d9f75844SAndroid Build Coastguard Worker                 absl::GetFlag(FLAGS_interval),
142*d9f75844SAndroid Build Coastguard Worker                 absl::GetFlag(FLAGS_pings_per_ip), absl::GetFlag(FLAGS_timeout),
143*d9f75844SAndroid Build Coastguard Worker                 AsyncCallback(finish_callback));
144*d9f75844SAndroid Build Coastguard Worker   thread.Run();
145*d9f75844SAndroid Build Coastguard Worker   return 0;
146*d9f75844SAndroid Build Coastguard Worker }
147