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 757 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 } | 768 } |
769 uint32_t network_info = connection_->port()->Network()->id(); | 769 uint32_t network_info = connection_->port()->Network()->id(); |
770 network_info = (network_info << 16) | connection_->port()->network_cost(); | 770 network_info = (network_info << 16) | connection_->port()->network_cost(); |
771 request->AddAttribute( | 771 request->AddAttribute( |
772 new StunUInt32Attribute(STUN_ATTR_NETWORK_INFO, network_info)); | 772 new StunUInt32Attribute(STUN_ATTR_NETWORK_INFO, network_info)); |
773 | 773 |
774 // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role. | 774 // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role. |
775 if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) { | 775 if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) { |
776 request->AddAttribute(new StunUInt64Attribute( | 776 request->AddAttribute(new StunUInt64Attribute( |
777 STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker())); | 777 STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker())); |
778 // Since we are trying aggressive nomination, sending USE-CANDIDATE | 778 // We should have either USE_CANDIDATE attribute or ICE_NOMINATION |
779 // attribute in every ping. | 779 // attribute but not both. That was enforced in p2ptransportchannel. |
780 // If we are dealing with a ice-lite end point, nomination flag | |
781 // in Connection will be set to false by default. Once the connection | |
782 // becomes "best connection", nomination flag will be turned on. | |
783 if (connection_->use_candidate_attr()) { | 780 if (connection_->use_candidate_attr()) { |
784 request->AddAttribute(new StunByteStringAttribute( | 781 request->AddAttribute(new StunByteStringAttribute( |
785 STUN_ATTR_USE_CANDIDATE)); | 782 STUN_ATTR_USE_CANDIDATE)); |
786 } | 783 } |
| 784 if (connection_->nomination() && |
| 785 connection_->nomination() != connection_->acked_nomination()) { |
| 786 request->AddAttribute(new StunUInt32Attribute( |
| 787 STUN_ATTR_NOMINATION, connection_->nomination())); |
| 788 } |
787 } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) { | 789 } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) { |
788 request->AddAttribute(new StunUInt64Attribute( | 790 request->AddAttribute(new StunUInt64Attribute( |
789 STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker())); | 791 STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker())); |
790 } else { | 792 } else { |
791 ASSERT(false); | 793 ASSERT(false); |
792 } | 794 } |
793 | 795 |
794 // Adding PRIORITY Attribute. | 796 // Adding PRIORITY Attribute. |
795 // Changing the type preference to Peer Reflexive and local preference | 797 // Changing the type preference to Peer Reflexive and local preference |
796 // and component id information is unchanged from the original priority. | 798 // and component id information is unchanged from the original priority. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 // | 841 // |
840 // Connection | 842 // Connection |
841 // | 843 // |
842 | 844 |
843 Connection::Connection(Port* port, | 845 Connection::Connection(Port* port, |
844 size_t index, | 846 size_t index, |
845 const Candidate& remote_candidate) | 847 const Candidate& remote_candidate) |
846 : port_(port), | 848 : port_(port), |
847 local_candidate_index_(index), | 849 local_candidate_index_(index), |
848 remote_candidate_(remote_candidate), | 850 remote_candidate_(remote_candidate), |
| 851 recv_rate_tracker_(100, 10u), |
| 852 send_rate_tracker_(100, 10u), |
849 write_state_(STATE_WRITE_INIT), | 853 write_state_(STATE_WRITE_INIT), |
850 receiving_(false), | 854 receiving_(false), |
851 connected_(true), | 855 connected_(true), |
852 pruned_(false), | 856 pruned_(false), |
853 use_candidate_attr_(false), | 857 use_candidate_attr_(false), |
854 nominated_(false), | |
855 remote_ice_mode_(ICEMODE_FULL), | 858 remote_ice_mode_(ICEMODE_FULL), |
856 requests_(port->thread()), | 859 requests_(port->thread()), |
857 rtt_(DEFAULT_RTT), | 860 rtt_(DEFAULT_RTT), |
858 last_ping_sent_(0), | 861 last_ping_sent_(0), |
859 last_ping_received_(0), | 862 last_ping_received_(0), |
860 last_data_received_(0), | 863 last_data_received_(0), |
861 last_ping_response_received_(0), | 864 last_ping_response_received_(0), |
862 recv_rate_tracker_(100, 10u), | |
863 send_rate_tracker_(100, 10u), | |
864 reported_(false), | 865 reported_(false), |
865 state_(STATE_WAITING), | 866 state_(STATE_WAITING), |
866 receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT), | 867 receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT), |
867 time_created_ms_(rtc::TimeMillis()) { | 868 time_created_ms_(rtc::TimeMillis()) { |
868 // All of our connections start in WAITING state. | 869 // All of our connections start in WAITING state. |
869 // TODO(mallinath) - Start connections from STATE_FROZEN. | 870 // TODO(mallinath) - Start connections from STATE_FROZEN. |
870 // Wire up to send stun packets | 871 // Wire up to send stun packets |
871 requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket); | 872 requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket); |
872 LOG_J(LS_INFO, this) << "Connection created"; | 873 LOG_J(LS_INFO, this) << "Connection created"; |
873 } | 874 } |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 | 1056 |
1056 // This is a validated stun request from remote peer. | 1057 // This is a validated stun request from remote peer. |
1057 port_->SendBindingResponse(msg, remote_addr); | 1058 port_->SendBindingResponse(msg, remote_addr); |
1058 | 1059 |
1059 // If it timed out on writing check, start up again | 1060 // If it timed out on writing check, start up again |
1060 if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) { | 1061 if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) { |
1061 set_write_state(STATE_WRITE_INIT); | 1062 set_write_state(STATE_WRITE_INIT); |
1062 } | 1063 } |
1063 | 1064 |
1064 if (port_->GetIceRole() == ICEROLE_CONTROLLED) { | 1065 if (port_->GetIceRole() == ICEROLE_CONTROLLED) { |
1065 const StunByteStringAttribute* use_candidate_attr = | 1066 const StunUInt32Attribute* nomination_attr = |
1066 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); | 1067 msg->GetUInt32(STUN_ATTR_NOMINATION); |
1067 if (use_candidate_attr) { | 1068 uint32_t nomination = 0; |
1068 set_nominated(true); | 1069 if (nomination_attr) { |
| 1070 nomination = nomination_attr->value(); |
| 1071 if (nomination == 0) { |
| 1072 LOG(LS_ERROR) << "Invalid nomination: " << nomination; |
| 1073 } |
| 1074 } else { |
| 1075 const StunByteStringAttribute* use_candidate_attr = |
| 1076 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); |
| 1077 if (use_candidate_attr) { |
| 1078 nomination = 1; |
| 1079 } |
| 1080 } |
| 1081 // We don't un-nominate a connection, so we only keep a larger nomination. |
| 1082 if (nomination > remote_nomination_) { |
| 1083 set_remote_nomination(nomination); |
1069 SignalNominated(this); | 1084 SignalNominated(this); |
1070 } | 1085 } |
1071 } | 1086 } |
1072 // Set the remote cost if the network_info attribute is available. | 1087 // Set the remote cost if the network_info attribute is available. |
1073 // Note: If packets are re-ordered, we may get incorrect network cost | 1088 // Note: If packets are re-ordered, we may get incorrect network cost |
1074 // temporarily, but it should get the correct value shortly after that. | 1089 // temporarily, but it should get the correct value shortly after that. |
1075 const StunUInt32Attribute* network_attr = | 1090 const StunUInt32Attribute* network_attr = |
1076 msg->GetUInt32(STUN_ATTR_NETWORK_INFO); | 1091 msg->GetUInt32(STUN_ATTR_NETWORK_INFO); |
1077 if (network_attr) { | 1092 if (network_attr) { |
1078 uint32_t network_info = network_attr->value(); | 1093 uint32_t network_info = network_attr->value(); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 // Update the receiving state. | 1207 // Update the receiving state. |
1193 UpdateReceiving(now); | 1208 UpdateReceiving(now); |
1194 if (dead(now)) { | 1209 if (dead(now)) { |
1195 Destroy(); | 1210 Destroy(); |
1196 } | 1211 } |
1197 } | 1212 } |
1198 | 1213 |
1199 void Connection::Ping(int64_t now) { | 1214 void Connection::Ping(int64_t now) { |
1200 last_ping_sent_ = now; | 1215 last_ping_sent_ = now; |
1201 ConnectionRequest *req = new ConnectionRequest(this); | 1216 ConnectionRequest *req = new ConnectionRequest(this); |
1202 pings_since_last_response_.push_back(SentPing(req->id(), now)); | 1217 pings_since_last_response_.push_back(SentPing(req->id(), now, nomination_)); |
1203 LOG_J(LS_VERBOSE, this) << "Sending STUN ping " | 1218 LOG_J(LS_VERBOSE, this) << "Sending STUN ping " |
1204 << ", id=" << rtc::hex_encode(req->id()); | 1219 << ", id=" << rtc::hex_encode(req->id()) |
| 1220 << ", nomination=" << nomination_; |
1205 requests_.Send(req); | 1221 requests_.Send(req); |
1206 state_ = STATE_INPROGRESS; | 1222 state_ = STATE_INPROGRESS; |
1207 num_pings_sent_++; | 1223 num_pings_sent_++; |
1208 } | 1224 } |
1209 | 1225 |
1210 void Connection::ReceivedPing() { | 1226 void Connection::ReceivedPing() { |
1211 last_ping_received_ = rtc::TimeMillis(); | 1227 last_ping_received_ = rtc::TimeMillis(); |
1212 UpdateReceiving(last_ping_received_); | 1228 UpdateReceiving(last_ping_received_); |
1213 } | 1229 } |
1214 | 1230 |
1215 void Connection::ReceivedPingResponse(int rtt) { | 1231 void Connection::ReceivedPingResponse(int rtt, const std::string& request_id) { |
1216 // We've already validated that this is a STUN binding response with | 1232 // We've already validated that this is a STUN binding response with |
1217 // the correct local and remote username for this connection. | 1233 // the correct local and remote username for this connection. |
1218 // So if we're not already, become writable. We may be bringing a pruned | 1234 // So if we're not already, become writable. We may be bringing a pruned |
1219 // connection back to life, but if we don't really want it, we can always | 1235 // connection back to life, but if we don't really want it, we can always |
1220 // prune it again. | 1236 // prune it again. |
| 1237 auto iter = std::find_if( |
| 1238 pings_since_last_response_.begin(), pings_since_last_response_.end(), |
| 1239 [request_id](const SentPing& ping) { return ping.id == request_id; }); |
| 1240 if (iter != pings_since_last_response_.end() && |
| 1241 iter->nomination > acked_nomination_) { |
| 1242 acked_nomination_ = iter->nomination; |
| 1243 } |
| 1244 |
| 1245 pings_since_last_response_.clear(); |
1221 last_ping_response_received_ = rtc::TimeMillis(); | 1246 last_ping_response_received_ = rtc::TimeMillis(); |
1222 UpdateReceiving(last_ping_response_received_); | 1247 UpdateReceiving(last_ping_response_received_); |
1223 set_write_state(STATE_WRITABLE); | 1248 set_write_state(STATE_WRITABLE); |
1224 set_state(STATE_SUCCEEDED); | 1249 set_state(STATE_SUCCEEDED); |
1225 pings_since_last_response_.clear(); | |
1226 rtt_samples_++; | 1250 rtt_samples_++; |
1227 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); | 1251 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); |
1228 } | 1252 } |
1229 | 1253 |
1230 bool Connection::dead(int64_t now) const { | 1254 bool Connection::dead(int64_t now) const { |
1231 if (last_received() > 0) { | 1255 if (last_received() > 0) { |
1232 // If it has ever received anything, we keep it alive until it hasn't | 1256 // If it has ever received anything, we keep it alive until it hasn't |
1233 // received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT. This covers the | 1257 // received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT. This covers the |
1234 // normal case of a successfully used connection that stops working. This | 1258 // normal case of a successfully used connection that stops working. This |
1235 // also allows a remote peer to continue pinging over a locally inactive | 1259 // also allows a remote peer to continue pinging over a locally inactive |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1288 }; | 1312 }; |
1289 const std::string ICESTATE[4] = { | 1313 const std::string ICESTATE[4] = { |
1290 "W", // STATE_WAITING | 1314 "W", // STATE_WAITING |
1291 "I", // STATE_INPROGRESS | 1315 "I", // STATE_INPROGRESS |
1292 "S", // STATE_SUCCEEDED | 1316 "S", // STATE_SUCCEEDED |
1293 "F" // STATE_FAILED | 1317 "F" // STATE_FAILED |
1294 }; | 1318 }; |
1295 const Candidate& local = local_candidate(); | 1319 const Candidate& local = local_candidate(); |
1296 const Candidate& remote = remote_candidate(); | 1320 const Candidate& remote = remote_candidate(); |
1297 std::stringstream ss; | 1321 std::stringstream ss; |
1298 ss << "Conn[" << ToDebugId() | 1322 ss << "Conn[" << ToDebugId() << ":" << port_->content_name() << ":" |
1299 << ":" << port_->content_name() | 1323 << local.id() << ":" << local.component() << ":" << local.generation() |
1300 << ":" << local.id() << ":" << local.component() | 1324 << ":" << local.type() << ":" << local.protocol() << ":" |
1301 << ":" << local.generation() | 1325 << local.address().ToSensitiveString() << "->" << remote.id() << ":" |
1302 << ":" << local.type() << ":" << local.protocol() | 1326 << remote.component() << ":" << remote.priority() << ":" << remote.type() |
1303 << ":" << local.address().ToSensitiveString() | 1327 << ":" << remote.protocol() << ":" << remote.address().ToSensitiveString() |
1304 << "->" << remote.id() << ":" << remote.component() | 1328 << "|" << CONNECT_STATE_ABBREV[connected()] |
1305 << ":" << remote.priority() | 1329 << RECEIVE_STATE_ABBREV[receiving()] << WRITE_STATE_ABBREV[write_state()] |
1306 << ":" << remote.type() << ":" | 1330 << ICESTATE[state()] << "|" << remote_nomination() << "|" << nomination() |
1307 << remote.protocol() << ":" << remote.address().ToSensitiveString() << "|" | 1331 << "|" << priority() << "|"; |
1308 << CONNECT_STATE_ABBREV[connected()] | |
1309 << RECEIVE_STATE_ABBREV[receiving()] | |
1310 << WRITE_STATE_ABBREV[write_state()] | |
1311 << ICESTATE[state()] << "|" | |
1312 << priority() << "|"; | |
1313 if (rtt_ < DEFAULT_RTT) { | 1332 if (rtt_ < DEFAULT_RTT) { |
1314 ss << rtt_ << "]"; | 1333 ss << rtt_ << "]"; |
1315 } else { | 1334 } else { |
1316 ss << "-]"; | 1335 ss << "-]"; |
1317 } | 1336 } |
1318 return ss.str(); | 1337 return ss.str(); |
1319 } | 1338 } |
1320 | 1339 |
1321 std::string Connection::ToSensitiveString() const { | 1340 std::string Connection::ToSensitiveString() const { |
1322 return ToString(); | 1341 return ToString(); |
1323 } | 1342 } |
1324 | 1343 |
1325 void Connection::OnConnectionRequestResponse(ConnectionRequest* request, | 1344 void Connection::OnConnectionRequestResponse(ConnectionRequest* request, |
1326 StunMessage* response) { | 1345 StunMessage* response) { |
1327 // Log at LS_INFO if we receive a ping response on an unwritable | 1346 // Log at LS_INFO if we receive a ping response on an unwritable |
1328 // connection. | 1347 // connection. |
1329 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; | 1348 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; |
1330 | 1349 |
1331 int rtt = request->Elapsed(); | 1350 int rtt = request->Elapsed(); |
1332 | 1351 |
1333 ReceivedPingResponse(rtt); | |
1334 | |
1335 if (LOG_CHECK_LEVEL_V(sev)) { | 1352 if (LOG_CHECK_LEVEL_V(sev)) { |
1336 bool use_candidate = ( | |
1337 response->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr); | |
1338 std::string pings; | 1353 std::string pings; |
1339 PrintPingsSinceLastResponse(&pings, 5); | 1354 PrintPingsSinceLastResponse(&pings, 5); |
1340 LOG_JV(sev, this) << "Received STUN ping response" | 1355 LOG_JV(sev, this) << "Received STUN ping response" |
1341 << ", id=" << rtc::hex_encode(request->id()) | 1356 << ", id=" << rtc::hex_encode(request->id()) |
1342 << ", code=0" // Makes logging easier to parse. | 1357 << ", code=0" // Makes logging easier to parse. |
1343 << ", rtt=" << rtt | 1358 << ", rtt=" << rtt |
1344 << ", use_candidate=" << use_candidate | |
1345 << ", pings_since_last_response=" << pings; | 1359 << ", pings_since_last_response=" << pings; |
1346 } | 1360 } |
| 1361 ReceivedPingResponse(rtt, request->id()); |
1347 | 1362 |
1348 stats_.recv_ping_responses++; | 1363 stats_.recv_ping_responses++; |
1349 | 1364 |
1350 MaybeAddPrflxCandidate(request, response); | 1365 MaybeAddPrflxCandidate(request, response); |
1351 } | 1366 } |
1352 | 1367 |
1353 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, | 1368 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, |
1354 StunMessage* response) { | 1369 StunMessage* response) { |
1355 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); | 1370 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); |
1356 int error_code = STUN_ERROR_GLOBAL_FAILURE; | 1371 int error_code = STUN_ERROR_GLOBAL_FAILURE; |
(...skipping 26 matching lines...) Expand all Loading... |
1383 // Log at LS_INFO if we miss a ping on a writable connection. | 1398 // Log at LS_INFO if we miss a ping on a writable connection. |
1384 rtc::LoggingSeverity sev = writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; | 1399 rtc::LoggingSeverity sev = writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; |
1385 LOG_JV(sev, this) << "Timing-out STUN ping " | 1400 LOG_JV(sev, this) << "Timing-out STUN ping " |
1386 << rtc::hex_encode(request->id()) | 1401 << rtc::hex_encode(request->id()) |
1387 << " after " << request->Elapsed() << " ms"; | 1402 << " after " << request->Elapsed() << " ms"; |
1388 } | 1403 } |
1389 | 1404 |
1390 void Connection::OnConnectionRequestSent(ConnectionRequest* request) { | 1405 void Connection::OnConnectionRequestSent(ConnectionRequest* request) { |
1391 // Log at LS_INFO if we send a ping on an unwritable connection. | 1406 // Log at LS_INFO if we send a ping on an unwritable connection. |
1392 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; | 1407 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; |
1393 bool use_candidate = use_candidate_attr(); | |
1394 LOG_JV(sev, this) << "Sent STUN ping" | 1408 LOG_JV(sev, this) << "Sent STUN ping" |
1395 << ", id=" << rtc::hex_encode(request->id()) | 1409 << ", id=" << rtc::hex_encode(request->id()) |
1396 << ", use_candidate=" << use_candidate; | 1410 << ", use_candidate=" << use_candidate_attr() |
| 1411 << ", nomination=" << nomination(); |
1397 stats_.sent_ping_requests_total++; | 1412 stats_.sent_ping_requests_total++; |
1398 if (stats_.recv_ping_responses == 0) { | 1413 if (stats_.recv_ping_responses == 0) { |
1399 stats_.sent_ping_requests_before_first_response++; | 1414 stats_.sent_ping_requests_before_first_response++; |
1400 } | 1415 } |
1401 } | 1416 } |
1402 | 1417 |
1403 void Connection::HandleRoleConflictFromPeer() { | 1418 void Connection::HandleRoleConflictFromPeer() { |
1404 port_->SignalRoleConflict(port_); | 1419 port_->SignalRoleConflict(port_); |
1405 } | 1420 } |
1406 | 1421 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1551 ASSERT(sent < 0); | 1566 ASSERT(sent < 0); |
1552 error_ = port_->GetError(); | 1567 error_ = port_->GetError(); |
1553 stats_.sent_discarded_packets++; | 1568 stats_.sent_discarded_packets++; |
1554 } else { | 1569 } else { |
1555 send_rate_tracker_.AddSamples(sent); | 1570 send_rate_tracker_.AddSamples(sent); |
1556 } | 1571 } |
1557 return sent; | 1572 return sent; |
1558 } | 1573 } |
1559 | 1574 |
1560 } // namespace cricket | 1575 } // namespace cricket |
OLD | NEW |