Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(265)

Side by Side Diff: webrtc/p2p/base/p2ptransportchannel.cc

Issue 2099563004: Start ICE connectivity checks as soon as the first pair is pingable. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Code style fixes, renaming some methods, calling MaybeStartPinging in a different place. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 #include "webrtc/p2p/base/p2ptransportchannel.h" 11 #include "webrtc/p2p/base/p2ptransportchannel.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <set> 14 #include <set>
15 15
16 #include "webrtc/base/common.h" 16 #include "webrtc/base/common.h"
17 #include "webrtc/base/crc32.h" 17 #include "webrtc/base/crc32.h"
18 #include "webrtc/base/logging.h" 18 #include "webrtc/base/logging.h"
19 #include "webrtc/base/stringencode.h" 19 #include "webrtc/base/stringencode.h"
20 #include "webrtc/p2p/base/candidate.h" 20 #include "webrtc/p2p/base/candidate.h"
21 #include "webrtc/p2p/base/candidatepairinterface.h" 21 #include "webrtc/p2p/base/candidatepairinterface.h"
22 #include "webrtc/p2p/base/common.h" 22 #include "webrtc/p2p/base/common.h"
23 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE. 23 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE.
24 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE. 24 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE.
25 #include "webrtc/system_wrappers/include/field_trial.h" 25 #include "webrtc/system_wrappers/include/field_trial.h"
26 26
27 namespace { 27 namespace {
28 28
29 // messages for queuing up work for ourselves 29 // messages for queuing up work for ourselves
30 enum { MSG_SORT = 1, MSG_CHECK_AND_PING }; 30 enum { MSG_SORT_AND_UPDATE_STATE = 1, MSG_CHECK_AND_PING };
31 31
32 // The minimum improvement in RTT that justifies a switch. 32 // The minimum improvement in RTT that justifies a switch.
33 static const double kMinImprovement = 10; 33 static const double kMinImprovement = 10;
34 34
35 bool IsRelayRelay(const cricket::Connection* conn) { 35 bool IsRelayRelay(const cricket::Connection* conn) {
36 return conn->local_candidate().type() == cricket::RELAY_PORT_TYPE && 36 return conn->local_candidate().type() == cricket::RELAY_PORT_TYPE &&
37 conn->remote_candidate().type() == cricket::RELAY_PORT_TYPE; 37 conn->remote_candidate().type() == cricket::RELAY_PORT_TYPE;
38 } 38 }
39 39
40 bool IsUdp(cricket::Connection* conn) { 40 bool IsUdp(cricket::Connection* conn) {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } 280 }
281 } 281 }
282 // We need to update the credentials and generation for any peer reflexive 282 // We need to update the credentials and generation for any peer reflexive
283 // candidates. 283 // candidates.
284 for (Connection* conn : connections_) { 284 for (Connection* conn : connections_) {
285 conn->MaybeSetRemoteIceCredentialsAndGeneration( 285 conn->MaybeSetRemoteIceCredentialsAndGeneration(
286 ice_ufrag, ice_pwd, 286 ice_ufrag, ice_pwd,
287 static_cast<int>(remote_ice_parameters_.size() - 1)); 287 static_cast<int>(remote_ice_parameters_.size() - 1));
288 } 288 }
289 // Updating the remote ICE candidate generation could change the sort order. 289 // Updating the remote ICE candidate generation could change the sort order.
290 RequestSort(); 290 RequestSortAndStateUpdate();
291 } 291 }
292 292
293 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { 293 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
294 remote_ice_mode_ = mode; 294 remote_ice_mode_ = mode;
295 } 295 }
296 296
297 void P2PTransportChannel::SetIceConfig(const IceConfig& config) { 297 void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
298 config_.gather_continually = config.gather_continually; 298 config_.gather_continually = config.gather_continually;
299 LOG(LS_INFO) << "Set gather_continually to " << config_.gather_continually; 299 LOG(LS_INFO) << "Set gather_continually to " << config_.gather_continually;
300 300
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 LOG(LS_INFO) << "Set presume writable when fully relayed to " 345 LOG(LS_INFO) << "Set presume writable when fully relayed to "
346 << config_.presume_writable_when_fully_relayed; 346 << config_.presume_writable_when_fully_relayed;
347 } 347 }
348 } 348 }
349 } 349 }
350 350
351 const IceConfig& P2PTransportChannel::config() const { 351 const IceConfig& P2PTransportChannel::config() const {
352 return config_; 352 return config_;
353 } 353 }
354 354
355 // Go into the state of processing candidates, and running in general 355 void P2PTransportChannel::MaybeStartGathering() {
356 void P2PTransportChannel::Connect() {
357 ASSERT(worker_thread_ == rtc::Thread::Current());
358 if (ice_ufrag_.empty() || ice_pwd_.empty()) { 356 if (ice_ufrag_.empty() || ice_pwd_.empty()) {
359 ASSERT(false);
360 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the "
361 << "ice_pwd_ are not set.";
362 return; 357 return;
363 } 358 }
364
365 // Start checking and pinging as the ports come in.
366 thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING);
367 }
368
369 void P2PTransportChannel::MaybeStartGathering() {
370 // Start gathering if we never started before, or if an ICE restart occurred. 359 // Start gathering if we never started before, or if an ICE restart occurred.
371 if (allocator_sessions_.empty() || 360 if (allocator_sessions_.empty() ||
372 IceCredentialsChanged(allocator_sessions_.back()->ice_ufrag(), 361 IceCredentialsChanged(allocator_sessions_.back()->ice_ufrag(),
373 allocator_sessions_.back()->ice_pwd(), ice_ufrag_, 362 allocator_sessions_.back()->ice_pwd(), ice_ufrag_,
374 ice_pwd_)) { 363 ice_pwd_)) {
375 if (gathering_state_ != kIceGatheringGathering) { 364 if (gathering_state_ != kIceGatheringGathering) {
376 gathering_state_ = kIceGatheringGathering; 365 gathering_state_ = kIceGatheringGathering;
377 SignalGatheringState(this); 366 SignalGatheringState(this);
378 } 367 }
379 // Time for a new allocator. 368 // Time for a new allocator.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 425
437 // Attempt to create a connection from this new port to all of the remote 426 // Attempt to create a connection from this new port to all of the remote
438 // candidates that we were given so far. 427 // candidates that we were given so far.
439 428
440 std::vector<RemoteCandidate>::iterator iter; 429 std::vector<RemoteCandidate>::iterator iter;
441 for (iter = remote_candidates_.begin(); iter != remote_candidates_.end(); 430 for (iter = remote_candidates_.begin(); iter != remote_candidates_.end();
442 ++iter) { 431 ++iter) {
443 CreateConnection(port, *iter, iter->origin_port()); 432 CreateConnection(port, *iter, iter->origin_port());
444 } 433 }
445 434
446 SortConnections(); 435 SortConnectionsAndUpdateState();
447 } 436 }
448 437
449 // A new candidate is available, let listeners know 438 // A new candidate is available, let listeners know
450 void P2PTransportChannel::OnCandidatesReady( 439 void P2PTransportChannel::OnCandidatesReady(
451 PortAllocatorSession* session, 440 PortAllocatorSession* session,
452 const std::vector<Candidate>& candidates) { 441 const std::vector<Candidate>& candidates) {
453 ASSERT(worker_thread_ == rtc::Thread::Current()); 442 ASSERT(worker_thread_ == rtc::Thread::Current());
454 for (size_t i = 0; i < candidates.size(); ++i) { 443 for (size_t i = 0; i < candidates.size(); ++i) {
455 SignalCandidateGathered(this, candidates[i]); 444 SignalCandidateGathered(this, candidates[i]);
456 } 445 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 567
579 LOG(LS_INFO) << "Adding connection from " 568 LOG(LS_INFO) << "Adding connection from "
580 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") 569 << (remote_candidate_is_new ? "peer reflexive" : "resurrected")
581 << " candidate: " << remote_candidate.ToString(); 570 << " candidate: " << remote_candidate.ToString();
582 AddConnection(connection); 571 AddConnection(connection);
583 connection->HandleBindingRequest(stun_msg); 572 connection->HandleBindingRequest(stun_msg);
584 573
585 // Update the list of connections since we just added another. We do this 574 // Update the list of connections since we just added another. We do this
586 // after sending the response since it could (in principle) delete the 575 // after sending the response since it could (in principle) delete the
587 // connection in question. 576 // connection in question.
588 SortConnections(); 577 SortConnectionsAndUpdateState();
589 } 578 }
590 579
591 void P2PTransportChannel::OnRoleConflict(PortInterface* port) { 580 void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
592 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called 581 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called
593 // from Transport. 582 // from Transport.
594 } 583 }
595 584
596 const IceParameters* P2PTransportChannel::FindRemoteIceFromUfrag( 585 const IceParameters* P2PTransportChannel::FindRemoteIceFromUfrag(
597 const std::string& ufrag, 586 const std::string& ufrag,
598 uint32_t* generation) { 587 uint32_t* generation) {
(...skipping 23 matching lines...) Expand all
622 << conn->ToString(); 611 << conn->ToString();
623 return; 612 return;
624 } 613 }
625 614
626 LOG(LS_INFO) 615 LOG(LS_INFO)
627 << "Switching selected connection on controlled side due to nomination: " 616 << "Switching selected connection on controlled side due to nomination: "
628 << conn->ToString(); 617 << conn->ToString();
629 SwitchSelectedConnection(conn); 618 SwitchSelectedConnection(conn);
630 // Now that we have selected a connection, it is time to prune other 619 // Now that we have selected a connection, it is time to prune other
631 // connections and update the read/write state of the channel. 620 // connections and update the read/write state of the channel.
632 RequestSort(); 621 RequestSortAndStateUpdate();
633 } 622 }
634 623
635 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) { 624 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) {
636 ASSERT(worker_thread_ == rtc::Thread::Current()); 625 ASSERT(worker_thread_ == rtc::Thread::Current());
637 626
638 uint32_t generation = GetRemoteCandidateGeneration(candidate); 627 uint32_t generation = GetRemoteCandidateGeneration(candidate);
639 // If a remote candidate with a previous generation arrives, drop it. 628 // If a remote candidate with a previous generation arrives, drop it.
640 if (generation < remote_ice_generation()) { 629 if (generation < remote_ice_generation()) {
641 LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag " 630 LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag "
642 << candidate.username() 631 << candidate.username()
(...skipping 26 matching lines...) Expand all
669 // If this candidate matches what was thought to be a peer reflexive 658 // If this candidate matches what was thought to be a peer reflexive
670 // candidate, we need to update the candidate priority/etc. 659 // candidate, we need to update the candidate priority/etc.
671 for (Connection* conn : connections_) { 660 for (Connection* conn : connections_) {
672 conn->MaybeUpdatePeerReflexiveCandidate(new_remote_candidate); 661 conn->MaybeUpdatePeerReflexiveCandidate(new_remote_candidate);
673 } 662 }
674 663
675 // Create connections to this remote candidate. 664 // Create connections to this remote candidate.
676 CreateConnections(new_remote_candidate, NULL); 665 CreateConnections(new_remote_candidate, NULL);
677 666
678 // Resort the connections list, which may have new elements. 667 // Resort the connections list, which may have new elements.
679 SortConnections(); 668 SortConnectionsAndUpdateState();
680 } 669 }
681 670
682 void P2PTransportChannel::RemoveRemoteCandidate( 671 void P2PTransportChannel::RemoveRemoteCandidate(
683 const Candidate& cand_to_remove) { 672 const Candidate& cand_to_remove) {
684 auto iter = 673 auto iter =
685 std::remove_if(remote_candidates_.begin(), remote_candidates_.end(), 674 std::remove_if(remote_candidates_.begin(), remote_candidates_.end(),
686 [cand_to_remove](const Candidate& candidate) { 675 [cand_to_remove](const Candidate& candidate) {
687 return cand_to_remove.MatchesForRemoval(candidate); 676 return cand_to_remove.MatchesForRemoval(candidate);
688 }); 677 });
689 if (iter != remote_candidates_.end()) { 678 if (iter != remote_candidates_.end()) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 void P2PTransportChannel::UpdateConnectionStates() { 927 void P2PTransportChannel::UpdateConnectionStates() {
939 int64_t now = rtc::TimeMillis(); 928 int64_t now = rtc::TimeMillis();
940 929
941 // We need to copy the list of connections since some may delete themselves 930 // We need to copy the list of connections since some may delete themselves
942 // when we call UpdateState. 931 // when we call UpdateState.
943 for (size_t i = 0; i < connections_.size(); ++i) 932 for (size_t i = 0; i < connections_.size(); ++i)
944 connections_[i]->UpdateState(now); 933 connections_[i]->UpdateState(now);
945 } 934 }
946 935
947 // Prepare for best candidate sorting. 936 // Prepare for best candidate sorting.
948 void P2PTransportChannel::RequestSort() { 937 void P2PTransportChannel::RequestSortAndStateUpdate() {
949 if (!sort_dirty_) { 938 if (!sort_dirty_) {
950 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT); 939 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT_AND_UPDATE_STATE);
951 sort_dirty_ = true; 940 sort_dirty_ = true;
952 } 941 }
953 } 942 }
954 943
944 void P2PTransportChannel::MaybeStartPinging() {
945 if (started_pinging_) {
946 return;
947 }
948 LOG(LS_INFO) << "IN maybestartpinging";
949
950 int64_t now = rtc::TimeMillis();
951 if (std::any_of(
952 connections_.begin(), connections_.end(),
953 [this, now](const Connection* c) { return IsPingable(c, now); })) {
954 LOG_J(LS_INFO, this) << "Have a pingable connection for the first time; "
955 << "starting to ping.";
956 thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING);
957 started_pinging_ = true;
958 }
959 }
960
955 // Compare two connections based on their writing, receiving, and connected 961 // Compare two connections based on their writing, receiving, and connected
956 // states. 962 // states.
957 int P2PTransportChannel::CompareConnectionStates(const Connection* a, 963 int P2PTransportChannel::CompareConnectionStates(const Connection* a,
958 const Connection* b) const { 964 const Connection* b) const {
959 // First, prefer a connection that's writable or presumed writable over 965 // First, prefer a connection that's writable or presumed writable over
960 // one that's not writable. 966 // one that's not writable.
961 bool a_writable = a->writable() || PresumedWritable(a); 967 bool a_writable = a->writable() || PresumedWritable(a);
962 bool b_writable = b->writable() || PresumedWritable(b); 968 bool b_writable = b->writable() || PresumedWritable(b);
963 if (a_writable && !b_writable) { 969 if (a_writable && !b_writable) {
964 return a_is_better; 970 return a_is_better;
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 int prefs_cmp = CompareConnectionCandidates(selected, conn); 1127 int prefs_cmp = CompareConnectionCandidates(selected, conn);
1122 if (prefs_cmp != 0) { 1128 if (prefs_cmp != 0) {
1123 return prefs_cmp < 0; 1129 return prefs_cmp < 0;
1124 } 1130 }
1125 1131
1126 return selected->rtt() - conn->rtt() >= kMinImprovement; 1132 return selected->rtt() - conn->rtt() >= kMinImprovement;
1127 } 1133 }
1128 1134
1129 // Sort the available connections to find the best one. We also monitor 1135 // Sort the available connections to find the best one. We also monitor
1130 // the number of available connections and the current state. 1136 // the number of available connections and the current state.
1131 void P2PTransportChannel::SortConnections() { 1137 void P2PTransportChannel::SortConnectionsAndUpdateState() {
1132 ASSERT(worker_thread_ == rtc::Thread::Current()); 1138 ASSERT(worker_thread_ == rtc::Thread::Current());
1133 1139
1134 // Make sure the connection states are up-to-date since this affects how they 1140 // Make sure the connection states are up-to-date since this affects how they
1135 // will be sorted. 1141 // will be sorted.
1136 UpdateConnectionStates(); 1142 UpdateConnectionStates();
1137 1143
1138 // Any changes after this point will require a re-sort. 1144 // Any changes after this point will require a re-sort.
1139 sort_dirty_ = false; 1145 sort_dirty_ = false;
1140 1146
1141 // Find the best alternative connection by sorting. It is important to note 1147 // Find the best alternative connection by sorting. It is important to note
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 break; 1196 break;
1191 } 1197 }
1192 } 1198 }
1193 1199
1194 // Now update the writable state of the channel with the information we have 1200 // Now update the writable state of the channel with the information we have
1195 // so far. 1201 // so far.
1196 if (all_connections_timedout) { 1202 if (all_connections_timedout) {
1197 HandleAllTimedOut(); 1203 HandleAllTimedOut();
1198 } 1204 }
1199 1205
1200 // Update the state of this channel. This method is called whenever the 1206 // Update the state of this channel.
1201 // state of any connection changes, so this is a good place to do this.
1202 UpdateState(); 1207 UpdateState();
1208
1209 // Also possibly start pinging.
1210 // We could start pinging if:
1211 // * The first connection was created.
1212 // * ICE credentials were provided.
1213 // * A TCP connection became connected.
pthatcher1 2016/06/29 17:45:43 Oh, wow, good catch about TCP. And much cleaner.
Taylor Brandstetter 2016/06/29 18:04:56 It actually wasn't my catch; it was the unit tests
1214 MaybeStartPinging();
1203 } 1215 }
1204 1216
1205 void P2PTransportChannel::PruneConnections() { 1217 void P2PTransportChannel::PruneConnections() {
1206 // We can prune any connection for which there is a connected, writable 1218 // We can prune any connection for which there is a connected, writable
1207 // connection on the same network with better or equal priority. We leave 1219 // connection on the same network with better or equal priority. We leave
1208 // those with better priority just in case they become writable later (at 1220 // those with better priority just in case they become writable later (at
1209 // which point, we would prune out the current selected connection). We leave 1221 // which point, we would prune out the current selected connection). We leave
1210 // connections on other networks because they may not be using the same 1222 // connections on other networks because they may not be using the same
1211 // resources and they may represent very distinct paths over which we can 1223 // resources and they may represent very distinct paths over which we can
1212 // switch. If the |premier| connection is not connected, we may be 1224 // switch. If the |premier| connection is not connected, we may be
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 } 1275 }
1264 SignalSelectedCandidatePairChanged(this, selected_connection_, 1276 SignalSelectedCandidatePairChanged(this, selected_connection_,
1265 last_sent_packet_id_); 1277 last_sent_packet_id_);
1266 } 1278 }
1267 1279
1268 // Warning: UpdateState should eventually be called whenever a connection 1280 // Warning: UpdateState should eventually be called whenever a connection
1269 // is added, deleted, or the write state of any connection changes so that the 1281 // is added, deleted, or the write state of any connection changes so that the
1270 // transport controller will get the up-to-date channel state. However it 1282 // transport controller will get the up-to-date channel state. However it
1271 // should not be called too often; in the case that multiple connection states 1283 // should not be called too often; in the case that multiple connection states
1272 // change, it should be called after all the connection states have changed. For 1284 // change, it should be called after all the connection states have changed. For
1273 // example, we call this at the end of SortConnections. 1285 // example, we call this at the end of SortConnectionsAndUpdateState.
1274 void P2PTransportChannel::UpdateState() { 1286 void P2PTransportChannel::UpdateState() {
1275 TransportChannelState state = ComputeState(); 1287 TransportChannelState state = ComputeState();
1276 if (state_ != state) { 1288 if (state_ != state) {
1277 LOG_J(LS_INFO, this) << "Transport channel state changed from " << state_ 1289 LOG_J(LS_INFO, this) << "Transport channel state changed from " << state_
1278 << " to " << state; 1290 << " to " << state;
1279 // Check that the requested transition is allowed. Note that 1291 // Check that the requested transition is allowed. Note that
1280 // P2PTransportChannel does not (yet) implement a direct mapping of the ICE 1292 // P2PTransportChannel does not (yet) implement a direct mapping of the ICE
1281 // states from the standard; the difference is covered by 1293 // states from the standard; the difference is covered by
1282 // TransportController and PeerConnection. 1294 // TransportController and PeerConnection.
1283 switch (state_) { 1295 switch (state_) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1372 return connections_[i]; 1384 return connections_[i];
1373 } 1385 }
1374 } 1386 }
1375 1387
1376 return NULL; 1388 return NULL;
1377 } 1389 }
1378 1390
1379 // Handle any queued up requests 1391 // Handle any queued up requests
1380 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { 1392 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) {
1381 switch (pmsg->message_id) { 1393 switch (pmsg->message_id) {
1382 case MSG_SORT: 1394 case MSG_SORT_AND_UPDATE_STATE:
1383 OnSort(); 1395 SortConnectionsAndUpdateState();
1384 break; 1396 break;
1385 case MSG_CHECK_AND_PING: 1397 case MSG_CHECK_AND_PING:
1386 OnCheckAndPing(); 1398 OnCheckAndPing();
1387 break; 1399 break;
1388 default: 1400 default:
1389 ASSERT(false); 1401 ASSERT(false);
1390 break; 1402 break;
1391 } 1403 }
1392 } 1404 }
1393 1405
1394 // Handle queued up sort request
1395 void P2PTransportChannel::OnSort() {
1396 // Resort the connections based on the new statistics.
1397 SortConnections();
1398 }
1399
1400 // Handle queued up check-and-ping request 1406 // Handle queued up check-and-ping request
1401 void P2PTransportChannel::OnCheckAndPing() { 1407 void P2PTransportChannel::OnCheckAndPing() {
1402 // Make sure the states of the connections are up-to-date (since this affects 1408 // Make sure the states of the connections are up-to-date (since this affects
1403 // which ones are pingable). 1409 // which ones are pingable).
1404 UpdateConnectionStates(); 1410 UpdateConnectionStates();
1405 // When the selected connection is not receiving or not writable, or any 1411 // When the selected connection is not receiving or not writable, or any
1406 // active connection has not been pinged enough times, use the weak ping 1412 // active connection has not been pinged enough times, use the weak ping
1407 // interval. 1413 // interval.
1408 bool need_more_pings_at_weak_interval = std::any_of( 1414 bool need_more_pings_at_weak_interval = std::any_of(
1409 connections_.begin(), connections_.end(), [](Connection* conn) { 1415 connections_.begin(), connections_.end(), [](Connection* conn) {
1410 return conn->active() && 1416 return conn->active() &&
1411 conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL; 1417 conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL;
1412 }); 1418 });
1413 int ping_interval = (weak() || need_more_pings_at_weak_interval) 1419 int ping_interval = (weak() || need_more_pings_at_weak_interval)
1414 ? weak_ping_interval_ 1420 ? weak_ping_interval_
1415 : STRONG_PING_INTERVAL; 1421 : STRONG_PING_INTERVAL;
1416 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) { 1422 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) {
1417 Connection* conn = FindNextPingableConnection(); 1423 Connection* conn = FindNextPingableConnection();
1418 if (conn) { 1424 if (conn) {
1419 PingConnection(conn); 1425 PingConnection(conn);
1420 MarkConnectionPinged(conn); 1426 MarkConnectionPinged(conn);
1421 } 1427 }
1422 } 1428 }
1423 int delay = std::min(ping_interval, check_receiving_interval_); 1429 int delay = std::min(ping_interval, check_receiving_interval_);
1424 thread()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_CHECK_AND_PING); 1430 thread()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_CHECK_AND_PING);
1425 } 1431 }
1426 1432
1427 // A connection is considered a backup connection if the channel state 1433 // A connection is considered a backup connection if the channel state
1428 // is completed, the connection is not the selected connection and it is active. 1434 // is completed, the connection is not the selected connection and it is active.
1429 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { 1435 bool P2PTransportChannel::IsBackupConnection(const Connection* conn) const {
1430 return state_ == STATE_COMPLETED && conn != selected_connection_ && 1436 return state_ == STATE_COMPLETED && conn != selected_connection_ &&
1431 conn->active(); 1437 conn->active();
1432 } 1438 }
1433 1439
1434 // Is the connection in a state for us to even consider pinging the other side? 1440 // Is the connection in a state for us to even consider pinging the other side?
1435 // We consider a connection pingable even if it's not connected because that's 1441 // We consider a connection pingable even if it's not connected because that's
1436 // how a TCP connection is kicked into reconnecting on the active side. 1442 // how a TCP connection is kicked into reconnecting on the active side.
1437 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { 1443 bool P2PTransportChannel::IsPingable(const Connection* conn,
1444 int64_t now) const {
1438 const Candidate& remote = conn->remote_candidate(); 1445 const Candidate& remote = conn->remote_candidate();
1439 // We should never get this far with an empty remote ufrag. 1446 // We should never get this far with an empty remote ufrag.
1440 ASSERT(!remote.username().empty()); 1447 ASSERT(!remote.username().empty());
1441 if (remote.username().empty() || remote.password().empty()) { 1448 if (remote.username().empty() || remote.password().empty()) {
1442 // If we don't have an ICE ufrag and pwd, there's no way we can ping. 1449 // If we don't have an ICE ufrag and pwd, there's no way we can ping.
1443 return false; 1450 return false;
1444 } 1451 }
1445 1452
1446 // A failed connection will not be pinged. 1453 // A failed connection will not be pinged.
1447 if (conn->state() == Connection::STATE_FAILED) { 1454 if (conn->state() == Connection::STATE_FAILED) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 bool P2PTransportChannel::IsSelectedConnectionPingable(int64_t now) { 1492 bool P2PTransportChannel::IsSelectedConnectionPingable(int64_t now) {
1486 if (!selected_connection_ || !selected_connection_->connected() || 1493 if (!selected_connection_ || !selected_connection_->connected() ||
1487 !selected_connection_->writable()) { 1494 !selected_connection_->writable()) {
1488 return false; 1495 return false;
1489 } 1496 }
1490 1497
1491 int interval = CalculateActiveWritablePingInterval(selected_connection_, now); 1498 int interval = CalculateActiveWritablePingInterval(selected_connection_, now);
1492 return selected_connection_->last_ping_sent() + interval <= now; 1499 return selected_connection_->last_ping_sent() + interval <= now;
1493 } 1500 }
1494 1501
1495 int P2PTransportChannel::CalculateActiveWritablePingInterval(Connection* conn, 1502 int P2PTransportChannel::CalculateActiveWritablePingInterval(
1496 int64_t now) { 1503 const Connection* conn,
1504 int64_t now) const {
1497 // Ping each connection at a higher rate at least 1505 // Ping each connection at a higher rate at least
1498 // MIN_PINGS_AT_WEAK_PING_INTERVAL times. 1506 // MIN_PINGS_AT_WEAK_PING_INTERVAL times.
1499 if (conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL) { 1507 if (conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL) {
1500 return weak_ping_interval_; 1508 return weak_ping_interval_;
1501 } 1509 }
1502 1510
1503 int stable_interval = config_.stable_writable_connection_ping_interval; 1511 int stable_interval = config_.stable_writable_connection_ping_interval;
1504 int stablizing_interval = 1512 int stablizing_interval =
1505 std::min(stable_interval, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL); 1513 std::min(stable_interval, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
1506 1514
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 // changing from (writable, receiving) to (writable, not receiving). 1579 // changing from (writable, receiving) to (writable, not receiving).
1572 bool strongly_connected = !connection->weak(); 1580 bool strongly_connected = !connection->weak();
1573 bool latest_generation = connection->local_candidate().generation() >= 1581 bool latest_generation = connection->local_candidate().generation() >=
1574 allocator_session()->generation(); 1582 allocator_session()->generation();
1575 if (strongly_connected && latest_generation) { 1583 if (strongly_connected && latest_generation) {
1576 MaybeStopPortAllocatorSessions(); 1584 MaybeStopPortAllocatorSessions();
1577 } 1585 }
1578 1586
1579 // We have to unroll the stack before doing this because we may be changing 1587 // We have to unroll the stack before doing this because we may be changing
1580 // the state of connections while sorting. 1588 // the state of connections while sorting.
1581 RequestSort(); 1589 RequestSortAndStateUpdate();
1582 } 1590 }
1583 1591
1584 // When a connection is removed, edit it out, and then update our best 1592 // When a connection is removed, edit it out, and then update our best
1585 // connection. 1593 // connection.
1586 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { 1594 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
1587 ASSERT(worker_thread_ == rtc::Thread::Current()); 1595 ASSERT(worker_thread_ == rtc::Thread::Current());
1588 1596
1589 // Note: the previous selected_connection_ may be destroyed by now, so don't 1597 // Note: the previous selected_connection_ may be destroyed by now, so don't
1590 // use it. 1598 // use it.
1591 1599
1592 // Remove this connection from the list. 1600 // Remove this connection from the list.
1593 std::vector<Connection*>::iterator iter = 1601 std::vector<Connection*>::iterator iter =
1594 std::find(connections_.begin(), connections_.end(), connection); 1602 std::find(connections_.begin(), connections_.end(), connection);
1595 ASSERT(iter != connections_.end()); 1603 ASSERT(iter != connections_.end());
1596 pinged_connections_.erase(*iter); 1604 pinged_connections_.erase(*iter);
1597 unpinged_connections_.erase(*iter); 1605 unpinged_connections_.erase(*iter);
1598 connections_.erase(iter); 1606 connections_.erase(iter);
1599 1607
1600 LOG_J(LS_INFO, this) << "Removed connection (" 1608 LOG_J(LS_INFO, this) << "Removed connection ("
1601 << static_cast<int>(connections_.size()) << " remaining)"; 1609 << static_cast<int>(connections_.size()) << " remaining)";
1602 1610
1603 // If this is currently the selected connection, then we need to pick a new 1611 // If this is currently the selected connection, then we need to pick a new
1604 // one. The call to SortConnections will pick a new one. It looks at the 1612 // one. The call to SortConnectionsAndUpdateState will pick a new one. It
1605 // current selected connection in order to avoid switching between fairly 1613 // looks at the current selected connection in order to avoid switching
1606 // similar ones. Since this connection is no longer an option, we can just 1614 // between fairly similar ones. Since this connection is no longer an option,
1607 // set selected to nullptr and re-choose a best assuming that there was no 1615 // we can just set selected to nullptr and re-choose a best assuming that
1608 // selected connection. 1616 // there was no selected connection.
1609 if (selected_connection_ == connection) { 1617 if (selected_connection_ == connection) {
1610 LOG(LS_INFO) << "selected connection destroyed. Will choose a new one."; 1618 LOG(LS_INFO) << "selected connection destroyed. Will choose a new one.";
1611 SwitchSelectedConnection(nullptr); 1619 SwitchSelectedConnection(nullptr);
1612 RequestSort(); 1620 RequestSortAndStateUpdate();
1613 } 1621 }
pthatcher1 2016/06/29 17:45:43 Do we need to update the state even if the destroy
Taylor Brandstetter 2016/06/29 18:04:56 You're right; I didn't mean to delete that. But it
1614
1615 UpdateState();
1616 } 1622 }
1617 1623
1618 // When a port is destroyed remove it from our list of ports to use for 1624 // When a port is destroyed remove it from our list of ports to use for
1619 // connection attempts. 1625 // connection attempts.
1620 void P2PTransportChannel::OnPortDestroyed(PortInterface* port) { 1626 void P2PTransportChannel::OnPortDestroyed(PortInterface* port) {
1621 ASSERT(worker_thread_ == rtc::Thread::Current()); 1627 ASSERT(worker_thread_ == rtc::Thread::Current());
1622 1628
1623 // Remove this port from the lists (if we didn't drop it already). 1629 // Remove this port from the lists (if we didn't drop it already).
1624 ports_.erase(std::remove(ports_.begin(), ports_.end(), port), ports_.end()); 1630 ports_.erase(std::remove(ports_.begin(), ports_.end(), port), ports_.end());
1625 removed_ports_.erase( 1631 removed_ports_.erase(
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 1805
1800 // During the initial state when nothing has been pinged yet, return the first 1806 // During the initial state when nothing has been pinged yet, return the first
1801 // one in the ordered |connections_|. 1807 // one in the ordered |connections_|.
1802 return *(std::find_if(connections_.begin(), connections_.end(), 1808 return *(std::find_if(connections_.begin(), connections_.end(),
1803 [conn1, conn2](Connection* conn) { 1809 [conn1, conn2](Connection* conn) {
1804 return conn == conn1 || conn == conn2; 1810 return conn == conn1 || conn == conn2;
1805 })); 1811 }));
1806 } 1812 }
1807 1813
1808 } // namespace cricket 1814 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698