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

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

Issue 2063823008: Adding IceConfig option to assume TURN/TURN candidate pairs will work. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Formatting. Created 4 years, 6 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
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
(...skipping 11 matching lines...) Expand all
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 = 1, MSG_CHECK_AND_PING };
31 31
32 // Mapped write states used by P2PTransportChannel::MappedWriteState.
33 enum {
34 MAPPED_WRITE_STATE_WRITABLE = 1,
35 MAPPED_WRITE_STATE_PROBABLY_WRITABLE,
36 MAPPED_WRITE_STATE_UNRELIABLE,
37 MAPPED_WRITE_STATE_INIT,
38 MAPPED_WRITE_STATE_TIMEOUT
39 };
pthatcher1 2016/06/15 19:12:46 Can we just add Connection::STATE_WRITE_PRESUMED t
40
32 // The minimum improvement in RTT that justifies a switch. 41 // The minimum improvement in RTT that justifies a switch.
33 static const double kMinImprovement = 10; 42 static const double kMinImprovement = 10;
34 43
35 bool IsRelayRelay(cricket::Connection* conn) { 44 bool IsRelayRelay(const cricket::Connection* conn) {
36 return conn->local_candidate().type() == cricket::RELAY_PORT_TYPE && 45 return conn->local_candidate().type() == cricket::RELAY_PORT_TYPE &&
37 conn->remote_candidate().type() == cricket::RELAY_PORT_TYPE; 46 conn->remote_candidate().type() == cricket::RELAY_PORT_TYPE;
38 } 47 }
39 48
40 bool IsUdp(cricket::Connection* conn) { 49 bool IsUdp(cricket::Connection* conn) {
41 return conn->local_candidate().relay_protocol() == cricket::UDP_PROTOCOL_NAME; 50 return conn->local_candidate().relay_protocol() == cricket::UDP_PROTOCOL_NAME;
42 } 51 }
43 52
44 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, 53 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port,
45 cricket::PortInterface* origin_port) { 54 cricket::PortInterface* origin_port) {
46 if (!origin_port) 55 if (!origin_port)
47 return cricket::PortInterface::ORIGIN_MESSAGE; 56 return cricket::PortInterface::ORIGIN_MESSAGE;
48 else if (port == origin_port) 57 else if (port == origin_port)
49 return cricket::PortInterface::ORIGIN_THIS_PORT; 58 return cricket::PortInterface::ORIGIN_THIS_PORT;
50 else 59 else
51 return cricket::PortInterface::ORIGIN_OTHER_PORT; 60 return cricket::PortInterface::ORIGIN_OTHER_PORT;
52 } 61 }
53 62
54 // Compares two connections based only on the candidate and network information.
55 // Returns positive if |a| is better than |b|.
56 int CompareConnectionCandidates(cricket::Connection* a,
57 cricket::Connection* b) {
58 uint32_t a_cost = a->ComputeNetworkCost();
59 uint32_t b_cost = b->ComputeNetworkCost();
60 // Smaller cost is better.
61 if (a_cost < b_cost) {
62 return 1;
63 }
64 if (a_cost > b_cost) {
65 return -1;
66 }
67
68 // Compare connection priority. Lower values get sorted last.
69 if (a->priority() > b->priority())
70 return 1;
71 if (a->priority() < b->priority())
72 return -1;
73
74 // If we're still tied at this point, prefer a younger generation.
75 return (a->remote_candidate().generation() + a->port()->generation()) -
76 (b->remote_candidate().generation() + b->port()->generation());
77 }
78
79 // Compare two connections based on their writing, receiving, and connected
80 // states.
81 int CompareConnectionStates(cricket::Connection* a, cricket::Connection* b) {
82 // Sort based on write-state. Better states have lower values.
83 if (a->write_state() < b->write_state())
84 return 1;
85 if (a->write_state() > b->write_state())
86 return -1;
87
88 // We prefer a receiving connection to a non-receiving, higher-priority
89 // connection when sorting connections and choosing which connection to
90 // switch to.
91 if (a->receiving() && !b->receiving())
92 return 1;
93 if (!a->receiving() && b->receiving())
94 return -1;
95
96 // WARNING: Some complexity here about TCP reconnecting.
97 // When a TCP connection fails because of a TCP socket disconnecting, the
98 // active side of the connection will attempt to reconnect for 5 seconds while
99 // pretending to be writable (the connection is not set to the unwritable
100 // state). On the passive side, the connection also remains writable even
101 // though it is disconnected, and a new connection is created when the active
102 // side connects. At that point, there are two TCP connections on the passive
103 // side: 1. the old, disconnected one that is pretending to be writable, and
104 // 2. the new, connected one that is maybe not yet writable. For purposes of
105 // pruning, pinging, and selecting the best connection, we want to treat the
106 // new connection as "better" than the old one. We could add a method called
107 // something like Connection::ImReallyBadEvenThoughImWritable, but that is
108 // equivalent to the existing Connection::connected(), which we already have.
109 // So, in code throughout this file, we'll check whether the connection is
110 // connected() or not, and if it is not, treat it as "worse" than a connected
111 // one, even though it's writable. In the code below, we're doing so to make
112 // sure we treat a new writable connection as better than an old disconnected
113 // connection.
114
115 // In the case where we reconnect TCP connections, the original best
116 // connection is disconnected without changing to WRITE_TIMEOUT. In this case,
117 // the new connection, when it becomes writable, should have higher priority.
118 if (a->write_state() == cricket::Connection::STATE_WRITABLE &&
119 b->write_state() == cricket::Connection::STATE_WRITABLE) {
120 if (a->connected() && !b->connected()) {
121 return 1;
122 }
123 if (!a->connected() && b->connected()) {
124 return -1;
125 }
126 }
127 return 0;
128 }
129
130 int CompareConnections(cricket::Connection* a, cricket::Connection* b) {
131 int state_cmp = CompareConnectionStates(a, b);
132 if (state_cmp != 0) {
133 return state_cmp;
134 }
135 // Compare the candidate information.
136 return CompareConnectionCandidates(a, b);
137 }
138
139 // Wraps the comparison connection into a less than operator that puts higher
140 // priority writable connections first.
141 class ConnectionCompare {
142 public:
143 bool operator()(const cricket::Connection *ca,
144 const cricket::Connection *cb) {
145 cricket::Connection* a = const_cast<cricket::Connection*>(ca);
146 cricket::Connection* b = const_cast<cricket::Connection*>(cb);
147
148 // Compare first on writability and static preferences.
149 int cmp = CompareConnections(a, b);
150 if (cmp > 0)
151 return true;
152 if (cmp < 0)
153 return false;
154
155 // Otherwise, sort based on latency estimate.
156 return a->rtt() < b->rtt();
157
158 // Should we bother checking for the last connection that last received
159 // data? It would help rendezvous on the connection that is also receiving
160 // packets.
161 //
162 // TODO: Yes we should definitely do this. The TCP protocol gains
163 // efficiency by being used bidirectionally, as opposed to two separate
164 // unidirectional streams. This test should probably occur before
165 // comparison of local prefs (assuming combined prefs are the same). We
166 // need to be careful though, not to bounce back and forth with both sides
167 // trying to rendevous with the other.
168 }
169 };
170
171 // Determines whether we should switch between two connections, based first on
172 // connection states, static preferences, and then (if those are equal) on
173 // latency estimates.
174 bool ShouldSwitch(cricket::Connection* a_conn,
175 cricket::Connection* b_conn,
176 cricket::IceRole ice_role) {
177 if (a_conn == b_conn)
178 return false;
179
180 if (!a_conn || !b_conn) // don't think the latter should happen
181 return true;
182
183 // We prefer to switch to a writable and receiving connection over a
184 // non-writable or non-receiving connection, even if the latter has
185 // been nominated by the controlling side.
186 int state_cmp = CompareConnectionStates(a_conn, b_conn);
187 if (state_cmp != 0) {
188 return state_cmp < 0;
189 }
190 if (ice_role == cricket::ICEROLE_CONTROLLED && a_conn->nominated()) {
191 LOG(LS_VERBOSE) << "Controlled side did not switch due to nominated status";
192 return false;
193 }
194
195 int prefs_cmp = CompareConnectionCandidates(a_conn, b_conn);
196 if (prefs_cmp != 0) {
197 return prefs_cmp < 0;
198 }
199
200 return b_conn->rtt() <= a_conn->rtt() + kMinImprovement;
201 }
202
203 } // unnamed namespace 63 } // unnamed namespace
204 64
205 namespace cricket { 65 namespace cricket {
206 66
207 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) 67 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers)
208 // for pinging. When the socket is writable, we will use only 1 Kbps because 68 // for pinging. When the socket is writable, we will use only 1 Kbps because
209 // we don't want to degrade the quality on a modem. These numbers should work 69 // we don't want to degrade the quality on a modem. These numbers should work
210 // well on a 28.8K modem, which is the slowest connection on which the voice 70 // well on a 28.8K modem, which is the slowest connection on which the voice
211 // quality is reasonable at all. 71 // quality is reasonable at all.
212 static const int PING_PACKET_SIZE = 60 * 8; 72 static const int PING_PACKET_SIZE = 60 * 8;
(...skipping 30 matching lines...) Expand all
243 sort_dirty_(false), 103 sort_dirty_(false),
244 remote_ice_mode_(ICEMODE_FULL), 104 remote_ice_mode_(ICEMODE_FULL),
245 ice_role_(ICEROLE_UNKNOWN), 105 ice_role_(ICEROLE_UNKNOWN),
246 tiebreaker_(0), 106 tiebreaker_(0),
247 gathering_state_(kIceGatheringNew), 107 gathering_state_(kIceGatheringNew),
248 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), 108 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5),
249 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, 109 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */,
250 0 /* backup_connection_ping_interval */, 110 0 /* backup_connection_ping_interval */,
251 false /* gather_continually */, 111 false /* gather_continually */,
252 false /* prioritize_most_likely_candidate_pairs */, 112 false /* prioritize_most_likely_candidate_pairs */,
253 MAX_CURRENT_STRONG_INTERVAL /* max_strong_interval */) { 113 MAX_CURRENT_STRONG_INTERVAL /* max_strong_interval */,
114 true /* turn_to_turn_createpermission_needed */) {
254 uint32_t weak_ping_interval = ::strtoul( 115 uint32_t weak_ping_interval = ::strtoul(
255 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), 116 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(),
256 nullptr, 10); 117 nullptr, 10);
257 if (weak_ping_interval) { 118 if (weak_ping_interval) {
258 weak_ping_interval_ = static_cast<int>(weak_ping_interval); 119 weak_ping_interval_ = static_cast<int>(weak_ping_interval);
259 } 120 }
260 } 121 }
261 122
262 P2PTransportChannel::~P2PTransportChannel() { 123 P2PTransportChannel::~P2PTransportChannel() {
263 ASSERT(worker_thread_ == rtc::Thread::Current()); 124 ASSERT(worker_thread_ == rtc::Thread::Current());
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 config.prioritize_most_likely_candidate_pairs; 292 config.prioritize_most_likely_candidate_pairs;
432 LOG(LS_INFO) << "Set ping most likely connection to " 293 LOG(LS_INFO) << "Set ping most likely connection to "
433 << config_.prioritize_most_likely_candidate_pairs; 294 << config_.prioritize_most_likely_candidate_pairs;
434 295
435 if (config.max_strong_interval >= 0 && 296 if (config.max_strong_interval >= 0 &&
436 config_.max_strong_interval != config.max_strong_interval) { 297 config_.max_strong_interval != config.max_strong_interval) {
437 config_.max_strong_interval = config.max_strong_interval; 298 config_.max_strong_interval = config.max_strong_interval;
438 LOG(LS_INFO) << "Set max strong interval to " 299 LOG(LS_INFO) << "Set max strong interval to "
439 << config_.max_strong_interval; 300 << config_.max_strong_interval;
440 } 301 }
302
303 if (config.turn_to_turn_createpermission_needed !=
304 config_.turn_to_turn_createpermission_needed) {
305 if (!connections_.empty()) {
306 LOG(LS_ERROR) << "Trying to change TURN-TURN CreatePermission needed "
307 << "while connections already exist!";
308 } else {
309 config_.turn_to_turn_createpermission_needed =
310 config.turn_to_turn_createpermission_needed;
311 LOG(LS_INFO) << "Set TURN-TURN CreatePermission needed to "
312 << config_.turn_to_turn_createpermission_needed;
313 }
314 }
pthatcher1 2016/06/15 19:12:46 Why not just allow it and document that it doesn't
Taylor Brandstetter 2016/06/16 00:13:40 It's easier to just disallow it then to allow it i
441 } 315 }
442 316
443 const IceConfig& P2PTransportChannel::config() const { 317 const IceConfig& P2PTransportChannel::config() const {
444 return config_; 318 return config_;
445 } 319 }
446 320
447 // Go into the state of processing candidates, and running in general 321 // Go into the state of processing candidates, and running in general
448 void P2PTransportChannel::Connect() { 322 void P2PTransportChannel::Connect() {
449 ASSERT(worker_thread_ == rtc::Thread::Current()); 323 ASSERT(worker_thread_ == rtc::Thread::Current());
450 if (ice_ufrag_.empty() || ice_pwd_.empty()) { 324 if (ice_ufrag_.empty() || ice_pwd_.empty()) {
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 } 930 }
1057 931
1058 // Prepare for best candidate sorting. 932 // Prepare for best candidate sorting.
1059 void P2PTransportChannel::RequestSort() { 933 void P2PTransportChannel::RequestSort() {
1060 if (!sort_dirty_) { 934 if (!sort_dirty_) {
1061 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT); 935 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT);
1062 sort_dirty_ = true; 936 sort_dirty_ = true;
1063 } 937 }
1064 } 938 }
1065 939
940 int P2PTransportChannel::MappedWriteState(const cricket::Connection* a) const {
941 switch (a->write_state()) {
942 case Connection::STATE_WRITABLE:
943 return MAPPED_WRITE_STATE_WRITABLE;
944 case Connection::STATE_WRITE_UNRELIABLE:
945 return MAPPED_WRITE_STATE_UNRELIABLE;
946 case Connection::STATE_WRITE_INIT:
947 // If the connection hasn't received a binding response, but it's a TURN-
948 // TURN connection and CreatePermission isn't needed, the connection is
949 // "probably writable" which is just a step below writable.
950 if (!config_.turn_to_turn_createpermission_needed && IsRelayRelay(a)) {
951 return MAPPED_WRITE_STATE_PROBABLY_WRITABLE;
952 }
953 return MAPPED_WRITE_STATE_INIT;
954 case Connection::STATE_WRITE_TIMEOUT:
955 return MAPPED_WRITE_STATE_TIMEOUT;
956 default:
957 RTC_DCHECK(false);
958 return MAPPED_WRITE_STATE_TIMEOUT;
honghaiz3 2016/06/15 16:37:18 Should we consider putting the write state mapping
Taylor Brandstetter 2016/06/15 17:08:56 I considered that. But that would mean we'd be let
pthatcher1 2016/06/15 19:12:46 What if we passed the initial Connection state int
honghaiz3 2016/06/15 19:26:36 There is one case in which the write_state reset t
Taylor Brandstetter 2016/06/16 00:13:40 I *really* don't want to pass a state in, or make
959 }
960 }
961
962 // Compare two connections based on their writing, receiving, and connected
963 // states.
964 int P2PTransportChannel::CompareConnectionStates(const Connection* a,
965 const Connection* b) const {
966 // Sort based on write-state. Better states have lower values.
967 if (MappedWriteState(a) < MappedWriteState(b)) {
968 return 1;
969 }
970 if (MappedWriteState(a) > MappedWriteState(b)) {
971 return -1;
972 }
pthatcher1 2016/06/15 19:12:46 This could be like the other comps: // Prefer bett
Taylor Brandstetter 2016/06/16 00:13:41 Done.
973
974 // We prefer a receiving connection to a non-receiving, higher-priority
975 // connection when sorting connections and choosing which connection to
976 // switch to.
977 if (a->receiving() && !b->receiving()) {
978 return 1;
979 }
980 if (!a->receiving() && b->receiving()) {
981 return -1;
982 }
983
984 // WARNING: Some complexity here about TCP reconnecting.
985 // When a TCP connection fails because of a TCP socket disconnecting, the
986 // active side of the connection will attempt to reconnect for 5 seconds while
987 // pretending to be writable (the connection is not set to the unwritable
988 // state). On the passive side, the connection also remains writable even
989 // though it is disconnected, and a new connection is created when the active
990 // side connects. At that point, there are two TCP connections on the passive
991 // side: 1. the old, disconnected one that is pretending to be writable, and
992 // 2. the new, connected one that is maybe not yet writable. For purposes of
993 // pruning, pinging, and selecting the best connection, we want to treat the
994 // new connection as "better" than the old one. We could add a method called
995 // something like Connection::ImReallyBadEvenThoughImWritable, but that is
996 // equivalent to the existing Connection::connected(), which we already have.
997 // So, in code throughout this file, we'll check whether the connection is
998 // connected() or not, and if it is not, treat it as "worse" than a connected
999 // one, even though it's writable. In the code below, we're doing so to make
1000 // sure we treat a new writable connection as better than an old disconnected
1001 // connection.
1002
1003 // In the case where we reconnect TCP connections, the original best
1004 // connection is disconnected without changing to WRITE_TIMEOUT. In this case,
1005 // the new connection, when it becomes writable, should have higher priority.
1006 if (a->write_state() == Connection::STATE_WRITABLE &&
1007 b->write_state() == Connection::STATE_WRITABLE) {
1008 if (a->connected() && !b->connected()) {
1009 return 1;
1010 }
1011 if (!a->connected() && b->connected()) {
1012 return -1;
1013 }
1014 }
1015 return 0;
1016 }
1017
1018 // Compares two connections based only on the candidate and network information.
1019 // Returns positive if |a| is better than |b|.
1020 int P2PTransportChannel::CompareConnectionCandidates(
1021 const Connection* a,
1022 const Connection* b) const {
1023 uint32_t a_cost = a->ComputeNetworkCost();
1024 uint32_t b_cost = b->ComputeNetworkCost();
1025 // Smaller cost is better.
1026 if (a_cost < b_cost) {
1027 return 1;
1028 }
1029 if (a_cost > b_cost) {
1030 return -1;
1031 }
pthatcher1 2016/06/15 19:12:46 To make it a lot like the other comp code, should
Taylor Brandstetter 2016/06/16 00:13:40 Hmm. Now we're talking about subtracting unsigned
pthatcher1 2016/06/16 23:31:36 True.
1032
1033 // Compare connection priority. Lower values get sorted last.
1034 if (a->priority() > b->priority()) {
1035 return 1;
1036 }
1037 if (a->priority() < b->priority()) {
1038 return -1;
1039 }
pthatcher1 2016/06/15 19:12:46 Similarly here: // Prefer higher priority int pri
Taylor Brandstetter 2016/06/16 00:13:40 See above. Plus, these are uint64_t's. Even if we
1040
1041 // If we're still tied at this point, prefer a younger generation.
pthatcher1 2016/06/15 19:12:46 Could you add "(larger generation number)" to make
Taylor Brandstetter 2016/06/16 00:13:40 Done.
1042 return (a->remote_candidate().generation() + a->port()->generation()) -
1043 (b->remote_candidate().generation() + b->port()->generation());
1044 }
1045
1046 int P2PTransportChannel::CompareConnections(const Connection* a,
1047 const Connection* b) const {
1048 // Compare first on writability and static preferences.
1049 int state_cmp = CompareConnectionStates(a, b);
1050 if (state_cmp != 0) {
1051 return state_cmp;
1052 }
1053 // Then compare the candidate information.
1054 int candidates_cmp = CompareConnectionCandidates(a, b);
1055 if (candidates_cmp != 0) {
1056 return candidates_cmp;
1057 }
1058 // Otherwise, compare based on latency estimate.
1059 return b->rtt() - a->rtt();
1060
1061 // Should we bother checking for the last connection that last received
1062 // data? It would help rendezvous on the connection that is also receiving
1063 // packets.
1064 //
1065 // TODO(deadbeef): Yes we should definitely do this. The TCP protocol gains
1066 // efficiency by being used bidirectionally, as opposed to two separate
1067 // unidirectional streams. This test should probably occur before
1068 // comparison of local prefs (assuming combined prefs are the same). We
1069 // need to be careful though, not to bounce back and forth with both sides
1070 // trying to rendevous with the other.
pthatcher1 2016/06/15 19:12:46 That's a good point. It would make sense for the
Taylor Brandstetter 2016/06/16 00:13:40 FYI: I didn't write this comment, I just moved it
1071 }
1072
1073 // Determines whether we should switch between two connections, based first on
1074 // connection states, static preferences, and then (if those are equal) on
1075 // latency estimates.
1076 bool P2PTransportChannel::ShouldSwitch(const Connection* a,
1077 const Connection* b) const {
pthatcher1 2016/06/15 19:12:46 If you're going to move this, we might as well nam
Taylor Brandstetter 2016/06/16 00:13:41 Done.
1078 if (a == b) {
1079 return false;
1080 }
1081
1082 if (!a || !b) { // don't think the latter should happen
1083 return true;
1084 }
pthatcher1 2016/06/15 19:12:46 This might be more readable as: if (!conn) { re
Taylor Brandstetter 2016/06/16 00:13:40 Done.
1085
1086 // We prefer to switch to a writable and receiving connection over a
1087 // non-writable or non-receiving connection, even if the latter has
1088 // been nominated by the controlling side.
1089 int state_cmp = CompareConnectionStates(a, b);
1090 if (state_cmp != 0) {
1091 return state_cmp < 0;
1092 }
1093 if (ice_role_ == ICEROLE_CONTROLLED && a->nominated()) {
pthatcher1 2016/06/15 19:12:46 Would it make sense to have a few helper methods?
Taylor Brandstetter 2016/06/16 00:13:40 We don't need the former function. If the other si
1094 LOG(LS_VERBOSE) << "Controlled side did not switch due to nominated status";
1095 return false;
1096 }
1097
1098 int prefs_cmp = CompareConnectionCandidates(a, b);
1099 if (prefs_cmp != 0) {
1100 return prefs_cmp < 0;
1101 }
1102
1103 return b->rtt() <= a->rtt() + kMinImprovement;
pthatcher1 2016/06/15 19:12:46 This might be more readable as: return (selected-
Taylor Brandstetter 2016/06/16 00:13:40 Done.
1104 }
1105
1066 // Sort the available connections to find the best one. We also monitor 1106 // Sort the available connections to find the best one. We also monitor
1067 // the number of available connections and the current state. 1107 // the number of available connections and the current state.
1068 void P2PTransportChannel::SortConnections() { 1108 void P2PTransportChannel::SortConnections() {
1069 ASSERT(worker_thread_ == rtc::Thread::Current()); 1109 ASSERT(worker_thread_ == rtc::Thread::Current());
1070 1110
1071 // Make sure the connection states are up-to-date since this affects how they 1111 // Make sure the connection states are up-to-date since this affects how they
1072 // will be sorted. 1112 // will be sorted.
1073 UpdateConnectionStates(); 1113 UpdateConnectionStates();
1074 1114
1075 // Any changes after this point will require a re-sort. 1115 // Any changes after this point will require a re-sort.
1076 sort_dirty_ = false; 1116 sort_dirty_ = false;
1077 1117
1078 // Find the best alternative connection by sorting. It is important to note 1118 // Find the best alternative connection by sorting. It is important to note
1079 // that amongst equal preference, writable connections, this will choose the 1119 // that amongst equal preference, writable connections, this will choose the
1080 // one whose estimated latency is lowest. So it is the only one that we 1120 // one whose estimated latency is lowest. So it is the only one that we
1081 // need to consider switching to. 1121 // need to consider switching to.
1082 ConnectionCompare cmp; 1122 std::stable_sort(connections_.begin(), connections_.end(),
1083 std::stable_sort(connections_.begin(), connections_.end(), cmp); 1123 [this](const Connection* a, const Connection* b) {
1124 return CompareConnections(a, b) > 0;
1125 });
1084 LOG(LS_VERBOSE) << "Sorting " << connections_.size() 1126 LOG(LS_VERBOSE) << "Sorting " << connections_.size()
1085 << " available connections:"; 1127 << " available connections:";
1086 for (size_t i = 0; i < connections_.size(); ++i) { 1128 for (size_t i = 0; i < connections_.size(); ++i) {
1087 LOG(LS_VERBOSE) << connections_[i]->ToString(); 1129 LOG(LS_VERBOSE) << connections_[i]->ToString();
1088 } 1130 }
1089 1131
1090 Connection* top_connection = 1132 Connection* top_connection =
1091 (connections_.size() > 0) ? connections_[0] : nullptr; 1133 (connections_.size() > 0) ? connections_[0] : nullptr;
1092 1134
1093 // If necessary, switch to the new choice. 1135 // If necessary, switch to the new choice.
1094 // Note that |top_connection| doesn't have to be writable to become the best 1136 // Note that |top_connection| doesn't have to be writable to become the best
1095 // connection although it will have higher priority if it is writable. 1137 // connection although it will have higher priority if it is writable.
1096 if (ShouldSwitch(best_connection_, top_connection, ice_role_)) { 1138 if (ShouldSwitch(best_connection_, top_connection)) {
1097 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); 1139 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString();
1098 SwitchBestConnectionTo(top_connection); 1140 SwitchBestConnectionTo(top_connection);
1099 } 1141 }
1100 1142
1101 // Controlled side can prune only if the best connection has been nominated. 1143 // Controlled side can prune only if the best connection has been nominated.
1102 // because otherwise it may delete the connection that will be selected by 1144 // because otherwise it may delete the connection that will be selected by
1103 // the controlling side. 1145 // the controlling side.
1104 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { 1146 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) {
1105 PruneConnections(); 1147 PruneConnections();
1106 } 1148 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 RTC_DCHECK(state == STATE_CONNECTING || state == STATE_COMPLETED); 1272 RTC_DCHECK(state == STATE_CONNECTING || state == STATE_COMPLETED);
1231 break; 1273 break;
1232 default: 1274 default:
1233 RTC_DCHECK(false); 1275 RTC_DCHECK(false);
1234 break; 1276 break;
1235 } 1277 }
1236 state_ = state; 1278 state_ = state;
1237 SignalStateChanged(this); 1279 SignalStateChanged(this);
1238 } 1280 }
1239 1281
1240 bool writable = best_connection_ && best_connection_->writable(); 1282 // If our best connection is "probably writable" (TURN-TURN with no
1283 // CreatePermission required), act like we're already writable to the upper
pthatcher1 2016/06/15 19:12:46 I think the phrased "presumed writable" might be s
Taylor Brandstetter 2016/06/16 00:13:41 Done.
1284 // layers, so they can start media quicker.
1285 bool writable =
pthatcher1 2016/06/15 19:12:46 Can we make a method called PresumedWritable()? T
Taylor Brandstetter 2016/06/16 00:13:41 Done.
1286 best_connection_ &&
1287 (MappedWriteState(best_connection_) == MAPPED_WRITE_STATE_WRITABLE ||
1288 MappedWriteState(best_connection_) ==
1289 MAPPED_WRITE_STATE_PROBABLY_WRITABLE);
1241 set_writable(writable); 1290 set_writable(writable);
1242 1291
1243 bool receiving = false; 1292 bool receiving = false;
1244 for (const Connection* connection : connections_) { 1293 for (const Connection* connection : connections_) {
1245 if (connection->receiving()) { 1294 if (connection->receiving()) {
1246 receiving = true; 1295 receiving = true;
1247 break; 1296 break;
1248 } 1297 }
1249 } 1298 }
1250 set_receiving(receiving); 1299 set_receiving(receiving);
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 1737
1689 // During the initial state when nothing has been pinged yet, return the first 1738 // During the initial state when nothing has been pinged yet, return the first
1690 // one in the ordered |connections_|. 1739 // one in the ordered |connections_|.
1691 return *(std::find_if(connections_.begin(), connections_.end(), 1740 return *(std::find_if(connections_.begin(), connections_.end(),
1692 [conn1, conn2](Connection* conn) { 1741 [conn1, conn2](Connection* conn) {
1693 return conn == conn1 || conn == conn2; 1742 return conn == conn1 || conn == conn2;
1694 })); 1743 }));
1695 } 1744 }
1696 1745
1697 } // namespace cricket 1746 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698