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}
This commit is contained in:
zhihuang
2016-06-01 17:09:15 -07:00
committed by Commit bot
parent 36f50e8e4e
commit 5ecf16c072
9 changed files with 95 additions and 58 deletions

View File

@ -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);

View File

@ -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*.

View File

@ -116,6 +116,11 @@ class StatsReport {
kStatsValueNameSsrc,
kStatsValueNameState,
kStatsValueNameTransportId,
kStatsValueNameSentPingRequestsTotal,
kStatsValueNameSentPingRequestsBeforeFirstResponse,
kStatsValueNameSentPingResponses,
kStatsValueNameRecvPingRequests,
kStatsValueNameRecvPingResponses,
// Internal StatsValue names.
kStatsValueNameAccelerateRate,

View File

@ -1018,24 +1018,16 @@ bool P2PTransportChannel::GetStats(ConnectionInfos *infos) {
// Gather connection infos.
infos->clear();
std::vector<Connection *>::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;

View File

@ -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);
}

View File

@ -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<Connection*> 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,

View File

@ -1649,12 +1649,21 @@ TEST_F(PortTest, TestSendStunMessage) {
// Save a copy of the BINDING-REQUEST for use below.
std::unique_ptr<IceMessage> 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<char>(),
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<char>(),
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<char>(),
rport->last_stun_buf()->size(), rtc::PacketTime());
msg = lport->last_stun_msg();
// Receive the BINDING-RESPONSE.
rconn->OnReadPacket(lport->last_stun_buf()->data<char>(),
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);

View File

@ -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);

View File

@ -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.