From 5ecf16c072cef53ecb270794577c39a66dcbac63 Mon Sep 17 00:00:00 2001 From: zhihuang Date: Wed, 1 Jun 2016 17:09:15 -0700 Subject: [PATCH] Add Stats to Stun ping. Add sent_ping_requests, recv_ping_responses to ConnectionInfo. recv_ping_responses_ will be incremented when OnConnectionRequestResponse() is called. ent_ping_requests_ will be incremented when OnConnectionRequestSent() is called. BUG=webrtc:5695 Review-Url: https://codereview.webrtc.org/1940493002 Cr-Commit-Position: refs/heads/master@{#13001} --- webrtc/api/statscollector.cc | 19 ++++++++---- webrtc/api/statstypes.cc | 12 +++++++ webrtc/api/statstypes.h | 5 +++ webrtc/p2p/base/p2ptransportchannel.cc | 12 ++----- webrtc/p2p/base/port.cc | 43 ++++++++++---------------- webrtc/p2p/base/port.h | 14 +++------ webrtc/p2p/base/port_unittest.cc | 33 +++++++++++++++++--- webrtc/p2p/base/tcpport.cc | 4 +-- webrtc/p2p/base/transport.h | 11 +++++++ 9 files changed, 95 insertions(+), 58 deletions(-) diff --git a/webrtc/api/statscollector.cc b/webrtc/api/statscollector.cc index df1d0aa0d3..ab191d15e5 100644 --- a/webrtc/api/statscollector.cc +++ b/webrtc/api/statscollector.cc @@ -629,12 +629,19 @@ StatsReport* StatsCollector::AddConnectionInfoReport( AddCandidateReport(info.remote_candidate, false)->id()); const Int64ForAdd int64s[] = { - { StatsReport::kStatsValueNameBytesReceived, info.recv_total_bytes }, - { StatsReport::kStatsValueNameBytesSent, info.sent_total_bytes }, - { StatsReport::kStatsValueNamePacketsSent, info.sent_total_packets }, - { StatsReport::kStatsValueNameRtt, info.rtt }, - { StatsReport::kStatsValueNameSendPacketsDiscarded, - info.sent_discarded_packets }, + {StatsReport::kStatsValueNameBytesReceived, info.recv_total_bytes}, + {StatsReport::kStatsValueNameBytesSent, info.sent_total_bytes}, + {StatsReport::kStatsValueNamePacketsSent, info.sent_total_packets}, + {StatsReport::kStatsValueNameRtt, info.rtt}, + {StatsReport::kStatsValueNameSendPacketsDiscarded, + info.sent_discarded_packets}, + {StatsReport::kStatsValueNameSentPingRequestsTotal, + info.sent_ping_requests_total}, + {StatsReport::kStatsValueNameSentPingRequestsBeforeFirstResponse, + info.sent_ping_requests_before_first_response}, + {StatsReport::kStatsValueNameSentPingResponses, info.sent_ping_responses}, + {StatsReport::kStatsValueNameRecvPingRequests, info.recv_ping_requests}, + {StatsReport::kStatsValueNameRecvPingResponses, info.recv_ping_responses}, }; for (const auto& i : int64s) report->AddInt64(i.name, i.value); diff --git a/webrtc/api/statstypes.cc b/webrtc/api/statstypes.cc index 61af82467a..9e5e176d82 100644 --- a/webrtc/api/statstypes.cc +++ b/webrtc/api/statstypes.cc @@ -414,6 +414,18 @@ const char* StatsReport::Value::display_name() const { return "googBucketDelay"; case kStatsValueNameBandwidthLimitedResolution: return "googBandwidthLimitedResolution"; + // STUN ping related attributes. + // TODO(zhihuang) Rename these stats to follow the standards. + case kStatsValueNameSentPingRequestsTotal: + return "requestsSent"; + case kStatsValueNameSentPingRequestsBeforeFirstResponse: + return "consentRequestsSent"; + case kStatsValueNameSentPingResponses: + return "responsesSent"; + case kStatsValueNameRecvPingRequests: + return "requestsReceived"; + case kStatsValueNameRecvPingResponses: + return "responsesReceived"; // Candidate related attributes. Values are taken from // http://w3c.github.io/webrtc-stats/#rtcstatstype-enum*. diff --git a/webrtc/api/statstypes.h b/webrtc/api/statstypes.h index 4f58b97540..093bdbffe1 100644 --- a/webrtc/api/statstypes.h +++ b/webrtc/api/statstypes.h @@ -116,6 +116,11 @@ class StatsReport { kStatsValueNameSsrc, kStatsValueNameState, kStatsValueNameTransportId, + kStatsValueNameSentPingRequestsTotal, + kStatsValueNameSentPingRequestsBeforeFirstResponse, + kStatsValueNameSentPingResponses, + kStatsValueNameRecvPingRequests, + kStatsValueNameRecvPingResponses, // Internal StatsValue names. kStatsValueNameAccelerateRate, diff --git a/webrtc/p2p/base/p2ptransportchannel.cc b/webrtc/p2p/base/p2ptransportchannel.cc index a2fb774456..fc1f0a4e67 100644 --- a/webrtc/p2p/base/p2ptransportchannel.cc +++ b/webrtc/p2p/base/p2ptransportchannel.cc @@ -1018,24 +1018,16 @@ bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { // Gather connection infos. infos->clear(); - std::vector::const_iterator it; for (Connection* connection : connections_) { - ConnectionInfo info; + ConnectionInfo info = connection->stats(); info.best_connection = (best_connection_ == connection); info.receiving = connection->receiving(); - info.writable = - (connection->write_state() == Connection::STATE_WRITABLE); + info.writable = (connection->write_state() == Connection::STATE_WRITABLE); info.timeout = (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); info.new_connection = !connection->reported(); connection->set_reported(true); info.rtt = connection->rtt(); - info.sent_total_bytes = connection->sent_total_bytes(); - info.sent_bytes_second = connection->sent_bytes_second(); - info.sent_discarded_packets = connection->sent_discarded_packets(); - info.sent_total_packets = connection->sent_total_packets(); - info.recv_total_bytes = connection->recv_total_bytes(); - info.recv_bytes_second = connection->recv_bytes_second(); info.local_candidate = connection->local_candidate(); info.remote_candidate = connection->remote_candidate(); info.key = connection; diff --git a/webrtc/p2p/base/port.cc b/webrtc/p2p/base/port.cc index 0ce946582a..9fa6bad911 100644 --- a/webrtc/p2p/base/port.cc +++ b/webrtc/p2p/base/port.cc @@ -605,6 +605,8 @@ void Port::SendBindingResponse(StunMessage* request, << "Sent STUN ping response" << ", to=" << addr.ToSensitiveString() << ", id=" << rtc::hex_encode(response.transaction_id()); + + conn->stats_.sent_ping_responses++; } } @@ -842,8 +844,6 @@ Connection::Connection(Port* port, last_ping_response_received_(0), recv_rate_tracker_(100, 10u), send_rate_tracker_(100, 10u), - sent_packets_discarded_(0), - sent_packets_total_(0), reported_(false), state_(STATE_WAITING), receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT), @@ -1030,6 +1030,8 @@ void Connection::HandleBindingRequest(IceMessage* msg) { return; } + stats_.recv_ping_requests++; + // This is a validated stun request from remote peer. port_->SendBindingResponse(msg, remote_addr); @@ -1310,6 +1312,7 @@ void Connection::OnConnectionRequestResponse(ConnectionRequest* request, } rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); + stats_.recv_ping_responses++; MaybeAddPrflxCandidate(request, response); } @@ -1358,6 +1361,10 @@ void Connection::OnConnectionRequestSent(ConnectionRequest* request) { LOG_JV(sev, this) << "Sent STUN ping" << ", id=" << rtc::hex_encode(request->id()) << ", use_candidate=" << use_candidate; + stats_.sent_ping_requests_total++; + if (stats_.recv_ping_responses == 0) { + stats_.sent_ping_requests_before_first_response++; + } } void Connection::HandleRoleConflictFromPeer() { @@ -1408,28 +1415,12 @@ int64_t Connection::last_received() const { std::max(last_ping_received_, last_ping_response_received_)); } -size_t Connection::recv_bytes_second() { - return round(recv_rate_tracker_.ComputeRate()); -} - -size_t Connection::recv_total_bytes() { - return recv_rate_tracker_.TotalSampleCount(); -} - -size_t Connection::sent_bytes_second() { - return round(send_rate_tracker_.ComputeRate()); -} - -size_t Connection::sent_total_bytes() { - return send_rate_tracker_.TotalSampleCount(); -} - -size_t Connection::sent_discarded_packets() { - return sent_packets_discarded_; -} - -size_t Connection::sent_total_packets() { - return sent_packets_total_; +ConnectionInfo Connection::stats() { + stats_.recv_bytes_second = round(recv_rate_tracker_.ComputeRate()); + stats_.recv_total_bytes = recv_rate_tracker_.TotalSampleCount(); + stats_.sent_bytes_second = round(send_rate_tracker_.ComputeRate()); + stats_.sent_total_bytes = send_rate_tracker_.TotalSampleCount(); + return stats_; } void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request, @@ -1510,13 +1501,13 @@ int ProxyConnection::Send(const void* data, size_t size, error_ = EWOULDBLOCK; return SOCKET_ERROR; } - sent_packets_total_++; + stats_.sent_total_packets++; int sent = port_->SendTo(data, size, remote_candidate_.address(), options, true); if (sent <= 0) { ASSERT(sent < 0); error_ = port_->GetError(); - sent_packets_discarded_++; + stats_.sent_discarded_packets++; } else { send_rate_tracker_.AddSamples(sent); } diff --git a/webrtc/p2p/base/port.h b/webrtc/p2p/base/port.h index 21203572b1..06efd2d3c2 100644 --- a/webrtc/p2p/base/port.h +++ b/webrtc/p2p/base/port.h @@ -467,14 +467,8 @@ class Connection : public CandidatePairInterface, // Estimate of the round-trip time over this connection. int rtt() const { return rtt_; } - size_t sent_total_bytes(); - size_t sent_bytes_second(); - // Used to track how many packets are discarded in the application socket due - // to errors. - size_t sent_discarded_packets(); - size_t sent_total_packets(); - size_t recv_total_bytes(); - size_t recv_bytes_second(); + ConnectionInfo stats(); + sigslot::signal1 SignalStateChange; // Sent when the connection has decided that it is no longer of value. It @@ -643,8 +637,8 @@ class Connection : public CandidatePairInterface, rtc::RateTracker recv_rate_tracker_; rtc::RateTracker send_rate_tracker_; - uint32_t sent_packets_discarded_; - uint32_t sent_packets_total_; + + ConnectionInfo stats_; private: void MaybeAddPrflxCandidate(ConnectionRequest* request, diff --git a/webrtc/p2p/base/port_unittest.cc b/webrtc/p2p/base/port_unittest.cc index 099567f431..a345e82b61 100644 --- a/webrtc/p2p/base/port_unittest.cc +++ b/webrtc/p2p/base/port_unittest.cc @@ -1649,12 +1649,21 @@ TEST_F(PortTest, TestSendStunMessage) { // Save a copy of the BINDING-REQUEST for use below. std::unique_ptr request(CopyStunMessage(msg)); - // Respond with a BINDING-RESPONSE. - rport->SendBindingResponse(request.get(), lport->Candidates()[0].address()); + // Receive the BINDING-REQUEST and respond with BINDING-RESPONSE. + rconn->OnReadPacket(lport->last_stun_buf()->data(), + lport->last_stun_buf()->size(), rtc::PacketTime()); msg = rport->last_stun_msg(); ASSERT_TRUE(msg != NULL); EXPECT_EQ(STUN_BINDING_RESPONSE, msg->type()); - + // Received a BINDING-RESPONSE. + lconn->OnReadPacket(rport->last_stun_buf()->data(), + rport->last_stun_buf()->size(), rtc::PacketTime()); + // Verify the STUN Stats. + EXPECT_EQ(1U, lconn->stats().sent_ping_requests_total); + EXPECT_EQ(1U, lconn->stats().sent_ping_requests_before_first_response); + EXPECT_EQ(1U, lconn->stats().recv_ping_responses); + EXPECT_EQ(1U, rconn->stats().recv_ping_requests); + EXPECT_EQ(1U, rconn->stats().sent_ping_responses); EXPECT_FALSE(msg->IsLegacy()); const StunAddressAttribute* addr_attr = msg->GetAddress( @@ -1728,8 +1737,24 @@ TEST_F(PortTest, TestSendStunMessage) { // Respond with a BINDING-RESPONSE. request.reset(CopyStunMessage(msg)); - lport->SendBindingResponse(request.get(), rport->Candidates()[0].address()); + lconn->OnReadPacket(rport->last_stun_buf()->data(), + rport->last_stun_buf()->size(), rtc::PacketTime()); msg = lport->last_stun_msg(); + // Receive the BINDING-RESPONSE. + rconn->OnReadPacket(lport->last_stun_buf()->data(), + lport->last_stun_buf()->size(), rtc::PacketTime()); + + // Verify the Stun ping stats. + EXPECT_EQ(3U, rconn->stats().sent_ping_requests_total); + EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response); + EXPECT_EQ(1U, rconn->stats().recv_ping_responses); + EXPECT_EQ(1U, lconn->stats().sent_ping_responses); + EXPECT_EQ(1U, lconn->stats().recv_ping_requests); + // Ping after receiver the first response + rconn->Ping(0); + rconn->Ping(0); + EXPECT_EQ(5U, rconn->stats().sent_ping_requests_total); + EXPECT_EQ(3U, rconn->stats().sent_ping_requests_before_first_response); // Response should include same ping count. retransmit_attr = msg->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT); diff --git a/webrtc/p2p/base/tcpport.cc b/webrtc/p2p/base/tcpport.cc index 54a44249d3..6166f52b4c 100644 --- a/webrtc/p2p/base/tcpport.cc +++ b/webrtc/p2p/base/tcpport.cc @@ -351,10 +351,10 @@ int TCPConnection::Send(const void* data, size_t size, error_ = EWOULDBLOCK; return SOCKET_ERROR; } - sent_packets_total_++; + stats_.sent_total_packets++; int sent = socket_->Send(data, size, options); if (sent < 0) { - sent_packets_discarded_++; + stats_.sent_discarded_packets++; error_ = socket_->GetError(); } else { send_rate_tracker_.AddSamples(sent); diff --git a/webrtc/p2p/base/transport.h b/webrtc/p2p/base/transport.h index e31d37a6f6..9b6cf519f8 100644 --- a/webrtc/p2p/base/transport.h +++ b/webrtc/p2p/base/transport.h @@ -95,8 +95,13 @@ struct ConnectionInfo { sent_bytes_second(0), sent_discarded_packets(0), sent_total_packets(0), + sent_ping_requests_total(0), + sent_ping_requests_before_first_response(0), + sent_ping_responses(0), recv_total_bytes(0), recv_bytes_second(0), + recv_ping_requests(0), + recv_ping_responses(0), key(NULL) {} bool best_connection; // Is this the best connection we have? @@ -111,9 +116,15 @@ struct ConnectionInfo { // socket errors. size_t sent_total_packets; // Number of total outgoing packets attempted for // sending. + size_t sent_ping_requests_total; // Number of STUN ping request sent. + size_t sent_ping_requests_before_first_response; // Number of STUN ping + // sent before receiving the first response. + size_t sent_ping_responses; // Number of STUN ping response sent. size_t recv_total_bytes; // Total bytes received on this connection. size_t recv_bytes_second; // Bps over the last measurement interval. + size_t recv_ping_requests; // Number of STUN ping request received. + size_t recv_ping_responses; // Number of STUN ping response received. Candidate local_candidate; // The local candidate for this connection. Candidate remote_candidate; // The remote candidate for this connection. void* key; // A static value that identifies this conn.