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

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

Issue 2063823008: Adding IceConfig option to assume TURN/TURN candidate pairs will work. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Responding to comments. Doing "presumed writable" determination in Connection. Created 4 years, 6 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
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 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 private: 818 private:
819 Connection* connection_; 819 Connection* connection_;
820 }; 820 };
821 821
822 // 822 //
823 // Connection 823 // Connection
824 // 824 //
825 825
826 Connection::Connection(Port* port, 826 Connection::Connection(Port* port,
827 size_t index, 827 size_t index,
828 const Candidate& remote_candidate) 828 const Candidate& remote_candidate,
829 const IceConfig& config)
829 : port_(port), 830 : port_(port),
830 local_candidate_index_(index), 831 local_candidate_index_(index),
831 remote_candidate_(remote_candidate), 832 remote_candidate_(remote_candidate),
832 write_state_(STATE_WRITE_INIT),
833 receiving_(false), 833 receiving_(false),
834 connected_(true), 834 connected_(true),
835 pruned_(false), 835 pruned_(false),
836 use_candidate_attr_(false), 836 use_candidate_attr_(false),
837 nominated_(false), 837 nominated_(false),
838 remote_ice_mode_(ICEMODE_FULL), 838 remote_ice_mode_(ICEMODE_FULL),
839 requests_(port->thread()), 839 requests_(port->thread()),
840 rtt_(DEFAULT_RTT), 840 rtt_(DEFAULT_RTT),
841 last_ping_sent_(0), 841 last_ping_sent_(0),
842 last_ping_received_(0), 842 last_ping_received_(0),
843 last_data_received_(0), 843 last_data_received_(0),
844 last_ping_response_received_(0), 844 last_ping_response_received_(0),
845 recv_rate_tracker_(100, 10u), 845 recv_rate_tracker_(100, 10u),
846 send_rate_tracker_(100, 10u), 846 send_rate_tracker_(100, 10u),
847 reported_(false), 847 reported_(false),
848 state_(STATE_WAITING), 848 state_(STATE_WAITING),
849 receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT), 849 receiving_timeout_(WEAK_CONNECTION_RECEIVE_TIMEOUT),
850 time_created_ms_(rtc::TimeMillis()) { 850 time_created_ms_(rtc::TimeMillis()),
851 fully_relayed_createpermission_needed_(
852 config.fully_relayed_createpermission_needed) {
851 // All of our connections start in WAITING state. 853 // All of our connections start in WAITING state.
852 // TODO(mallinath) - Start connections from STATE_FROZEN. 854 // TODO(mallinath) - Start connections from STATE_FROZEN.
855 write_state_ = InitialWriteState();
honghaiz3 2016/06/17 16:22:07 Instead of setting the write_state_ every time it
Taylor Brandstetter 2016/06/20 17:15:45 Isn't that effectively the same as having two enum
honghaiz3 2016/06/20 22:31:03 Which method will return four possible values? My
pthatcher1 2016/06/21 06:20:50 I's like having one internal enum with 4 values an
pthatcher1 2016/06/21 06:20:50 No, I think it would go to INIT (it would eventual
honghaiz3 2016/06/21 19:37:57 Ah. You are right. I thought of presumed_writable
Taylor Brandstetter 2016/06/22 00:37:07 I'm completely confused. Peter, the reason I did t
pthatcher1 2016/06/22 05:46:13 Sorry for the confusion.I like having one enum. W
Taylor Brandstetter 2016/06/22 15:34:43 That's effectively the same as having two enums, a
853 // Wire up to send stun packets 856 // Wire up to send stun packets
854 requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket); 857 requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket);
855 LOG_J(LS_INFO, this) << "Connection created"; 858 LOG_J(LS_INFO, this) << "Connection created";
856 } 859 }
857 860
858 Connection::~Connection() { 861 Connection::~Connection() {
859 } 862 }
860 863
861 const Candidate& Connection::local_candidate() const { 864 const Candidate& Connection::local_candidate() const {
862 ASSERT(local_candidate_index_ < port_->Candidates().size()); 865 ASSERT(local_candidate_index_ < port_->Candidates().size());
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 if (!port_->GetStunMessage(data, size, addr, &msg, &remote_ufrag)) { 954 if (!port_->GetStunMessage(data, size, addr, &msg, &remote_ufrag)) {
952 // The packet did not parse as a valid STUN message 955 // The packet did not parse as a valid STUN message
953 // This is a data packet, pass it along. 956 // This is a data packet, pass it along.
954 set_receiving(true); 957 set_receiving(true);
955 last_data_received_ = rtc::TimeMillis(); 958 last_data_received_ = rtc::TimeMillis();
956 recv_rate_tracker_.AddSamples(size); 959 recv_rate_tracker_.AddSamples(size);
957 SignalReadPacket(this, data, size, packet_time); 960 SignalReadPacket(this, data, size, packet_time);
958 961
959 // If timed out sending writability checks, start up again 962 // If timed out sending writability checks, start up again
960 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) { 963 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) {
964 set_write_state(InitialWriteState());
961 LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. " 965 LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. "
962 << "Resetting state to STATE_WRITE_INIT."; 966 << "Reset state to " << write_state_ << ".";
963 set_write_state(STATE_WRITE_INIT);
964 } 967 }
965 } else if (!msg) { 968 } else if (!msg) {
966 // The packet was STUN, but failed a check and was handled internally. 969 // The packet was STUN, but failed a check and was handled internally.
967 } else { 970 } else {
968 // The packet is STUN and passed the Port checks. 971 // The packet is STUN and passed the Port checks.
969 // Perform our own checks to ensure this packet is valid. 972 // Perform our own checks to ensure this packet is valid.
970 // If this is a STUN request, then update the receiving bit and respond. 973 // If this is a STUN request, then update the receiving bit and respond.
971 // If this is a STUN response, then update the writable bit. 974 // If this is a STUN response, then update the writable bit.
972 // Log at LS_INFO if we receive a ping on an unwritable connection. 975 // Log at LS_INFO if we receive a ping on an unwritable connection.
973 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE); 976 rtc::LoggingSeverity sev = (!writable() ? rtc::LS_INFO : rtc::LS_VERBOSE);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 return; 1033 return;
1031 } 1034 }
1032 1035
1033 stats_.recv_ping_requests++; 1036 stats_.recv_ping_requests++;
1034 1037
1035 // This is a validated stun request from remote peer. 1038 // This is a validated stun request from remote peer.
1036 port_->SendBindingResponse(msg, remote_addr); 1039 port_->SendBindingResponse(msg, remote_addr);
1037 1040
1038 // If it timed out on writing check, start up again 1041 // If it timed out on writing check, start up again
1039 if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) { 1042 if (!pruned_ && write_state_ == STATE_WRITE_TIMEOUT) {
1040 set_write_state(STATE_WRITE_INIT); 1043 set_write_state(InitialWriteState());
1041 } 1044 }
1042 1045
1043 if (port_->GetIceRole() == ICEROLE_CONTROLLED) { 1046 if (port_->GetIceRole() == ICEROLE_CONTROLLED) {
1044 const StunByteStringAttribute* use_candidate_attr = 1047 const StunByteStringAttribute* use_candidate_attr =
1045 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); 1048 msg->GetByteString(STUN_ATTR_USE_CANDIDATE);
1046 if (use_candidate_attr) { 1049 if (use_candidate_attr) {
1047 set_nominated(true); 1050 set_nominated(true);
1048 SignalNominated(this); 1051 SignalNominated(this);
1049 } 1052 }
1050 } 1053 }
1051 // Set the remote cost if the network_info attribute is available. 1054 // Set the remote cost if the network_info attribute is available.
1052 // Note: If packets are re-ordered, we may get incorrect network cost 1055 // Note: If packets are re-ordered, we may get incorrect network cost
1053 // temporarily, but it should get the correct value shortly after that. 1056 // temporarily, but it should get the correct value shortly after that.
1054 const StunUInt32Attribute* network_attr = 1057 const StunUInt32Attribute* network_attr =
1055 msg->GetUInt32(STUN_ATTR_NETWORK_INFO); 1058 msg->GetUInt32(STUN_ATTR_NETWORK_INFO);
1056 if (network_attr) { 1059 if (network_attr) {
1057 uint32_t network_info = network_attr->value(); 1060 uint32_t network_info = network_attr->value();
1058 uint16_t network_cost = static_cast<uint16_t>(network_info); 1061 uint16_t network_cost = static_cast<uint16_t>(network_info);
1059 if (network_cost != remote_candidate_.network_cost()) { 1062 if (network_cost != remote_candidate_.network_cost()) {
1060 remote_candidate_.set_network_cost(network_cost); 1063 remote_candidate_.set_network_cost(network_cost);
1061 // Network cost change will affect the connection ranking, so signal 1064 // Network cost change will affect the connection ranking, so signal
1062 // state change to force a re-sort in P2PTransportChannel. 1065 // state change to force a re-sort in P2PTransportChannel.
1063 SignalStateChange(this); 1066 SignalStateChange(this);
1064 } 1067 }
1065 } 1068 }
1066 } 1069 }
1067 1070
1068 void Connection::OnReadyToSend() { 1071 void Connection::OnReadyToSend() {
1069 if (write_state_ == STATE_WRITABLE) { 1072 if (presumed_writable()) {
1070 SignalReadyToSend(this); 1073 SignalReadyToSend(this);
1071 } 1074 }
1072 } 1075 }
1073 1076
1074 void Connection::Prune() { 1077 void Connection::Prune() {
1075 if (!pruned_ || active()) { 1078 if (!pruned_ || active()) {
1076 LOG_J(LS_INFO, this) << "Connection pruned"; 1079 LOG_J(LS_INFO, this) << "Connection pruned";
1077 pruned_ = true; 1080 pruned_ = true;
1078 requests_.Clear(); 1081 requests_.Clear();
1079 set_write_state(STATE_WRITE_TIMEOUT); 1082 set_write_state(STATE_WRITE_TIMEOUT);
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1239 1242
1240 std::string Connection::ToString() const { 1243 std::string Connection::ToString() const {
1241 const char CONNECT_STATE_ABBREV[2] = { 1244 const char CONNECT_STATE_ABBREV[2] = {
1242 '-', // not connected (false) 1245 '-', // not connected (false)
1243 'C', // connected (true) 1246 'C', // connected (true)
1244 }; 1247 };
1245 const char RECEIVE_STATE_ABBREV[2] = { 1248 const char RECEIVE_STATE_ABBREV[2] = {
1246 '-', // not receiving (false) 1249 '-', // not receiving (false)
1247 'R', // receiving (true) 1250 'R', // receiving (true)
1248 }; 1251 };
1249 const char WRITE_STATE_ABBREV[4] = { 1252 const char WRITE_STATE_ABBREV[5] = {
1250 'W', // STATE_WRITABLE 1253 'W', // STATE_WRITABLE
1251 'w', // STATE_WRITE_UNRELIABLE 1254 'P', // STATE_PRESUMED_WRITABLE
1252 '-', // STATE_WRITE_INIT 1255 'w', // STATE_WRITE_UNRELIABLE
1253 'x', // STATE_WRITE_TIMEOUT 1256 '-', // STATE_WRITE_INIT
1257 'x', // STATE_WRITE_TIMEOUT
1254 }; 1258 };
1255 const std::string ICESTATE[4] = { 1259 const std::string ICESTATE[4] = {
1256 "W", // STATE_WAITING 1260 "W", // STATE_WAITING
1257 "I", // STATE_INPROGRESS 1261 "I", // STATE_INPROGRESS
1258 "S", // STATE_SUCCEEDED 1262 "S", // STATE_SUCCEEDED
1259 "F" // STATE_FAILED 1263 "F" // STATE_FAILED
1260 }; 1264 };
1261 const Candidate& local = local_candidate(); 1265 const Candidate& local = local_candidate();
1262 const Candidate& remote = remote_candidate(); 1266 const Candidate& remote = remote_candidate();
1263 std::stringstream ss; 1267 std::stringstream ss;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1360 bool use_candidate = use_candidate_attr(); 1364 bool use_candidate = use_candidate_attr();
1361 LOG_JV(sev, this) << "Sent STUN ping" 1365 LOG_JV(sev, this) << "Sent STUN ping"
1362 << ", id=" << rtc::hex_encode(request->id()) 1366 << ", id=" << rtc::hex_encode(request->id())
1363 << ", use_candidate=" << use_candidate; 1367 << ", use_candidate=" << use_candidate;
1364 stats_.sent_ping_requests_total++; 1368 stats_.sent_ping_requests_total++;
1365 if (stats_.recv_ping_responses == 0) { 1369 if (stats_.recv_ping_responses == 0) {
1366 stats_.sent_ping_requests_before_first_response++; 1370 stats_.sent_ping_requests_before_first_response++;
1367 } 1371 }
1368 } 1372 }
1369 1373
1374 Connection::WriteState Connection::InitialWriteState() const {
1375 if (!fully_relayed_createpermission_needed_ &&
1376 local_candidate().type() == RELAY_PORT_TYPE &&
1377 remote_candidate().type() == RELAY_PORT_TYPE) {
1378 return STATE_PRESUMED_WRITABLE;
1379 }
1380 return STATE_WRITE_INIT;
1381 }
1382
1370 void Connection::HandleRoleConflictFromPeer() { 1383 void Connection::HandleRoleConflictFromPeer() {
1371 port_->SignalRoleConflict(port_); 1384 port_->SignalRoleConflict(port_);
1372 } 1385 }
1373 1386
1374 void Connection::MaybeSetRemoteIceCredentialsAndGeneration( 1387 void Connection::MaybeSetRemoteIceCredentialsAndGeneration(
1375 const std::string& ice_ufrag, 1388 const std::string& ice_ufrag,
1376 const std::string& ice_pwd, 1389 const std::string& ice_pwd,
1377 int generation) { 1390 int generation) {
1378 if (remote_candidate_.username() == ice_ufrag && 1391 if (remote_candidate_.username() == ice_ufrag &&
1379 remote_candidate_.password().empty()) { 1392 remote_candidate_.password().empty()) {
(...skipping 12 matching lines...) Expand all
1392 void Connection::MaybeUpdatePeerReflexiveCandidate( 1405 void Connection::MaybeUpdatePeerReflexiveCandidate(
1393 const Candidate& new_candidate) { 1406 const Candidate& new_candidate) {
1394 if (remote_candidate_.type() == PRFLX_PORT_TYPE && 1407 if (remote_candidate_.type() == PRFLX_PORT_TYPE &&
1395 new_candidate.type() != PRFLX_PORT_TYPE && 1408 new_candidate.type() != PRFLX_PORT_TYPE &&
1396 remote_candidate_.protocol() == new_candidate.protocol() && 1409 remote_candidate_.protocol() == new_candidate.protocol() &&
1397 remote_candidate_.address() == new_candidate.address() && 1410 remote_candidate_.address() == new_candidate.address() &&
1398 remote_candidate_.username() == new_candidate.username() && 1411 remote_candidate_.username() == new_candidate.username() &&
1399 remote_candidate_.password() == new_candidate.password() && 1412 remote_candidate_.password() == new_candidate.password() &&
1400 remote_candidate_.generation() == new_candidate.generation()) { 1413 remote_candidate_.generation() == new_candidate.generation()) {
1401 remote_candidate_ = new_candidate; 1414 remote_candidate_ = new_candidate;
1415 // If it turns out that the peer reflexive candidate was a TURN candidate,
1416 // we may need to change the state to STATE_PRESUMED_WRITABLE.
1417 if (write_state() == STATE_WRITE_INIT) {
1418 set_write_state(InitialWriteState());
1419 }
pthatcher1 2016/06/16 23:31:36 Oh, this is a good point. It would be faster if w
Taylor Brandstetter 2016/06/20 17:15:45 But we don't know that the prflx candidate is a TU
pthatcher1 2016/06/21 06:20:50 I don't think it's risky to presume a TURN<->PRFLX
Taylor Brandstetter 2016/06/22 00:37:07 The outgoing pings won't be delayed. Just the outg
pthatcher1 2016/06/22 05:46:13 Sorry, you're right. I meant the outgoing dtls/me
1402 } 1420 }
1403 } 1421 }
1404 1422
1405 void Connection::OnMessage(rtc::Message *pmsg) { 1423 void Connection::OnMessage(rtc::Message *pmsg) {
1406 ASSERT(pmsg->message_id == MSG_DELETE); 1424 ASSERT(pmsg->message_id == MSG_DELETE);
1407 LOG(LS_INFO) << "Connection deleted with number of pings sent: " 1425 LOG(LS_INFO) << "Connection deleted with number of pings sent: "
1408 << num_pings_sent_; 1426 << num_pings_sent_;
1409 SignalDestroyed(this); 1427 SignalDestroyed(this);
1410 delete this; 1428 delete this;
1411 } 1429 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 // Change the local candidate of this Connection to the new prflx candidate. 1503 // Change the local candidate of this Connection to the new prflx candidate.
1486 local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate); 1504 local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate);
1487 1505
1488 // SignalStateChange to force a re-sort in P2PTransportChannel as this 1506 // SignalStateChange to force a re-sort in P2PTransportChannel as this
1489 // Connection's local candidate has changed. 1507 // Connection's local candidate has changed.
1490 SignalStateChange(this); 1508 SignalStateChange(this);
1491 } 1509 }
1492 1510
1493 ProxyConnection::ProxyConnection(Port* port, 1511 ProxyConnection::ProxyConnection(Port* port,
1494 size_t index, 1512 size_t index,
1495 const Candidate& remote_candidate) 1513 const Candidate& remote_candidate,
1496 : Connection(port, index, remote_candidate) {} 1514 const IceConfig& config)
1515 : Connection(port, index, remote_candidate, config) {}
1497 1516
1498 int ProxyConnection::Send(const void* data, size_t size, 1517 int ProxyConnection::Send(const void* data, size_t size,
1499 const rtc::PacketOptions& options) { 1518 const rtc::PacketOptions& options) {
1500 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) { 1519 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) {
1501 error_ = EWOULDBLOCK; 1520 error_ = EWOULDBLOCK;
1502 return SOCKET_ERROR; 1521 return SOCKET_ERROR;
1503 } 1522 }
1504 stats_.sent_total_packets++; 1523 stats_.sent_total_packets++;
1505 int sent = port_->SendTo(data, size, remote_candidate_.address(), 1524 int sent = port_->SendTo(data, size, remote_candidate_.address(),
1506 options, true); 1525 options, true);
1507 if (sent <= 0) { 1526 if (sent <= 0) {
1508 ASSERT(sent < 0); 1527 ASSERT(sent < 0);
1509 error_ = port_->GetError(); 1528 error_ = port_->GetError();
1510 stats_.sent_discarded_packets++; 1529 stats_.sent_discarded_packets++;
1511 } else { 1530 } else {
1512 send_rate_tracker_.AddSamples(sent); 1531 send_rate_tracker_.AddSamples(sent);
1513 } 1532 }
1514 return sent; 1533 return sent;
1515 } 1534 }
1516 1535
1517 } // namespace cricket 1536 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698