Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: webrtc/p2p/base/port.cc

Issue 2163403002: Prepare for ICE-renomination (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Updated comments Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/port.h ('k') | webrtc/p2p/base/stun.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « webrtc/p2p/base/port.h ('k') | webrtc/p2p/base/stun.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698