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 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 presume_writable_when_fully_relayed_( |
| 852 config.presume_writable_when_fully_relayed) { |
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(); |
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 Loading... |
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 Loading... |
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 | 1127 |
1125 // Check the writable state. (The order of these checks is important.) | 1128 // Check the writable state. (The order of these checks is important.) |
1126 // | 1129 // |
1127 // Before becoming unwritable, we allow for a fixed number of pings to fail | 1130 // Before becoming unwritable, we allow for a fixed number of pings to fail |
1128 // (i.e., receive no response). We also have to give the response time to | 1131 // (i.e., receive no response). We also have to give the response time to |
1129 // get back, so we include a conservative estimate of this. | 1132 // get back, so we include a conservative estimate of this. |
1130 // | 1133 // |
1131 // Before timing out writability, we give a fixed amount of time. This is to | 1134 // Before timing out writability, we give a fixed amount of time. This is to |
1132 // allow for changes in network conditions. | 1135 // allow for changes in network conditions. |
1133 | 1136 |
1134 if ((write_state_ == STATE_WRITABLE) && | 1137 if (presumed_writable() && |
1135 TooManyFailures(pings_since_last_response_, | 1138 TooManyFailures(pings_since_last_response_, |
1136 CONNECTION_WRITE_CONNECT_FAILURES, | 1139 CONNECTION_WRITE_CONNECT_FAILURES, rtt, now) && |
1137 rtt, | |
1138 now) && | |
1139 TooLongWithoutResponse(pings_since_last_response_, | 1140 TooLongWithoutResponse(pings_since_last_response_, |
1140 CONNECTION_WRITE_CONNECT_TIMEOUT, | 1141 CONNECTION_WRITE_CONNECT_TIMEOUT, now)) { |
1141 now)) { | |
1142 uint32_t max_pings = CONNECTION_WRITE_CONNECT_FAILURES; | 1142 uint32_t max_pings = CONNECTION_WRITE_CONNECT_FAILURES; |
1143 LOG_J(LS_INFO, this) << "Unwritable after " << max_pings | 1143 LOG_J(LS_INFO, this) << "Unwritable after " << max_pings |
1144 << " ping failures and " | 1144 << " ping failures and " |
1145 << now - pings_since_last_response_[0].sent_time | 1145 << now - pings_since_last_response_[0].sent_time |
1146 << " ms without a response," | 1146 << " ms without a response," |
1147 << " ms since last received ping=" | 1147 << " ms since last received ping=" |
1148 << now - last_ping_received_ | 1148 << now - last_ping_received_ |
1149 << " ms since last received data=" | 1149 << " ms since last received data=" |
1150 << now - last_data_received_ | 1150 << now - last_data_received_ |
1151 << " rtt=" << rtt; | 1151 << " rtt=" << rtt; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 | 1239 |
1240 std::string Connection::ToString() const { | 1240 std::string Connection::ToString() const { |
1241 const char CONNECT_STATE_ABBREV[2] = { | 1241 const char CONNECT_STATE_ABBREV[2] = { |
1242 '-', // not connected (false) | 1242 '-', // not connected (false) |
1243 'C', // connected (true) | 1243 'C', // connected (true) |
1244 }; | 1244 }; |
1245 const char RECEIVE_STATE_ABBREV[2] = { | 1245 const char RECEIVE_STATE_ABBREV[2] = { |
1246 '-', // not receiving (false) | 1246 '-', // not receiving (false) |
1247 'R', // receiving (true) | 1247 'R', // receiving (true) |
1248 }; | 1248 }; |
1249 const char WRITE_STATE_ABBREV[4] = { | 1249 const char WRITE_STATE_ABBREV[5] = { |
1250 'W', // STATE_WRITABLE | 1250 'W', // STATE_WRITABLE |
1251 'w', // STATE_WRITE_UNRELIABLE | 1251 'P', // STATE_PRESUMED_WRITABLE |
1252 '-', // STATE_WRITE_INIT | 1252 'w', // STATE_WRITE_UNRELIABLE |
1253 'x', // STATE_WRITE_TIMEOUT | 1253 '-', // STATE_WRITE_INIT |
| 1254 'x', // STATE_WRITE_TIMEOUT |
1254 }; | 1255 }; |
1255 const std::string ICESTATE[4] = { | 1256 const std::string ICESTATE[4] = { |
1256 "W", // STATE_WAITING | 1257 "W", // STATE_WAITING |
1257 "I", // STATE_INPROGRESS | 1258 "I", // STATE_INPROGRESS |
1258 "S", // STATE_SUCCEEDED | 1259 "S", // STATE_SUCCEEDED |
1259 "F" // STATE_FAILED | 1260 "F" // STATE_FAILED |
1260 }; | 1261 }; |
1261 const Candidate& local = local_candidate(); | 1262 const Candidate& local = local_candidate(); |
1262 const Candidate& remote = remote_candidate(); | 1263 const Candidate& remote = remote_candidate(); |
1263 std::stringstream ss; | 1264 std::stringstream ss; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 bool use_candidate = use_candidate_attr(); | 1361 bool use_candidate = use_candidate_attr(); |
1361 LOG_JV(sev, this) << "Sent STUN ping" | 1362 LOG_JV(sev, this) << "Sent STUN ping" |
1362 << ", id=" << rtc::hex_encode(request->id()) | 1363 << ", id=" << rtc::hex_encode(request->id()) |
1363 << ", use_candidate=" << use_candidate; | 1364 << ", use_candidate=" << use_candidate; |
1364 stats_.sent_ping_requests_total++; | 1365 stats_.sent_ping_requests_total++; |
1365 if (stats_.recv_ping_responses == 0) { | 1366 if (stats_.recv_ping_responses == 0) { |
1366 stats_.sent_ping_requests_before_first_response++; | 1367 stats_.sent_ping_requests_before_first_response++; |
1367 } | 1368 } |
1368 } | 1369 } |
1369 | 1370 |
| 1371 Connection::WriteState Connection::InitialWriteState() const { |
| 1372 if (presume_writable_when_fully_relayed_ && |
| 1373 local_candidate().type() == RELAY_PORT_TYPE && |
| 1374 (remote_candidate().type() == RELAY_PORT_TYPE || |
| 1375 remote_candidate().type() == PRFLX_PORT_TYPE)) { |
| 1376 return STATE_PRESUMED_WRITABLE; |
| 1377 } |
| 1378 return STATE_WRITE_INIT; |
| 1379 } |
| 1380 |
1370 void Connection::HandleRoleConflictFromPeer() { | 1381 void Connection::HandleRoleConflictFromPeer() { |
1371 port_->SignalRoleConflict(port_); | 1382 port_->SignalRoleConflict(port_); |
1372 } | 1383 } |
1373 | 1384 |
1374 void Connection::MaybeSetRemoteIceCredentialsAndGeneration( | 1385 void Connection::MaybeSetRemoteIceCredentialsAndGeneration( |
1375 const std::string& ice_ufrag, | 1386 const std::string& ice_ufrag, |
1376 const std::string& ice_pwd, | 1387 const std::string& ice_pwd, |
1377 int generation) { | 1388 int generation) { |
1378 if (remote_candidate_.username() == ice_ufrag && | 1389 if (remote_candidate_.username() == ice_ufrag && |
1379 remote_candidate_.password().empty()) { | 1390 remote_candidate_.password().empty()) { |
(...skipping 12 matching lines...) Expand all Loading... |
1392 void Connection::MaybeUpdatePeerReflexiveCandidate( | 1403 void Connection::MaybeUpdatePeerReflexiveCandidate( |
1393 const Candidate& new_candidate) { | 1404 const Candidate& new_candidate) { |
1394 if (remote_candidate_.type() == PRFLX_PORT_TYPE && | 1405 if (remote_candidate_.type() == PRFLX_PORT_TYPE && |
1395 new_candidate.type() != PRFLX_PORT_TYPE && | 1406 new_candidate.type() != PRFLX_PORT_TYPE && |
1396 remote_candidate_.protocol() == new_candidate.protocol() && | 1407 remote_candidate_.protocol() == new_candidate.protocol() && |
1397 remote_candidate_.address() == new_candidate.address() && | 1408 remote_candidate_.address() == new_candidate.address() && |
1398 remote_candidate_.username() == new_candidate.username() && | 1409 remote_candidate_.username() == new_candidate.username() && |
1399 remote_candidate_.password() == new_candidate.password() && | 1410 remote_candidate_.password() == new_candidate.password() && |
1400 remote_candidate_.generation() == new_candidate.generation()) { | 1411 remote_candidate_.generation() == new_candidate.generation()) { |
1401 remote_candidate_ = new_candidate; | 1412 remote_candidate_ = new_candidate; |
| 1413 // If it turns out that the peer reflexive candidate was a TURN candidate, |
| 1414 // we may need to change the state to STATE_PRESUMED_WRITABLE. |
| 1415 if (write_state() == STATE_WRITE_INIT) { |
| 1416 set_write_state(InitialWriteState()); |
| 1417 } |
1402 } | 1418 } |
1403 } | 1419 } |
1404 | 1420 |
1405 void Connection::OnMessage(rtc::Message *pmsg) { | 1421 void Connection::OnMessage(rtc::Message *pmsg) { |
1406 ASSERT(pmsg->message_id == MSG_DELETE); | 1422 ASSERT(pmsg->message_id == MSG_DELETE); |
1407 LOG(LS_INFO) << "Connection deleted with number of pings sent: " | 1423 LOG(LS_INFO) << "Connection deleted with number of pings sent: " |
1408 << num_pings_sent_; | 1424 << num_pings_sent_; |
1409 SignalDestroyed(this); | 1425 SignalDestroyed(this); |
1410 delete this; | 1426 delete this; |
1411 } | 1427 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 // Change the local candidate of this Connection to the new prflx candidate. | 1501 // Change the local candidate of this Connection to the new prflx candidate. |
1486 local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate); | 1502 local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate); |
1487 | 1503 |
1488 // SignalStateChange to force a re-sort in P2PTransportChannel as this | 1504 // SignalStateChange to force a re-sort in P2PTransportChannel as this |
1489 // Connection's local candidate has changed. | 1505 // Connection's local candidate has changed. |
1490 SignalStateChange(this); | 1506 SignalStateChange(this); |
1491 } | 1507 } |
1492 | 1508 |
1493 ProxyConnection::ProxyConnection(Port* port, | 1509 ProxyConnection::ProxyConnection(Port* port, |
1494 size_t index, | 1510 size_t index, |
1495 const Candidate& remote_candidate) | 1511 const Candidate& remote_candidate, |
1496 : Connection(port, index, remote_candidate) {} | 1512 const IceConfig& config) |
| 1513 : Connection(port, index, remote_candidate, config) {} |
1497 | 1514 |
1498 int ProxyConnection::Send(const void* data, size_t size, | 1515 int ProxyConnection::Send(const void* data, size_t size, |
1499 const rtc::PacketOptions& options) { | 1516 const rtc::PacketOptions& options) { |
1500 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) { | 1517 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) { |
1501 error_ = EWOULDBLOCK; | 1518 error_ = EWOULDBLOCK; |
1502 return SOCKET_ERROR; | 1519 return SOCKET_ERROR; |
1503 } | 1520 } |
1504 stats_.sent_total_packets++; | 1521 stats_.sent_total_packets++; |
1505 int sent = port_->SendTo(data, size, remote_candidate_.address(), | 1522 int sent = port_->SendTo(data, size, remote_candidate_.address(), |
1506 options, true); | 1523 options, true); |
1507 if (sent <= 0) { | 1524 if (sent <= 0) { |
1508 ASSERT(sent < 0); | 1525 ASSERT(sent < 0); |
1509 error_ = port_->GetError(); | 1526 error_ = port_->GetError(); |
1510 stats_.sent_discarded_packets++; | 1527 stats_.sent_discarded_packets++; |
1511 } else { | 1528 } else { |
1512 send_rate_tracker_.AddSamples(sent); | 1529 send_rate_tracker_.AddSamples(sent); |
1513 } | 1530 } |
1514 return sent; | 1531 return sent; |
1515 } | 1532 } |
1516 | 1533 |
1517 } // namespace cricket | 1534 } // namespace cricket |
OLD | NEW |