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