OLD | NEW |
| (Empty) |
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 <stdio.h> | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 | |
15 #include <iostream> | |
16 #include <map> | |
17 #include <memory> | |
18 | |
19 #include "webrtc/base/checks.h" | |
20 #include "webrtc/base/flags.h" | |
21 #include "webrtc/base/helpers.h" | |
22 #include "webrtc/base/nethelpers.h" | |
23 #include "webrtc/base/network.h" | |
24 #include "webrtc/base/logging.h" | |
25 #include "webrtc/base/ssladapter.h" | |
26 #include "webrtc/base/stringutils.h" | |
27 #include "webrtc/base/thread.h" | |
28 #include "webrtc/base/timeutils.h" | |
29 #include "webrtc/p2p/base/basicpacketsocketfactory.h" | |
30 #include "webrtc/p2p/stunprober/stunprober.h" | |
31 | |
32 using stunprober::StunProber; | |
33 using stunprober::AsyncCallback; | |
34 | |
35 DEFINE_bool(help, false, "Prints this message"); | |
36 DEFINE_int(interval, 10, "Interval of consecutive stun pings in milliseconds"); | |
37 DEFINE_bool(shared_socket, false, "Share socket mode for different remote IPs"); | |
38 DEFINE_int(pings_per_ip, | |
39 10, | |
40 "Number of consecutive stun pings to send for each IP"); | |
41 DEFINE_int(timeout, | |
42 1000, | |
43 "Milliseconds of wait after the last ping sent before exiting"); | |
44 DEFINE_string( | |
45 servers, | |
46 "stun.l.google.com:19302,stun1.l.google.com:19302,stun2.l.google.com:19302", | |
47 "Comma separated STUN server addresses with ports"); | |
48 | |
49 namespace { | |
50 | |
51 const char* PrintNatType(stunprober::NatType type) { | |
52 switch (type) { | |
53 case stunprober::NATTYPE_NONE: | |
54 return "Not behind a NAT"; | |
55 case stunprober::NATTYPE_UNKNOWN: | |
56 return "Unknown NAT type"; | |
57 case stunprober::NATTYPE_SYMMETRIC: | |
58 return "Symmetric NAT"; | |
59 case stunprober::NATTYPE_NON_SYMMETRIC: | |
60 return "Non-Symmetric NAT"; | |
61 default: | |
62 return "Invalid"; | |
63 } | |
64 } | |
65 | |
66 void PrintStats(StunProber* prober) { | |
67 StunProber::Stats stats; | |
68 if (!prober->GetStats(&stats)) { | |
69 LOG(LS_WARNING) << "Results are inconclusive."; | |
70 return; | |
71 } | |
72 | |
73 LOG(LS_INFO) << "Shared Socket Mode: " << stats.shared_socket_mode; | |
74 LOG(LS_INFO) << "Requests sent: " << stats.num_request_sent; | |
75 LOG(LS_INFO) << "Responses received: " << stats.num_response_received; | |
76 LOG(LS_INFO) << "Target interval (ns): " << stats.target_request_interval_ns; | |
77 LOG(LS_INFO) << "Actual interval (ns): " << stats.actual_request_interval_ns; | |
78 LOG(LS_INFO) << "NAT Type: " << PrintNatType(stats.nat_type); | |
79 LOG(LS_INFO) << "Host IP: " << stats.host_ip; | |
80 LOG(LS_INFO) << "Server-reflexive ips: "; | |
81 for (auto& ip : stats.srflx_addrs) { | |
82 LOG(LS_INFO) << "\t" << ip; | |
83 } | |
84 | |
85 LOG(LS_INFO) << "Success Precent: " << stats.success_percent; | |
86 LOG(LS_INFO) << "Response Latency:" << stats.average_rtt_ms; | |
87 } | |
88 | |
89 void StopTrial(rtc::Thread* thread, StunProber* prober, int result) { | |
90 thread->Quit(); | |
91 if (prober) { | |
92 LOG(LS_INFO) << "Result: " << result; | |
93 if (result == StunProber::SUCCESS) { | |
94 PrintStats(prober); | |
95 } | |
96 } | |
97 } | |
98 | |
99 } // namespace | |
100 | |
101 int main(int argc, char** argv) { | |
102 rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true); | |
103 if (FLAG_help) { | |
104 rtc::FlagList::Print(nullptr, false); | |
105 return 0; | |
106 } | |
107 | |
108 std::vector<rtc::SocketAddress> server_addresses; | |
109 std::istringstream servers(FLAG_servers); | |
110 std::string server; | |
111 while (getline(servers, server, ',')) { | |
112 rtc::SocketAddress addr; | |
113 if (!addr.FromString(server)) { | |
114 LOG(LS_ERROR) << "Parsing " << server << " failed."; | |
115 return -1; | |
116 } | |
117 server_addresses.push_back(addr); | |
118 } | |
119 | |
120 rtc::InitializeSSL(); | |
121 rtc::InitRandom(rtc::Time32()); | |
122 rtc::Thread* thread = rtc::ThreadManager::Instance()->WrapCurrentThread(); | |
123 std::unique_ptr<rtc::BasicPacketSocketFactory> socket_factory( | |
124 new rtc::BasicPacketSocketFactory()); | |
125 std::unique_ptr<rtc::BasicNetworkManager> network_manager( | |
126 new rtc::BasicNetworkManager()); | |
127 rtc::NetworkManager::NetworkList networks; | |
128 network_manager->GetNetworks(&networks); | |
129 StunProber* prober = | |
130 new StunProber(socket_factory.get(), rtc::Thread::Current(), networks); | |
131 auto finish_callback = [thread](StunProber* prober, int result) { | |
132 StopTrial(thread, prober, result); | |
133 }; | |
134 prober->Start(server_addresses, FLAG_shared_socket, FLAG_interval, | |
135 FLAG_pings_per_ip, FLAG_timeout, | |
136 AsyncCallback(finish_callback)); | |
137 thread->Run(); | |
138 delete prober; | |
139 return 0; | |
140 } | |
OLD | NEW |