OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1181 requests_.Send(req); | 1181 requests_.Send(req); |
1182 state_ = STATE_INPROGRESS; | 1182 state_ = STATE_INPROGRESS; |
1183 num_pings_sent_++; | 1183 num_pings_sent_++; |
1184 } | 1184 } |
1185 | 1185 |
1186 void Connection::ReceivedPing() { | 1186 void Connection::ReceivedPing() { |
1187 set_receiving(true); | 1187 set_receiving(true); |
1188 last_ping_received_ = rtc::TimeMillis(); | 1188 last_ping_received_ = rtc::TimeMillis(); |
1189 } | 1189 } |
1190 | 1190 |
1191 void Connection::ReceivedPingResponse() { | 1191 void Connection::ReceivedPingResponse(int rtt) { |
1192 // We've already validated that this is a STUN binding response with | 1192 // We've already validated that this is a STUN binding response with |
1193 // the correct local and remote username for this connection. | 1193 // the correct local and remote username for this connection. |
1194 // So if we're not already, become writable. We may be bringing a pruned | 1194 // So if we're not already, become writable. We may be bringing a pruned |
1195 // connection back to life, but if we don't really want it, we can always | 1195 // connection back to life, but if we don't really want it, we can always |
1196 // prune it again. | 1196 // prune it again. |
1197 set_receiving(true); | 1197 set_receiving(true); |
1198 set_write_state(STATE_WRITABLE); | 1198 set_write_state(STATE_WRITABLE); |
1199 set_state(STATE_SUCCEEDED); | 1199 set_state(STATE_SUCCEEDED); |
1200 pings_since_last_response_.clear(); | 1200 pings_since_last_response_.clear(); |
1201 last_ping_response_received_ = rtc::TimeMillis(); | 1201 last_ping_response_received_ = rtc::TimeMillis(); |
| 1202 rtt_samples_++; |
| 1203 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); |
1202 } | 1204 } |
1203 | 1205 |
1204 bool Connection::dead(int64_t now) const { | 1206 bool Connection::dead(int64_t now) const { |
1205 if (last_received() > 0) { | 1207 if (last_received() > 0) { |
1206 // If it has ever received anything, we keep it alive until it hasn't | 1208 // If it has ever received anything, we keep it alive until it hasn't |
1207 // received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT. This covers the | 1209 // received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT. This covers the |
1208 // normal case of a successfully used connection that stops working. This | 1210 // normal case of a successfully used connection that stops working. This |
1209 // also allows a remote peer to continue pinging over a locally inactive | 1211 // also allows a remote peer to continue pinging over a locally inactive |
1210 // (pruned) connection. | 1212 // (pruned) connection. |
1211 return (now > (last_received() + DEAD_CONNECTION_RECEIVE_TIMEOUT)); | 1213 return (now > (last_received() + DEAD_CONNECTION_RECEIVE_TIMEOUT)); |
1212 } | 1214 } |
1213 | 1215 |
1214 if (active()) { | 1216 if (active()) { |
1215 // If it has never received anything, keep it alive as long as it is | 1217 // If it has never received anything, keep it alive as long as it is |
1216 // actively pinging and not pruned. Otherwise, the connection might be | 1218 // actively pinging and not pruned. Otherwise, the connection might be |
1217 // deleted before it has a chance to ping. This is the normal case for a | 1219 // deleted before it has a chance to ping. This is the normal case for a |
1218 // new connection that is pinging but hasn't received anything yet. | 1220 // new connection that is pinging but hasn't received anything yet. |
1219 return false; | 1221 return false; |
1220 } | 1222 } |
1221 | 1223 |
1222 // If it has never received anything and is not actively pinging (pruned), we | 1224 // If it has never received anything and is not actively pinging (pruned), we |
1223 // keep it around for at least MIN_CONNECTION_LIFETIME to prevent connections | 1225 // keep it around for at least MIN_CONNECTION_LIFETIME to prevent connections |
1224 // from being pruned too quickly during a network change event when two | 1226 // from being pruned too quickly during a network change event when two |
1225 // networks would be up simultaneously but only for a brief period. | 1227 // networks would be up simultaneously but only for a brief period. |
1226 return now > (time_created_ms_ + MIN_CONNECTION_LIFETIME); | 1228 return now > (time_created_ms_ + MIN_CONNECTION_LIFETIME); |
1227 } | 1229 } |
1228 | 1230 |
| 1231 bool Connection::stable(int64_t now) { |
| 1232 // A connection is stable if it's RTT has converged and it isn't missing any |
| 1233 // responses. We should send pings at a higher rate until the RTT converges |
| 1234 // and whenever a ping response is missing (so that we can detect |
| 1235 // unwritability faster) |
| 1236 return rtt_converged() && !missing_responses(now); |
| 1237 } |
| 1238 |
1229 std::string Connection::ToDebugId() const { | 1239 std::string Connection::ToDebugId() const { |
1230 std::stringstream ss; | 1240 std::stringstream ss; |
1231 ss << std::hex << this; | 1241 ss << std::hex << this; |
1232 return ss.str(); | 1242 return ss.str(); |
1233 } | 1243 } |
1234 | 1244 |
1235 uint32_t Connection::ComputeNetworkCost() const { | 1245 uint32_t Connection::ComputeNetworkCost() const { |
1236 // TODO(honghaiz): Will add rtt as part of the network cost. | 1246 // TODO(honghaiz): Will add rtt as part of the network cost. |
1237 return port()->network_cost() + remote_candidate_.network_cost(); | 1247 return port()->network_cost() + remote_candidate_.network_cost(); |
1238 } | 1248 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1289 } | 1299 } |
1290 | 1300 |
1291 void Connection::OnConnectionRequestResponse(ConnectionRequest* request, | 1301 void Connection::OnConnectionRequestResponse(ConnectionRequest* request, |
1292 StunMessage* response) { | 1302 StunMessage* response) { |
1293 // Log at LS_INFO if we receive a ping response on an unwritable | 1303 // Log at LS_INFO if we receive a ping response on an unwritable |
1294 // connection. | 1304 // connection. |
1295 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; | 1305 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; |
1296 | 1306 |
1297 int rtt = request->Elapsed(); | 1307 int rtt = request->Elapsed(); |
1298 | 1308 |
1299 ReceivedPingResponse(); | 1309 ReceivedPingResponse(rtt); |
1300 | 1310 |
1301 if (LOG_CHECK_LEVEL_V(sev)) { | 1311 if (LOG_CHECK_LEVEL_V(sev)) { |
1302 bool use_candidate = ( | 1312 bool use_candidate = ( |
1303 response->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr); | 1313 response->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr); |
1304 std::string pings; | 1314 std::string pings; |
1305 PrintPingsSinceLastResponse(&pings, 5); | 1315 PrintPingsSinceLastResponse(&pings, 5); |
1306 LOG_JV(sev, this) << "Received STUN ping response" | 1316 LOG_JV(sev, this) << "Received STUN ping response" |
1307 << ", id=" << rtc::hex_encode(request->id()) | 1317 << ", id=" << rtc::hex_encode(request->id()) |
1308 << ", code=0" // Makes logging easier to parse. | 1318 << ", code=0" // Makes logging easier to parse. |
1309 << ", rtt=" << rtt | 1319 << ", rtt=" << rtt |
1310 << ", use_candidate=" << use_candidate | 1320 << ", use_candidate=" << use_candidate |
1311 << ", pings_since_last_response=" << pings; | 1321 << ", pings_since_last_response=" << pings; |
1312 } | 1322 } |
1313 | 1323 |
1314 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); | |
1315 stats_.recv_ping_responses++; | 1324 stats_.recv_ping_responses++; |
1316 | 1325 |
1317 MaybeAddPrflxCandidate(request, response); | 1326 MaybeAddPrflxCandidate(request, response); |
1318 } | 1327 } |
1319 | 1328 |
1320 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, | 1329 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, |
1321 StunMessage* response) { | 1330 StunMessage* response) { |
1322 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); | 1331 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); |
1323 int error_code = STUN_ERROR_GLOBAL_FAILURE; | 1332 int error_code = STUN_ERROR_GLOBAL_FAILURE; |
1324 if (error_attr) { | 1333 if (error_attr) { |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1483 new_local_candidate.set_network_cost(local_candidate().network_cost()); | 1492 new_local_candidate.set_network_cost(local_candidate().network_cost()); |
1484 | 1493 |
1485 // Change the local candidate of this Connection to the new prflx candidate. | 1494 // Change the local candidate of this Connection to the new prflx candidate. |
1486 local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate); | 1495 local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate); |
1487 | 1496 |
1488 // SignalStateChange to force a re-sort in P2PTransportChannel as this | 1497 // SignalStateChange to force a re-sort in P2PTransportChannel as this |
1489 // Connection's local candidate has changed. | 1498 // Connection's local candidate has changed. |
1490 SignalStateChange(this); | 1499 SignalStateChange(this); |
1491 } | 1500 } |
1492 | 1501 |
| 1502 bool Connection::rtt_converged() { |
| 1503 return rtt_samples_ > (RTT_RATIO + 1); |
| 1504 } |
| 1505 |
| 1506 bool Connection::missing_responses(int64_t now) { |
| 1507 if (pings_since_last_response_.empty()) { |
| 1508 return false; |
| 1509 } |
| 1510 |
| 1511 int64_t waiting = now - pings_since_last_response_[0].sent_time; |
| 1512 return waiting > 2 * rtt(); |
| 1513 } |
| 1514 |
1493 ProxyConnection::ProxyConnection(Port* port, | 1515 ProxyConnection::ProxyConnection(Port* port, |
1494 size_t index, | 1516 size_t index, |
1495 const Candidate& remote_candidate) | 1517 const Candidate& remote_candidate) |
1496 : Connection(port, index, remote_candidate) {} | 1518 : Connection(port, index, remote_candidate) {} |
1497 | 1519 |
1498 int ProxyConnection::Send(const void* data, size_t size, | 1520 int ProxyConnection::Send(const void* data, size_t size, |
1499 const rtc::PacketOptions& options) { | 1521 const rtc::PacketOptions& options) { |
1500 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) { | 1522 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) { |
1501 error_ = EWOULDBLOCK; | 1523 error_ = EWOULDBLOCK; |
1502 return SOCKET_ERROR; | 1524 return SOCKET_ERROR; |
1503 } | 1525 } |
1504 stats_.sent_total_packets++; | 1526 stats_.sent_total_packets++; |
1505 int sent = port_->SendTo(data, size, remote_candidate_.address(), | 1527 int sent = port_->SendTo(data, size, remote_candidate_.address(), |
1506 options, true); | 1528 options, true); |
1507 if (sent <= 0) { | 1529 if (sent <= 0) { |
1508 ASSERT(sent < 0); | 1530 ASSERT(sent < 0); |
1509 error_ = port_->GetError(); | 1531 error_ = port_->GetError(); |
1510 stats_.sent_discarded_packets++; | 1532 stats_.sent_discarded_packets++; |
1511 } else { | 1533 } else { |
1512 send_rate_tracker_.AddSamples(sent); | 1534 send_rate_tracker_.AddSamples(sent); |
1513 } | 1535 } |
1514 return sent; | 1536 return sent; |
1515 } | 1537 } |
1516 | 1538 |
1517 } // namespace cricket | 1539 } // namespace cricket |
OLD | NEW |