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 |