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 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 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |