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