| 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 session->SignalCandidatesReady.connect( | 214 session->SignalCandidatesReady.connect( |
| 215 this, &P2PTransportChannel::OnCandidatesReady); | 215 this, &P2PTransportChannel::OnCandidatesReady); |
| 216 session->SignalCandidatesAllocationDone.connect( | 216 session->SignalCandidatesAllocationDone.connect( |
| 217 this, &P2PTransportChannel::OnCandidatesAllocationDone); | 217 this, &P2PTransportChannel::OnCandidatesAllocationDone); |
| 218 session->StartGettingPorts(); | 218 session->StartGettingPorts(); |
| 219 } | 219 } |
| 220 | 220 |
| 221 void P2PTransportChannel::AddConnection(Connection* connection) { | 221 void P2PTransportChannel::AddConnection(Connection* connection) { |
| 222 connections_.push_back(connection); | 222 connections_.push_back(connection); |
| 223 connection->set_remote_ice_mode(remote_ice_mode_); | 223 connection->set_remote_ice_mode(remote_ice_mode_); |
| 224 connection->set_receiving_timeout(receiving_timeout_); |
| 224 connection->SignalReadPacket.connect( | 225 connection->SignalReadPacket.connect( |
| 225 this, &P2PTransportChannel::OnReadPacket); | 226 this, &P2PTransportChannel::OnReadPacket); |
| 226 connection->SignalReadyToSend.connect( | 227 connection->SignalReadyToSend.connect( |
| 227 this, &P2PTransportChannel::OnReadyToSend); | 228 this, &P2PTransportChannel::OnReadyToSend); |
| 228 connection->SignalStateChange.connect( | 229 connection->SignalStateChange.connect( |
| 229 this, &P2PTransportChannel::OnConnectionStateChange); | 230 this, &P2PTransportChannel::OnConnectionStateChange); |
| 230 connection->SignalDestroyed.connect( | 231 connection->SignalDestroyed.connect( |
| 231 this, &P2PTransportChannel::OnConnectionDestroyed); | 232 this, &P2PTransportChannel::OnConnectionDestroyed); |
| 232 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated); | 233 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated); |
| 233 } | 234 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 remote_ice_mode_ = mode; | 334 remote_ice_mode_ = mode; |
| 334 } | 335 } |
| 335 | 336 |
| 336 void P2PTransportChannel::SetReceivingTimeout(int receiving_timeout_ms) { | 337 void P2PTransportChannel::SetReceivingTimeout(int receiving_timeout_ms) { |
| 337 if (receiving_timeout_ms < 0) { | 338 if (receiving_timeout_ms < 0) { |
| 338 return; | 339 return; |
| 339 } | 340 } |
| 340 receiving_timeout_ = receiving_timeout_ms; | 341 receiving_timeout_ = receiving_timeout_ms; |
| 341 check_receiving_delay_ = | 342 check_receiving_delay_ = |
| 342 std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); | 343 std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); |
| 344 |
| 345 for (Connection* connection : connections_) { |
| 346 connection->set_receiving_timeout(receiving_timeout_); |
| 347 } |
| 343 LOG(LS_VERBOSE) << "Set ICE receiving timeout to " << receiving_timeout_ | 348 LOG(LS_VERBOSE) << "Set ICE receiving timeout to " << receiving_timeout_ |
| 344 << " milliseconds"; | 349 << " milliseconds"; |
| 345 } | 350 } |
| 346 | 351 |
| 347 // Go into the state of processing candidates, and running in general | 352 // Go into the state of processing candidates, and running in general |
| 348 void P2PTransportChannel::Connect() { | 353 void P2PTransportChannel::Connect() { |
| 349 ASSERT(worker_thread_ == rtc::Thread::Current()); | 354 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 350 if (ice_ufrag_.empty() || ice_pwd_.empty()) { | 355 if (ice_ufrag_.empty() || ice_pwd_.empty()) { |
| 351 ASSERT(false); | 356 ASSERT(false); |
| 352 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " | 357 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed); | 398 port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed); |
| 394 port->SignalRoleConflict.connect( | 399 port->SignalRoleConflict.connect( |
| 395 this, &P2PTransportChannel::OnRoleConflict); | 400 this, &P2PTransportChannel::OnRoleConflict); |
| 396 | 401 |
| 397 // Attempt to create a connection from this new port to all of the remote | 402 // Attempt to create a connection from this new port to all of the remote |
| 398 // candidates that we were given so far. | 403 // candidates that we were given so far. |
| 399 | 404 |
| 400 std::vector<RemoteCandidate>::iterator iter; | 405 std::vector<RemoteCandidate>::iterator iter; |
| 401 for (iter = remote_candidates_.begin(); iter != remote_candidates_.end(); | 406 for (iter = remote_candidates_.begin(); iter != remote_candidates_.end(); |
| 402 ++iter) { | 407 ++iter) { |
| 403 CreateConnection(port, *iter, iter->origin_port(), false); | 408 CreateConnection(port, *iter, iter->origin_port()); |
| 404 } | 409 } |
| 405 | 410 |
| 406 SortConnections(); | 411 SortConnections(); |
| 407 } | 412 } |
| 408 | 413 |
| 409 // A new candidate is available, let listeners know | 414 // A new candidate is available, let listeners know |
| 410 void P2PTransportChannel::OnCandidatesReady( | 415 void P2PTransportChannel::OnCandidatesReady( |
| 411 PortAllocatorSession *session, const std::vector<Candidate>& candidates) { | 416 PortAllocatorSession *session, const std::vector<Candidate>& candidates) { |
| 412 ASSERT(worker_thread_ == rtc::Thread::Current()); | 417 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 413 for (size_t i = 0; i < candidates.size(); ++i) { | 418 for (size_t i = 0; i < candidates.size(); ++i) { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 // remote candidate with an older generation arrives, drop it. | 614 // remote candidate with an older generation arrives, drop it. |
| 610 if (generation != 0 && generation < remote_candidate_generation_) { | 615 if (generation != 0 && generation < remote_candidate_generation_) { |
| 611 LOG(LS_WARNING) << "Dropping a remote candidate because its generation " | 616 LOG(LS_WARNING) << "Dropping a remote candidate because its generation " |
| 612 << generation | 617 << generation |
| 613 << " is lower than the current remote generation " | 618 << " is lower than the current remote generation " |
| 614 << remote_candidate_generation_; | 619 << remote_candidate_generation_; |
| 615 return; | 620 return; |
| 616 } | 621 } |
| 617 | 622 |
| 618 // Create connections to this remote candidate. | 623 // Create connections to this remote candidate. |
| 619 CreateConnections(candidate, NULL, false); | 624 CreateConnections(candidate, NULL); |
| 620 | 625 |
| 621 // Resort the connections list, which may have new elements. | 626 // Resort the connections list, which may have new elements. |
| 622 SortConnections(); | 627 SortConnections(); |
| 623 } | 628 } |
| 624 | 629 |
| 625 // Creates connections from all of the ports that we care about to the given | 630 // Creates connections from all of the ports that we care about to the given |
| 626 // remote candidate. The return value is true if we created a connection from | 631 // remote candidate. The return value is true if we created a connection from |
| 627 // the origin port. | 632 // the origin port. |
| 628 bool P2PTransportChannel::CreateConnections(const Candidate& remote_candidate, | 633 bool P2PTransportChannel::CreateConnections(const Candidate& remote_candidate, |
| 629 PortInterface* origin_port, | 634 PortInterface* origin_port) { |
| 630 bool readable) { | |
| 631 ASSERT(worker_thread_ == rtc::Thread::Current()); | 635 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 632 | 636 |
| 633 Candidate new_remote_candidate(remote_candidate); | 637 Candidate new_remote_candidate(remote_candidate); |
| 634 new_remote_candidate.set_generation( | 638 new_remote_candidate.set_generation( |
| 635 GetRemoteCandidateGeneration(remote_candidate)); | 639 GetRemoteCandidateGeneration(remote_candidate)); |
| 636 // ICE candidates don't need to have username and password set, but | 640 // ICE candidates don't need to have username and password set, but |
| 637 // the code below this (specifically, ConnectionRequest::Prepare in | 641 // the code below this (specifically, ConnectionRequest::Prepare in |
| 638 // port.cc) uses the remote candidates's username. So, we set it | 642 // port.cc) uses the remote candidates's username. So, we set it |
| 639 // here. | 643 // here. |
| 640 if (remote_candidate.username().empty()) { | 644 if (remote_candidate.username().empty()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 658 } | 662 } |
| 659 | 663 |
| 660 // Add a new connection for this candidate to every port that allows such a | 664 // Add a new connection for this candidate to every port that allows such a |
| 661 // connection (i.e., if they have compatible protocols) and that does not | 665 // connection (i.e., if they have compatible protocols) and that does not |
| 662 // already have a connection to an equivalent candidate. We must be careful | 666 // already have a connection to an equivalent candidate. We must be careful |
| 663 // to make sure that the origin port is included, even if it was pruned, | 667 // to make sure that the origin port is included, even if it was pruned, |
| 664 // since that may be the only port that can create this connection. | 668 // since that may be the only port that can create this connection. |
| 665 bool created = false; | 669 bool created = false; |
| 666 std::vector<PortInterface *>::reverse_iterator it; | 670 std::vector<PortInterface *>::reverse_iterator it; |
| 667 for (it = ports_.rbegin(); it != ports_.rend(); ++it) { | 671 for (it = ports_.rbegin(); it != ports_.rend(); ++it) { |
| 668 if (CreateConnection(*it, new_remote_candidate, origin_port, readable)) { | 672 if (CreateConnection(*it, new_remote_candidate, origin_port)) { |
| 669 if (*it == origin_port) | 673 if (*it == origin_port) |
| 670 created = true; | 674 created = true; |
| 671 } | 675 } |
| 672 } | 676 } |
| 673 | 677 |
| 674 if ((origin_port != NULL) && | 678 if ((origin_port != NULL) && |
| 675 std::find(ports_.begin(), ports_.end(), origin_port) == ports_.end()) { | 679 std::find(ports_.begin(), ports_.end(), origin_port) == ports_.end()) { |
| 676 if (CreateConnection( | 680 if (CreateConnection(origin_port, new_remote_candidate, origin_port)) |
| 677 origin_port, new_remote_candidate, origin_port, readable)) | |
| 678 created = true; | 681 created = true; |
| 679 } | 682 } |
| 680 | 683 |
| 681 // Remember this remote candidate so that we can add it to future ports. | 684 // Remember this remote candidate so that we can add it to future ports. |
| 682 RememberRemoteCandidate(new_remote_candidate, origin_port); | 685 RememberRemoteCandidate(new_remote_candidate, origin_port); |
| 683 | 686 |
| 684 return created; | 687 return created; |
| 685 } | 688 } |
| 686 | 689 |
| 687 // Setup a connection object for the local and remote candidate combination. | 690 // Setup a connection object for the local and remote candidate combination. |
| 688 // And then listen to connection object for changes. | 691 // And then listen to connection object for changes. |
| 689 bool P2PTransportChannel::CreateConnection(PortInterface* port, | 692 bool P2PTransportChannel::CreateConnection(PortInterface* port, |
| 690 const Candidate& remote_candidate, | 693 const Candidate& remote_candidate, |
| 691 PortInterface* origin_port, | 694 PortInterface* origin_port) { |
| 692 bool readable) { | |
| 693 // Look for an existing connection with this remote address. If one is not | 695 // Look for an existing connection with this remote address. If one is not |
| 694 // found, then we can create a new connection for this address. | 696 // found, then we can create a new connection for this address. |
| 695 Connection* connection = port->GetConnection(remote_candidate.address()); | 697 Connection* connection = port->GetConnection(remote_candidate.address()); |
| 696 if (connection != NULL) { | 698 if (connection != NULL) { |
| 697 connection->MaybeUpdatePeerReflexiveCandidate(remote_candidate); | 699 connection->MaybeUpdatePeerReflexiveCandidate(remote_candidate); |
| 698 | 700 |
| 699 // It is not legal to try to change any of the parameters of an existing | 701 // It is not legal to try to change any of the parameters of an existing |
| 700 // connection; however, the other side can send a duplicate candidate. | 702 // connection; however, the other side can send a duplicate candidate. |
| 701 if (!remote_candidate.IsEquivalent(connection->remote_candidate())) { | 703 if (!remote_candidate.IsEquivalent(connection->remote_candidate())) { |
| 702 LOG(INFO) << "Attempt to change a remote candidate." | 704 LOG(INFO) << "Attempt to change a remote candidate." |
| (...skipping 14 matching lines...) Expand all Loading... |
| 717 connection = port->CreateConnection(remote_candidate, origin); | 719 connection = port->CreateConnection(remote_candidate, origin); |
| 718 if (!connection) | 720 if (!connection) |
| 719 return false; | 721 return false; |
| 720 | 722 |
| 721 AddConnection(connection); | 723 AddConnection(connection); |
| 722 | 724 |
| 723 LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", (" | 725 LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", (" |
| 724 << connections_.size() << " total)"; | 726 << connections_.size() << " total)"; |
| 725 } | 727 } |
| 726 | 728 |
| 727 // If we are readable, it is because we are creating this in response to a | |
| 728 // ping from the other side. This will cause the state to become readable. | |
| 729 if (readable) | |
| 730 connection->ReceivedPing(); | |
| 731 | |
| 732 return true; | 729 return true; |
| 733 } | 730 } |
| 734 | 731 |
| 735 bool P2PTransportChannel::FindConnection( | 732 bool P2PTransportChannel::FindConnection( |
| 736 cricket::Connection* connection) const { | 733 cricket::Connection* connection) const { |
| 737 std::vector<Connection*>::const_iterator citer = | 734 std::vector<Connection*>::const_iterator citer = |
| 738 std::find(connections_.begin(), connections_.end(), connection); | 735 std::find(connections_.begin(), connections_.end(), connection); |
| 739 return citer != connections_.end(); | 736 return citer != connections_.end(); |
| 740 } | 737 } |
| 741 | 738 |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { | 843 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { |
| 847 ASSERT(worker_thread_ == rtc::Thread::Current()); | 844 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 848 // Gather connection infos. | 845 // Gather connection infos. |
| 849 infos->clear(); | 846 infos->clear(); |
| 850 | 847 |
| 851 std::vector<Connection *>::const_iterator it; | 848 std::vector<Connection *>::const_iterator it; |
| 852 for (it = connections_.begin(); it != connections_.end(); ++it) { | 849 for (it = connections_.begin(); it != connections_.end(); ++it) { |
| 853 Connection *connection = *it; | 850 Connection *connection = *it; |
| 854 ConnectionInfo info; | 851 ConnectionInfo info; |
| 855 info.best_connection = (best_connection_ == connection); | 852 info.best_connection = (best_connection_ == connection); |
| 856 info.readable = | 853 info.receiving = connection->receiving(); |
| 857 (connection->read_state() == Connection::STATE_READABLE); | |
| 858 info.writable = | 854 info.writable = |
| 859 (connection->write_state() == Connection::STATE_WRITABLE); | 855 (connection->write_state() == Connection::STATE_WRITABLE); |
| 860 info.timeout = | 856 info.timeout = |
| 861 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); | 857 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); |
| 862 info.new_connection = !connection->reported(); | 858 info.new_connection = !connection->reported(); |
| 863 connection->set_reported(true); | 859 connection->set_reported(true); |
| 864 info.rtt = connection->rtt(); | 860 info.rtt = connection->rtt(); |
| 865 info.sent_total_bytes = connection->sent_total_bytes(); | 861 info.sent_total_bytes = connection->sent_total_bytes(); |
| 866 info.sent_bytes_second = connection->sent_bytes_second(); | 862 info.sent_bytes_second = connection->sent_bytes_second(); |
| 867 info.sent_discarded_packets = connection->sent_discarded_packets(); | 863 info.sent_discarded_packets = connection->sent_discarded_packets(); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 Connection* old_best_connection = best_connection_; | 1018 Connection* old_best_connection = best_connection_; |
| 1023 best_connection_ = conn; | 1019 best_connection_ = conn; |
| 1024 if (best_connection_) { | 1020 if (best_connection_) { |
| 1025 if (old_best_connection) { | 1021 if (old_best_connection) { |
| 1026 LOG_J(LS_INFO, this) << "Previous best connection: " | 1022 LOG_J(LS_INFO, this) << "Previous best connection: " |
| 1027 << old_best_connection->ToString(); | 1023 << old_best_connection->ToString(); |
| 1028 } | 1024 } |
| 1029 LOG_J(LS_INFO, this) << "New best connection: " | 1025 LOG_J(LS_INFO, this) << "New best connection: " |
| 1030 << best_connection_->ToString(); | 1026 << best_connection_->ToString(); |
| 1031 SignalRouteChange(this, best_connection_->remote_candidate()); | 1027 SignalRouteChange(this, best_connection_->remote_candidate()); |
| 1032 // When it just switched to a best connection, set receiving to true. | 1028 set_receiving(best_connection_->receiving()); |
| 1033 set_receiving(true); | |
| 1034 } else { | 1029 } else { |
| 1035 LOG_J(LS_INFO, this) << "No best connection"; | 1030 LOG_J(LS_INFO, this) << "No best connection"; |
| 1036 } | 1031 } |
| 1037 } | 1032 } |
| 1038 | 1033 |
| 1039 void P2PTransportChannel::UpdateChannelState() { | 1034 void P2PTransportChannel::UpdateChannelState() { |
| 1040 // The Handle* functions already set the writable state. We'll just double- | 1035 // The Handle* functions already set the writable state. We'll just double- |
| 1041 // check it here. | 1036 // check it here. |
| 1042 bool writable = ((best_connection_ != NULL) && | 1037 bool writable = ((best_connection_ != NULL) && |
| 1043 (best_connection_->write_state() == | 1038 (best_connection_->write_state() == |
| 1044 Connection::STATE_WRITABLE)); | 1039 Connection::STATE_WRITABLE)); |
| 1045 ASSERT(writable == this->writable()); | 1040 ASSERT(writable == this->writable()); |
| 1046 if (writable != this->writable()) | 1041 if (writable != this->writable()) |
| 1047 LOG(LS_ERROR) << "UpdateChannelState: writable state mismatch"; | 1042 LOG(LS_ERROR) << "UpdateChannelState: writable state mismatch"; |
| 1048 | 1043 |
| 1049 bool readable = false; | 1044 // TODO(honghaiz): The channel receiving state is set in OnCheckReceiving. |
| 1050 for (uint32 i = 0; i < connections_.size(); ++i) { | 1045 // Will revisit in a subsequent code change. |
| 1051 if (connections_[i]->read_state() == Connection::STATE_READABLE) { | |
| 1052 readable = true; | |
| 1053 break; | |
| 1054 } | |
| 1055 } | |
| 1056 set_readable(readable); | |
| 1057 } | 1046 } |
| 1058 | 1047 |
| 1059 // We checked the status of our connections and we had at least one that | 1048 // We checked the status of our connections and we had at least one that |
| 1060 // was writable, go into the writable state. | 1049 // was writable, go into the writable state. |
| 1061 void P2PTransportChannel::HandleWritable() { | 1050 void P2PTransportChannel::HandleWritable() { |
| 1062 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1051 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 1063 if (!writable()) { | 1052 if (!writable()) { |
| 1064 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) { | 1053 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) { |
| 1065 if (allocator_sessions_[i]->IsGettingPorts()) { | 1054 if (allocator_sessions_[i]->IsGettingPorts()) { |
| 1066 allocator_sessions_[i]->StopGettingPorts(); | 1055 allocator_sessions_[i]->StopGettingPorts(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1137 Connection* conn = FindNextPingableConnection(); | 1126 Connection* conn = FindNextPingableConnection(); |
| 1138 if (conn) | 1127 if (conn) |
| 1139 PingConnection(conn); | 1128 PingConnection(conn); |
| 1140 | 1129 |
| 1141 // Post ourselves a message to perform the next ping. | 1130 // Post ourselves a message to perform the next ping. |
| 1142 uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY; | 1131 uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY; |
| 1143 thread()->PostDelayed(delay, this, MSG_PING); | 1132 thread()->PostDelayed(delay, this, MSG_PING); |
| 1144 } | 1133 } |
| 1145 | 1134 |
| 1146 void P2PTransportChannel::OnCheckReceiving() { | 1135 void P2PTransportChannel::OnCheckReceiving() { |
| 1147 // Check receiving only if the best connection has received data packets | 1136 if (best_connection_) { |
| 1148 // because we want to detect not receiving any packets only after the media | |
| 1149 // have started flowing. | |
| 1150 if (best_connection_ && best_connection_->recv_total_bytes() > 0) { | |
| 1151 bool receiving = rtc::Time() <= | 1137 bool receiving = rtc::Time() <= |
| 1152 best_connection_->last_received() + receiving_timeout_; | 1138 best_connection_->last_received() + receiving_timeout_; |
| 1153 set_receiving(receiving); | 1139 set_receiving(receiving); |
| 1154 } | 1140 } |
| 1155 | 1141 |
| 1156 thread()->PostDelayed(check_receiving_delay_, this, MSG_CHECK_RECEIVING); | 1142 thread()->PostDelayed(check_receiving_delay_, this, MSG_CHECK_RECEIVING); |
| 1157 } | 1143 } |
| 1158 | 1144 |
| 1159 // Is the connection in a state for us to even consider pinging the other side? | 1145 // Is the connection in a state for us to even consider pinging the other side? |
| 1160 // We consider a connection pingable even if it's not connected because that's | 1146 // We consider a connection pingable even if it's not connected because that's |
| 1161 // how a TCP connection is kicked into reconnecting on the active side. | 1147 // how a TCP connection is kicked into reconnecting on the active side. |
| 1162 bool P2PTransportChannel::IsPingable(Connection* conn) { | 1148 bool P2PTransportChannel::IsPingable(Connection* conn) { |
| 1163 const Candidate& remote = conn->remote_candidate(); | 1149 const Candidate& remote = conn->remote_candidate(); |
| 1164 // We should never get this far with an empty remote ufrag. | 1150 // We should never get this far with an empty remote ufrag. |
| 1165 ASSERT(!remote.username().empty()); | 1151 ASSERT(!remote.username().empty()); |
| 1166 if (remote.username().empty() || remote.password().empty()) { | 1152 if (remote.username().empty() || remote.password().empty()) { |
| 1167 // If we don't have an ICE ufrag and pwd, there's no way we can ping. | 1153 // If we don't have an ICE ufrag and pwd, there's no way we can ping. |
| 1168 return false; | 1154 return false; |
| 1169 } | 1155 } |
| 1170 | 1156 |
| 1171 // An never connected connection cannot be written to at all, so pinging is | 1157 // An never connected connection cannot be written to at all, so pinging is |
| 1172 // out of the question. However, if it has become WRITABLE, it is in the | 1158 // out of the question. However, if it has become WRITABLE, it is in the |
| 1173 // reconnecting state so ping is needed. | 1159 // reconnecting state so ping is needed. |
| 1174 if (!conn->connected() && conn->write_state() != Connection::STATE_WRITABLE) { | 1160 if (!conn->connected() && !conn->writable()) { |
| 1175 return false; | 1161 return false; |
| 1176 } | 1162 } |
| 1177 | 1163 |
| 1178 if (writable()) { | 1164 // If the channel is not writable, ping all candidates. Otherwise, we only |
| 1179 // If we are writable, then we only want to ping connections that could be | 1165 // want to ping connections that have not timed out on writing. |
| 1180 // better than this one, i.e., the ones that were not pruned. | 1166 return !writable() || conn->write_state() != Connection::STATE_WRITE_TIMEOUT; |
| 1181 return (conn->write_state() != Connection::STATE_WRITE_TIMEOUT); | |
| 1182 } else { | |
| 1183 // If we are not writable, then we need to try everything that might work. | |
| 1184 // This includes both connections that do not have write timeout as well as | |
| 1185 // ones that do not have read timeout. A connection could be readable but | |
| 1186 // be in write-timeout if we pruned it before. Since the other side is | |
| 1187 // still pinging it, it very well might still work. | |
| 1188 return (conn->write_state() != Connection::STATE_WRITE_TIMEOUT) || | |
| 1189 (conn->read_state() != Connection::STATE_READ_TIMEOUT); | |
| 1190 } | |
| 1191 } | 1167 } |
| 1192 | 1168 |
| 1193 // Returns the next pingable connection to ping. This will be the oldest | 1169 // Returns the next pingable connection to ping. This will be the oldest |
| 1194 // pingable connection unless we have a connected, writable connection that is | 1170 // pingable connection unless we have a connected, writable connection that is |
| 1195 // past the maximum acceptable ping delay. When reconnecting a TCP connection, | 1171 // past the maximum acceptable ping delay. When reconnecting a TCP connection, |
| 1196 // the best connection is disconnected, although still WRITABLE while | 1172 // the best connection is disconnected, although still WRITABLE while |
| 1197 // reconnecting. The newly created connection should be selected as the ping | 1173 // reconnecting. The newly created connection should be selected as the ping |
| 1198 // target to become writable instead. See the big comment in CompareConnections. | 1174 // target to become writable instead. See the big comment in CompareConnections. |
| 1199 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1175 Connection* P2PTransportChannel::FindNextPingableConnection() { |
| 1200 uint32 now = rtc::Time(); | 1176 uint32 now = rtc::Time(); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1355 } | 1331 } |
| 1356 } | 1332 } |
| 1357 | 1333 |
| 1358 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1334 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
| 1359 if (connection == best_connection_ && writable()) { | 1335 if (connection == best_connection_ && writable()) { |
| 1360 SignalReadyToSend(this); | 1336 SignalReadyToSend(this); |
| 1361 } | 1337 } |
| 1362 } | 1338 } |
| 1363 | 1339 |
| 1364 } // namespace cricket | 1340 } // namespace cricket |
| OLD | NEW |