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 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
747 } | 747 } |
748 uint32_t network_info = connection_->port()->Network()->id(); | 748 uint32_t network_info = connection_->port()->Network()->id(); |
749 network_info = (network_info << 16) | connection_->port()->network_cost(); | 749 network_info = (network_info << 16) | connection_->port()->network_cost(); |
750 request->AddAttribute( | 750 request->AddAttribute( |
751 new StunUInt32Attribute(STUN_ATTR_NETWORK_INFO, network_info)); | 751 new StunUInt32Attribute(STUN_ATTR_NETWORK_INFO, network_info)); |
752 | 752 |
753 // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role. | 753 // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role. |
754 if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) { | 754 if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) { |
755 request->AddAttribute(new StunUInt64Attribute( | 755 request->AddAttribute(new StunUInt64Attribute( |
756 STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker())); | 756 STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker())); |
757 // Since we are trying aggressive nomination, sending USE-CANDIDATE | 757 // We should really have either USE_CANDIDATE attribute or |
758 // attribute in every ping. | 758 // ICE_NOMINATION_VALUE attribute but not both. That was enforced in |
759 // If we are dealing with a ice-lite end point, nomination flag | 759 // p2ptransportchannel. |
760 // in Connection will be set to false by default. Once the connection | 760 // Note: This will keep on sending USE_CANDIDATE_ATTR on the selected |
761 // becomes "best connection", nomination flag will be turned on. | 761 // connection if peer does not support re-nomination. |
762 if (connection_->use_candidate_attr()) { | 762 if (connection_->use_candidate_attr()) { |
763 request->AddAttribute(new StunByteStringAttribute( | 763 request->AddAttribute(new StunByteStringAttribute( |
764 STUN_ATTR_USE_CANDIDATE)); | 764 STUN_ATTR_USE_CANDIDATE)); |
765 } | 765 } |
766 if (connection_->nominating_value() > 0 && | |
767 !connection_->nomination_acknowledged()) { | |
768 request->AddAttribute(new StunUInt32Attribute( | |
769 STUN_ATTR_NOMINATION_VALUE, connection_->nominating_value())); | |
770 } | |
766 } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) { | 771 } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) { |
767 request->AddAttribute(new StunUInt64Attribute( | 772 request->AddAttribute(new StunUInt64Attribute( |
768 STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker())); | 773 STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker())); |
769 } else { | 774 } else { |
770 ASSERT(false); | 775 ASSERT(false); |
771 } | 776 } |
772 | 777 |
773 // Adding PRIORITY Attribute. | 778 // Adding PRIORITY Attribute. |
774 // Changing the type preference to Peer Reflexive and local preference | 779 // Changing the type preference to Peer Reflexive and local preference |
775 // and component id information is unchanged from the original priority. | 780 // and component id information is unchanged from the original priority. |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
823 size_t index, | 828 size_t index, |
824 const Candidate& remote_candidate) | 829 const Candidate& remote_candidate) |
825 : port_(port), | 830 : port_(port), |
826 local_candidate_index_(index), | 831 local_candidate_index_(index), |
827 remote_candidate_(remote_candidate), | 832 remote_candidate_(remote_candidate), |
828 write_state_(STATE_WRITE_INIT), | 833 write_state_(STATE_WRITE_INIT), |
829 receiving_(false), | 834 receiving_(false), |
830 connected_(true), | 835 connected_(true), |
831 pruned_(false), | 836 pruned_(false), |
832 use_candidate_attr_(false), | 837 use_candidate_attr_(false), |
833 nominated_(false), | |
834 remote_ice_mode_(ICEMODE_FULL), | 838 remote_ice_mode_(ICEMODE_FULL), |
835 requests_(port->thread()), | 839 requests_(port->thread()), |
836 rtt_(DEFAULT_RTT), | 840 rtt_(DEFAULT_RTT), |
837 last_ping_sent_(0), | 841 last_ping_sent_(0), |
838 last_ping_received_(0), | 842 last_ping_received_(0), |
839 last_data_received_(0), | 843 last_data_received_(0), |
840 last_ping_response_received_(0), | 844 last_ping_response_received_(0), |
841 recv_rate_tracker_(100, 10u), | 845 recv_rate_tracker_(100, 10u), |
842 send_rate_tracker_(100, 10u), | 846 send_rate_tracker_(100, 10u), |
843 reported_(false), | 847 reported_(false), |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1034 | 1038 |
1035 // This is a validated stun request from remote peer. | 1039 // This is a validated stun request from remote peer. |
1036 port_->SendBindingResponse(msg, remote_addr); | 1040 port_->SendBindingResponse(msg, remote_addr); |
1037 | 1041 |
1038 // If it timed out on writing check, start up again | 1042 // If it timed out on writing check, start up again |
1039 if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) { | 1043 if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) { |
1040 set_write_state(STATE_WRITE_INIT); | 1044 set_write_state(STATE_WRITE_INIT); |
1041 } | 1045 } |
1042 | 1046 |
1043 if (port_->GetIceRole() == ICEROLE_CONTROLLED) { | 1047 if (port_->GetIceRole() == ICEROLE_CONTROLLED) { |
1044 const StunByteStringAttribute* use_candidate_attr = | 1048 const StunUInt32Attribute* nomination_value_attr = |
1045 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); | 1049 msg->GetUInt32(STUN_ATTR_NOMINATION_VALUE); |
1046 if (use_candidate_attr) { | 1050 int nomination_value = 0; |
1047 set_nominated(true); | 1051 if (nomination_value_attr) { |
1052 nomination_value = static_cast<int>(nomination_value_attr->value()); | |
1053 if (nomination_value < 0) { | |
1054 LOG(LS_ERROR) << "Negative nomination value: " << nomination_value; | |
1055 } | |
1056 } else { | |
1057 const StunByteStringAttribute* use_candidate_attr = | |
1058 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); | |
1059 if (use_candidate_attr) { | |
1060 nomination_value = 1; | |
1061 } | |
1062 } | |
1063 if (nomination_value > 0) { | |
1064 set_nominated_value(nomination_value); | |
1048 SignalNominated(this); | 1065 SignalNominated(this); |
1049 } | 1066 } |
1050 } | 1067 } |
1051 // Set the remote cost if the network_info attribute is available. | 1068 // Set the remote cost if the network_info attribute is available. |
1052 // Note: If packets are re-ordered, we may get incorrect network cost | 1069 // Note: If packets are re-ordered, we may get incorrect network cost |
1053 // temporarily, but it should get the correct value shortly after that. | 1070 // temporarily, but it should get the correct value shortly after that. |
1054 const StunUInt32Attribute* network_attr = | 1071 const StunUInt32Attribute* network_attr = |
1055 msg->GetUInt32(STUN_ATTR_NETWORK_INFO); | 1072 msg->GetUInt32(STUN_ATTR_NETWORK_INFO); |
1056 if (network_attr) { | 1073 if (network_attr) { |
1057 uint32_t network_info = network_attr->value(); | 1074 uint32_t network_info = network_attr->value(); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1171 // Update the receiving state. | 1188 // Update the receiving state. |
1172 UpdateReceiving(now); | 1189 UpdateReceiving(now); |
1173 if (dead(now)) { | 1190 if (dead(now)) { |
1174 Destroy(); | 1191 Destroy(); |
1175 } | 1192 } |
1176 } | 1193 } |
1177 | 1194 |
1178 void Connection::Ping(int64_t now) { | 1195 void Connection::Ping(int64_t now) { |
1179 last_ping_sent_ = now; | 1196 last_ping_sent_ = now; |
1180 ConnectionRequest *req = new ConnectionRequest(this); | 1197 ConnectionRequest *req = new ConnectionRequest(this); |
1181 pings_since_last_response_.push_back(SentPing(req->id(), now)); | 1198 pings_since_last_response_.push_back( |
1199 SentPing(req->id(), now, nominating_value_)); | |
1182 LOG_J(LS_VERBOSE, this) << "Sending STUN ping " | 1200 LOG_J(LS_VERBOSE, this) << "Sending STUN ping " |
1183 << ", id=" << rtc::hex_encode(req->id()); | 1201 << ", id=" << rtc::hex_encode(req->id()) |
1202 << ", nominating_value=" << nominating_value_; | |
1184 requests_.Send(req); | 1203 requests_.Send(req); |
1185 state_ = STATE_INPROGRESS; | 1204 state_ = STATE_INPROGRESS; |
1186 num_pings_sent_++; | 1205 num_pings_sent_++; |
1187 } | 1206 } |
1188 | 1207 |
1189 void Connection::ReceivedPing() { | 1208 void Connection::ReceivedPing() { |
1190 last_ping_received_ = rtc::TimeMillis(); | 1209 last_ping_received_ = rtc::TimeMillis(); |
1191 UpdateReceiving(last_ping_received_); | 1210 UpdateReceiving(last_ping_received_); |
1192 } | 1211 } |
1193 | 1212 |
1194 void Connection::ReceivedPingResponse(int rtt) { | 1213 void Connection::ReceivedPingResponse(int rtt, const std::string& request_id) { |
1195 // We've already validated that this is a STUN binding response with | 1214 // We've already validated that this is a STUN binding response with |
1196 // the correct local and remote username for this connection. | 1215 // the correct local and remote username for this connection. |
1197 // So if we're not already, become writable. We may be bringing a pruned | 1216 // So if we're not already, become writable. We may be bringing a pruned |
1198 // connection back to life, but if we don't really want it, we can always | 1217 // connection back to life, but if we don't really want it, we can always |
1199 // prune it again. | 1218 // prune it again. |
1219 if (!nomination_acknowledged_) { | |
1220 auto iter = std::find_if( | |
1221 pings_since_last_response_.begin(), pings_since_last_response_.end(), | |
1222 [request_id](const SentPing& ping) { return ping.id == request_id; }); | |
1223 if (iter != pings_since_last_response_.end() && | |
1224 iter->nomination_value == nominating_value_) { | |
1225 nomination_acknowledged_ = true; | |
1226 } | |
1227 } | |
1228 pings_since_last_response_.clear(); | |
1200 last_ping_response_received_ = rtc::TimeMillis(); | 1229 last_ping_response_received_ = rtc::TimeMillis(); |
1201 UpdateReceiving(last_ping_response_received_); | 1230 UpdateReceiving(last_ping_response_received_); |
1202 set_write_state(STATE_WRITABLE); | 1231 set_write_state(STATE_WRITABLE); |
1203 set_state(STATE_SUCCEEDED); | 1232 set_state(STATE_SUCCEEDED); |
1204 pings_since_last_response_.clear(); | |
1205 rtt_samples_++; | 1233 rtt_samples_++; |
1206 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); | 1234 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); |
1207 } | 1235 } |
1208 | 1236 |
1209 bool Connection::dead(int64_t now) const { | 1237 bool Connection::dead(int64_t now) const { |
1210 if (last_received() > 0) { | 1238 if (last_received() > 0) { |
1211 // If it has ever received anything, we keep it alive until it hasn't | 1239 // If it has ever received anything, we keep it alive until it hasn't |
1212 // received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT. This covers the | 1240 // received anything for DEAD_CONNECTION_RECEIVE_TIMEOUT. This covers the |
1213 // normal case of a successfully used connection that stops working. This | 1241 // normal case of a successfully used connection that stops working. This |
1214 // also allows a remote peer to continue pinging over a locally inactive | 1242 // 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... | |
1267 }; | 1295 }; |
1268 const std::string ICESTATE[4] = { | 1296 const std::string ICESTATE[4] = { |
1269 "W", // STATE_WAITING | 1297 "W", // STATE_WAITING |
1270 "I", // STATE_INPROGRESS | 1298 "I", // STATE_INPROGRESS |
1271 "S", // STATE_SUCCEEDED | 1299 "S", // STATE_SUCCEEDED |
1272 "F" // STATE_FAILED | 1300 "F" // STATE_FAILED |
1273 }; | 1301 }; |
1274 const Candidate& local = local_candidate(); | 1302 const Candidate& local = local_candidate(); |
1275 const Candidate& remote = remote_candidate(); | 1303 const Candidate& remote = remote_candidate(); |
1276 std::stringstream ss; | 1304 std::stringstream ss; |
1277 ss << "Conn[" << ToDebugId() | 1305 ss << "Conn[" << ToDebugId() << ":" << port_->content_name() << ":" |
1278 << ":" << port_->content_name() | 1306 << local.id() << ":" << local.component() << ":" << local.generation() |
1279 << ":" << local.id() << ":" << local.component() | 1307 << ":" << local.type() << ":" << local.protocol() << ":" |
1280 << ":" << local.generation() | 1308 << local.address().ToSensitiveString() << "->" << remote.id() << ":" |
1281 << ":" << local.type() << ":" << local.protocol() | 1309 << remote.component() << ":" << remote.priority() << ":" << remote.type() |
1282 << ":" << local.address().ToSensitiveString() | 1310 << ":" << remote.protocol() << ":" << remote.address().ToSensitiveString() |
1283 << "->" << remote.id() << ":" << remote.component() | 1311 << "|" << CONNECT_STATE_ABBREV[connected()] |
1284 << ":" << remote.priority() | 1312 << RECEIVE_STATE_ABBREV[receiving()] << WRITE_STATE_ABBREV[write_state()] |
1285 << ":" << remote.type() << ":" | 1313 << ICESTATE[state()] << "|" << nominated_value() << "|" << priority() |
Taylor Brandstetter
2016/07/22 17:36:01
It seems like nominating_value would also be usefu
honghaiz3
2016/07/22 22:50:11
nominating_value_ could change dynamically.
Basic
Taylor Brandstetter
2016/07/22 23:48:28
I don't see where nominating_value_ is set to 0. A
honghaiz3
2016/07/25 22:24:40
Hope this is clearer now with the updated CL.
Taylor Brandstetter
2016/07/27 22:20:55
I see that in the updated CL, the nominating value
| |
1286 << remote.protocol() << ":" << remote.address().ToSensitiveString() << "|" | 1314 << "|"; |
1287 << CONNECT_STATE_ABBREV[connected()] | |
1288 << RECEIVE_STATE_ABBREV[receiving()] | |
1289 << WRITE_STATE_ABBREV[write_state()] | |
1290 << ICESTATE[state()] << "|" | |
1291 << priority() << "|"; | |
1292 if (rtt_ < DEFAULT_RTT) { | 1315 if (rtt_ < DEFAULT_RTT) { |
1293 ss << rtt_ << "]"; | 1316 ss << rtt_ << "]"; |
1294 } else { | 1317 } else { |
1295 ss << "-]"; | 1318 ss << "-]"; |
1296 } | 1319 } |
1297 return ss.str(); | 1320 return ss.str(); |
1298 } | 1321 } |
1299 | 1322 |
1300 std::string Connection::ToSensitiveString() const { | 1323 std::string Connection::ToSensitiveString() const { |
1301 return ToString(); | 1324 return ToString(); |
1302 } | 1325 } |
1303 | 1326 |
1304 void Connection::OnConnectionRequestResponse(ConnectionRequest* request, | 1327 void Connection::OnConnectionRequestResponse(ConnectionRequest* request, |
1305 StunMessage* response) { | 1328 StunMessage* response) { |
1306 // Log at LS_INFO if we receive a ping response on an unwritable | 1329 // Log at LS_INFO if we receive a ping response on an unwritable |
1307 // connection. | 1330 // connection. |
1308 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; | 1331 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; |
1309 | 1332 |
1310 int rtt = request->Elapsed(); | 1333 int rtt = request->Elapsed(); |
1311 | 1334 |
1312 ReceivedPingResponse(rtt); | |
1313 | |
1314 if (LOG_CHECK_LEVEL_V(sev)) { | 1335 if (LOG_CHECK_LEVEL_V(sev)) { |
1315 bool use_candidate = ( | |
1316 response->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr); | |
1317 std::string pings; | 1336 std::string pings; |
1318 PrintPingsSinceLastResponse(&pings, 5); | 1337 PrintPingsSinceLastResponse(&pings, 5); |
1319 LOG_JV(sev, this) << "Received STUN ping response" | 1338 LOG_JV(sev, this) << "Received STUN ping response" |
1320 << ", id=" << rtc::hex_encode(request->id()) | 1339 << ", id=" << rtc::hex_encode(request->id()) |
1321 << ", code=0" // Makes logging easier to parse. | 1340 << ", code=0" // Makes logging easier to parse. |
1322 << ", rtt=" << rtt | 1341 << ", rtt=" << rtt |
1323 << ", use_candidate=" << use_candidate | |
Taylor Brandstetter
2016/07/22 17:36:01
Can we log both use_candidate and nominating_value
honghaiz3
2016/07/22 22:50:11
This is in the PingResponse.
We don't send use_ca
Taylor Brandstetter
2016/07/22 23:48:28
Acknowledged.
honghaiz3
2016/07/25 22:24:40
Acknowledged.
| |
1324 << ", pings_since_last_response=" << pings; | 1342 << ", pings_since_last_response=" << pings; |
1325 } | 1343 } |
1344 ReceivedPingResponse(rtt, request->id()); | |
1326 | 1345 |
1327 stats_.recv_ping_responses++; | 1346 stats_.recv_ping_responses++; |
1328 | 1347 |
1329 MaybeAddPrflxCandidate(request, response); | 1348 MaybeAddPrflxCandidate(request, response); |
1330 } | 1349 } |
1331 | 1350 |
1332 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, | 1351 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, |
1333 StunMessage* response) { | 1352 StunMessage* response) { |
1334 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); | 1353 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); |
1335 int error_code = STUN_ERROR_GLOBAL_FAILURE; | 1354 int error_code = STUN_ERROR_GLOBAL_FAILURE; |
(...skipping 26 matching lines...) Expand all Loading... | |
1362 // Log at LS_INFO if we miss a ping on a writable connection. | 1381 // Log at LS_INFO if we miss a ping on a writable connection. |
1363 rtc::LoggingSeverity sev = writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; | 1382 rtc::LoggingSeverity sev = writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; |
1364 LOG_JV(sev, this) << "Timing-out STUN ping " | 1383 LOG_JV(sev, this) << "Timing-out STUN ping " |
1365 << rtc::hex_encode(request->id()) | 1384 << rtc::hex_encode(request->id()) |
1366 << " after " << request->Elapsed() << " ms"; | 1385 << " after " << request->Elapsed() << " ms"; |
1367 } | 1386 } |
1368 | 1387 |
1369 void Connection::OnConnectionRequestSent(ConnectionRequest* request) { | 1388 void Connection::OnConnectionRequestSent(ConnectionRequest* request) { |
1370 // Log at LS_INFO if we send a ping on an unwritable connection. | 1389 // Log at LS_INFO if we send a ping on an unwritable connection. |
1371 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; | 1390 rtc::LoggingSeverity sev = !writable() ? rtc::LS_INFO : rtc::LS_VERBOSE; |
1372 bool use_candidate = use_candidate_attr(); | |
1373 LOG_JV(sev, this) << "Sent STUN ping" | 1391 LOG_JV(sev, this) << "Sent STUN ping" |
1374 << ", id=" << rtc::hex_encode(request->id()) | 1392 << ", id=" << rtc::hex_encode(request->id()) |
1375 << ", use_candidate=" << use_candidate; | 1393 << ", use_candidate=" << use_candidate_attr() |
1394 << ", nominating value=" << nominating_value(); | |
1376 stats_.sent_ping_requests_total++; | 1395 stats_.sent_ping_requests_total++; |
1377 if (stats_.recv_ping_responses == 0) { | 1396 if (stats_.recv_ping_responses == 0) { |
1378 stats_.sent_ping_requests_before_first_response++; | 1397 stats_.sent_ping_requests_before_first_response++; |
1379 } | 1398 } |
1380 } | 1399 } |
1381 | 1400 |
1382 void Connection::HandleRoleConflictFromPeer() { | 1401 void Connection::HandleRoleConflictFromPeer() { |
1383 port_->SignalRoleConflict(port_); | 1402 port_->SignalRoleConflict(port_); |
1384 } | 1403 } |
1385 | 1404 |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1530 ASSERT(sent < 0); | 1549 ASSERT(sent < 0); |
1531 error_ = port_->GetError(); | 1550 error_ = port_->GetError(); |
1532 stats_.sent_discarded_packets++; | 1551 stats_.sent_discarded_packets++; |
1533 } else { | 1552 } else { |
1534 send_rate_tracker_.AddSamples(sent); | 1553 send_rate_tracker_.AddSamples(sent); |
1535 } | 1554 } |
1536 return sent; | 1555 return sent; |
1537 } | 1556 } |
1538 | 1557 |
1539 } // namespace cricket | 1558 } // namespace cricket |
OLD | NEW |