| Index: webrtc/p2p/stunprober/stunprober.cc
|
| diff --git a/webrtc/p2p/stunprober/stunprober.cc b/webrtc/p2p/stunprober/stunprober.cc
|
| index ffa66fade15fb402e951327775fd2bd4c034d5a3..8efe069b0b52f1841e59978a24023d087415e881 100644
|
| --- a/webrtc/p2p/stunprober/stunprober.cc
|
| +++ b/webrtc/p2p/stunprober/stunprober.cc
|
| @@ -24,11 +24,15 @@ namespace stunprober {
|
|
|
| namespace {
|
|
|
| -void IncrementCounterByAddress(std::map<rtc::IPAddress, int>* counter_per_ip,
|
| - const rtc::IPAddress& ip) {
|
| +template <typename T>
|
| +void IncrementCounterByAddress(std::map<T, int>* counter_per_ip, const T& ip) {
|
| counter_per_ip->insert(std::make_pair(ip, 0)).first->second++;
|
| }
|
|
|
| +bool behind_nat(NatType nat_type) {
|
| + return nat_type > stunprober::NATTYPE_NONE;
|
| +}
|
| +
|
| } // namespace
|
|
|
| // A requester tracks the requests and responses from a single socket to many
|
| @@ -418,7 +422,7 @@ void StunProber::MaybeScheduleStunRequests() {
|
| rtc::Bind(&StunProber::MaybeScheduleStunRequests, this), 1 /* ms */);
|
| }
|
|
|
| -bool StunProber::GetStats(StunProber::Stats* prob_stats) {
|
| +bool StunProber::GetStats(StunProber::Stats* prob_stats) const {
|
| // No need to be on the same thread.
|
| if (!prob_stats) {
|
| return false;
|
| @@ -427,25 +431,26 @@ bool StunProber::GetStats(StunProber::Stats* prob_stats) {
|
| StunProber::Stats stats;
|
|
|
| int rtt_sum = 0;
|
| - bool behind_nat_set = false;
|
| int64 first_sent_time = 0;
|
| int64 last_sent_time = 0;
|
| + NatType nat_type = NATTYPE_INVALID;
|
|
|
| // Track of how many srflx IP that we have seen.
|
| std::set<rtc::IPAddress> srflx_ips;
|
|
|
| // If we're not receiving any response on a given IP, all requests sent to
|
| // that IP should be ignored as this could just be an DNS error.
|
| - std::map<rtc::IPAddress, int> num_response_per_ip;
|
| - std::map<rtc::IPAddress, int> num_request_per_ip;
|
| + std::map<rtc::IPAddress, int> num_response_per_server;
|
| + std::map<rtc::IPAddress, int> num_request_per_server;
|
|
|
| for (auto* requester : requesters_) {
|
| + std::map<rtc::SocketAddress, int> num_response_per_srflx_addr;
|
| for (auto request : requester->requests()) {
|
| if (request->sent_time_ms <= 0) {
|
| continue;
|
| }
|
|
|
| - IncrementCounterByAddress(&num_request_per_ip, request->server_addr);
|
| + IncrementCounterByAddress(&num_request_per_server, request->server_addr);
|
|
|
| if (!first_sent_time) {
|
| first_sent_time = request->sent_time_ms;
|
| @@ -456,19 +461,26 @@ bool StunProber::GetStats(StunProber::Stats* prob_stats) {
|
| continue;
|
| }
|
|
|
| - IncrementCounterByAddress(&num_response_per_ip, request->server_addr);
|
| + IncrementCounterByAddress(&num_response_per_server, request->server_addr);
|
| + IncrementCounterByAddress(&num_response_per_srflx_addr,
|
| + request->srflx_addr);
|
|
|
| rtt_sum += request->rtt();
|
| - if (!behind_nat_set) {
|
| - stats.behind_nat = request->behind_nat;
|
| - behind_nat_set = true;
|
| - } else if (stats.behind_nat != request->behind_nat) {
|
| + if (nat_type == NATTYPE_INVALID) {
|
| + nat_type = request->behind_nat ? NATTYPE_UNKNOWN : NATTYPE_NONE;
|
| + } else if (behind_nat(nat_type) != request->behind_nat) {
|
| // Detect the inconsistency in NAT presence.
|
| return false;
|
| }
|
| stats.srflx_addrs.insert(request->srflx_addr.ToString());
|
| srflx_ips.insert(request->srflx_addr.ipaddr());
|
| }
|
| +
|
| + // If we're using shared mode and seeing >1 srflx addresses for a single
|
| + // requester, it's symmetric NAT.
|
| + if (shared_socket_mode_ && num_response_per_srflx_addr.size() > 1) {
|
| + nat_type = NATTYPE_SYMMETRIC;
|
| + }
|
| }
|
|
|
| // We're probably not behind a regular NAT. We have more than 1 distinct
|
| @@ -481,11 +493,11 @@ bool StunProber::GetStats(StunProber::Stats* prob_stats) {
|
| int num_received = 0;
|
| int num_server_ip_with_response = 0;
|
|
|
| - for (const auto& kv : num_response_per_ip) {
|
| + for (const auto& kv : num_response_per_server) {
|
| DCHECK_GT(kv.second, 0);
|
| num_server_ip_with_response++;
|
| num_received += kv.second;
|
| - num_sent += num_request_per_ip[kv.first];
|
| + num_sent += num_request_per_server[kv.first];
|
| }
|
|
|
| // Not receiving any response, the trial is inconclusive.
|
| @@ -493,17 +505,21 @@ bool StunProber::GetStats(StunProber::Stats* prob_stats) {
|
| return false;
|
| }
|
|
|
| + stats.nat_type = nat_type;
|
| +
|
| // Shared mode is only true if we use the shared socket and there are more
|
| // than 1 responding servers.
|
| stats.shared_socket_mode =
|
| shared_socket_mode_ && (num_server_ip_with_response > 1);
|
|
|
| + if (stats.shared_socket_mode && nat_type == NATTYPE_UNKNOWN) {
|
| + stats.nat_type = NATTYPE_NON_SYMMETRIC;
|
| + }
|
| +
|
| stats.host_ip = local_addr_.ToString();
|
| stats.num_request_sent = num_sent;
|
| stats.num_response_received = num_received;
|
| stats.target_request_interval_ns = interval_ms_ * 1000;
|
| - stats.symmetric_nat =
|
| - stats.srflx_addrs.size() > static_cast<size_t>(GetTotalServerSockets());
|
|
|
| if (num_sent) {
|
| stats.success_percent = static_cast<int>(100 * num_received / num_sent);
|
|
|