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 |
11 #include "webrtc/p2p/base/p2ptransportchannel.h" | 11 #include "webrtc/p2p/base/p2ptransportchannel.h" |
12 | 12 |
13 #include <set> | 13 #include <set> |
14 #include "webrtc/p2p/base/common.h" | 14 #include "webrtc/p2p/base/common.h" |
15 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE. | 15 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE. |
16 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE. | 16 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE. |
17 #include "webrtc/base/common.h" | 17 #include "webrtc/base/common.h" |
18 #include "webrtc/base/crc32.h" | 18 #include "webrtc/base/crc32.h" |
19 #include "webrtc/base/logging.h" | 19 #include "webrtc/base/logging.h" |
20 #include "webrtc/base/stringencode.h" | 20 #include "webrtc/base/stringencode.h" |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // messages for queuing up work for ourselves | 24 // messages for queuing up work for ourselves |
25 enum { | 25 enum { MSG_SORT = 1, MSG_CHECK_AND_PING }; |
26 MSG_SORT = 1, | |
27 MSG_PING, | |
28 MSG_CHECK_RECEIVING | |
29 }; | |
30 | 26 |
31 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) | 27 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) |
32 // for pinging. When the socket is writable, we will use only 1 Kbps because | 28 // for pinging. When the socket is writable, we will use only 1 Kbps because |
33 // we don't want to degrade the quality on a modem. These numbers should work | 29 // we don't want to degrade the quality on a modem. These numbers should work |
34 // well on a 28.8K modem, which is the slowest connection on which the voice | 30 // well on a 28.8K modem, which is the slowest connection on which the voice |
35 // quality is reasonable at all. | 31 // quality is reasonable at all. |
36 static const uint32 PING_PACKET_SIZE = 60 * 8; | 32 static const uint32 PING_PACKET_SIZE = 60 * 8; |
37 static const uint32 WRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 1000; // 480ms | 33 // STRONG_PING_DELAY (480ms) is applied when the best connection is not |
38 static const uint32 UNWRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 10000; // 50ms | 34 // writable or not receiving. |
| 35 static const uint32 STRONG_PING_DELAY = 1000 * PING_PACKET_SIZE / 1000; |
| 36 // WEAK_PING_DELAY (48ms) is applied when the best connection is both |
| 37 // writable and receiving. |
| 38 static const uint32 WEAK_PING_DELAY = 1000 * PING_PACKET_SIZE / 10000; |
39 | 39 |
40 // If there is a current writable connection, then we will also try hard to | 40 // If there is a current writable connection, then we will also try hard to |
41 // make sure it is pinged at this rate. | 41 // make sure it is pinged at this rate (a little less than |
42 static const uint32 MAX_CURRENT_WRITABLE_DELAY = 900; // 2*WRITABLE_DELAY - bit | 42 // 2 * STRONG_PING_DELAY). |
| 43 static const uint32 MAX_CURRENT_WRITABLE_DELAY = 900; |
43 | 44 |
44 static const int MIN_CHECK_RECEIVING_DELAY = 50; // ms | 45 static const int MIN_CHECK_RECEIVING_DELAY = 50; // ms |
45 | 46 |
46 // The minimum improvement in RTT that justifies a switch. | 47 // The minimum improvement in RTT that justifies a switch. |
47 static const double kMinImprovement = 10; | 48 static const double kMinImprovement = 10; |
48 | 49 |
49 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, | 50 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, |
50 cricket::PortInterface* origin_port) { | 51 cricket::PortInterface* origin_port) { |
51 if (!origin_port) | 52 if (!origin_port) |
52 return cricket::PortInterface::ORIGIN_MESSAGE; | 53 return cricket::PortInterface::ORIGIN_MESSAGE; |
(...skipping 10 matching lines...) Expand all Loading... |
63 if (a->priority() > b->priority()) | 64 if (a->priority() > b->priority()) |
64 return 1; | 65 return 1; |
65 if (a->priority() < b->priority()) | 66 if (a->priority() < b->priority()) |
66 return -1; | 67 return -1; |
67 | 68 |
68 // If we're still tied at this point, prefer a younger generation. | 69 // If we're still tied at this point, prefer a younger generation. |
69 return (a->remote_candidate().generation() + a->port()->generation()) - | 70 return (a->remote_candidate().generation() + a->port()->generation()) - |
70 (b->remote_candidate().generation() + b->port()->generation()); | 71 (b->remote_candidate().generation() + b->port()->generation()); |
71 } | 72 } |
72 | 73 |
73 // Compare two connections based on their connected state, writability and | 74 // Compare two connections based on their writing, receiving, and connected |
74 // static preferences. | 75 // states. |
75 int CompareConnections(cricket::Connection *a, cricket::Connection *b) { | 76 int CompareConnectionStates(cricket::Connection* a, cricket::Connection* b) { |
76 // Sort based on write-state. Better states have lower values. | 77 // Sort based on write-state. Better states have lower values. |
77 if (a->write_state() < b->write_state()) | 78 if (a->write_state() < b->write_state()) |
78 return 1; | 79 return 1; |
79 if (a->write_state() > b->write_state()) | 80 if (a->write_state() > b->write_state()) |
80 return -1; | 81 return -1; |
81 | 82 |
| 83 if (a->receiving() && !b->receiving()) |
| 84 return 1; |
| 85 if (!a->receiving() && b->receiving()) |
| 86 return -1; |
| 87 |
82 // WARNING: Some complexity here about TCP reconnecting. | 88 // WARNING: Some complexity here about TCP reconnecting. |
83 // When a TCP connection fails because of a TCP socket disconnecting, the | 89 // When a TCP connection fails because of a TCP socket disconnecting, the |
84 // active side of the connection will attempt to reconnect for 5 seconds while | 90 // active side of the connection will attempt to reconnect for 5 seconds while |
85 // pretending to be writable (the connection is not set to the unwritable | 91 // pretending to be writable (the connection is not set to the unwritable |
86 // state). On the passive side, the connection also remains writable even | 92 // state). On the passive side, the connection also remains writable even |
87 // though it is disconnected, and a new connection is created when the active | 93 // though it is disconnected, and a new connection is created when the active |
88 // side connects. At that point, there are two TCP connections on the passive | 94 // side connects. At that point, there are two TCP connections on the passive |
89 // side: 1. the old, disconnected one that is pretending to be writable, and | 95 // side: 1. the old, disconnected one that is pretending to be writable, and |
90 // 2. the new, connected one that is maybe not yet writable. For purposes of | 96 // 2. the new, connected one that is maybe not yet writable. For purposes of |
91 // pruning, pinging, and selecting the best connection, we want to treat the | 97 // pruning, pinging, and selecting the best connection, we want to treat the |
(...skipping 11 matching lines...) Expand all Loading... |
103 // the new connection, when it becomes writable, should have higher priority. | 109 // the new connection, when it becomes writable, should have higher priority. |
104 if (a->write_state() == cricket::Connection::STATE_WRITABLE && | 110 if (a->write_state() == cricket::Connection::STATE_WRITABLE && |
105 b->write_state() == cricket::Connection::STATE_WRITABLE) { | 111 b->write_state() == cricket::Connection::STATE_WRITABLE) { |
106 if (a->connected() && !b->connected()) { | 112 if (a->connected() && !b->connected()) { |
107 return 1; | 113 return 1; |
108 } | 114 } |
109 if (!a->connected() && b->connected()) { | 115 if (!a->connected() && b->connected()) { |
110 return -1; | 116 return -1; |
111 } | 117 } |
112 } | 118 } |
| 119 return 0; |
| 120 } |
113 | 121 |
| 122 int CompareConnections(cricket::Connection* a, cricket::Connection* b) { |
| 123 int state_cmp = CompareConnectionStates(a, b); |
| 124 if (state_cmp != 0) { |
| 125 return state_cmp; |
| 126 } |
114 // Compare the candidate information. | 127 // Compare the candidate information. |
115 return CompareConnectionCandidates(a, b); | 128 return CompareConnectionCandidates(a, b); |
116 } | 129 } |
117 | 130 |
118 // Wraps the comparison connection into a less than operator that puts higher | 131 // Wraps the comparison connection into a less than operator that puts higher |
119 // priority writable connections first. | 132 // priority writable connections first. |
120 class ConnectionCompare { | 133 class ConnectionCompare { |
121 public: | 134 public: |
122 bool operator()(const cricket::Connection *ca, | 135 bool operator()(const cricket::Connection *ca, |
123 const cricket::Connection *cb) { | 136 const cricket::Connection *cb) { |
(...skipping 17 matching lines...) Expand all Loading... |
141 // TODO: Yes we should definitely do this. The TCP protocol gains | 154 // TODO: Yes we should definitely do this. The TCP protocol gains |
142 // efficiency by being used bidirectionally, as opposed to two separate | 155 // efficiency by being used bidirectionally, as opposed to two separate |
143 // unidirectional streams. This test should probably occur before | 156 // unidirectional streams. This test should probably occur before |
144 // comparison of local prefs (assuming combined prefs are the same). We | 157 // comparison of local prefs (assuming combined prefs are the same). We |
145 // need to be careful though, not to bounce back and forth with both sides | 158 // need to be careful though, not to bounce back and forth with both sides |
146 // trying to rendevous with the other. | 159 // trying to rendevous with the other. |
147 } | 160 } |
148 }; | 161 }; |
149 | 162 |
150 // Determines whether we should switch between two connections, based first on | 163 // Determines whether we should switch between two connections, based first on |
151 // static preferences and then (if those are equal) on latency estimates. | 164 // connection states, static preferences, and then (if those are equal) on |
152 bool ShouldSwitch(cricket::Connection* a_conn, cricket::Connection* b_conn) { | 165 // latency estimates. |
| 166 bool ShouldSwitch(cricket::Connection* a_conn, |
| 167 cricket::Connection* b_conn, |
| 168 cricket::IceRole ice_role) { |
153 if (a_conn == b_conn) | 169 if (a_conn == b_conn) |
154 return false; | 170 return false; |
155 | 171 |
156 if (!a_conn || !b_conn) // don't think the latter should happen | 172 if (!a_conn || !b_conn) // don't think the latter should happen |
157 return true; | 173 return true; |
158 | 174 |
159 int prefs_cmp = CompareConnections(a_conn, b_conn); | 175 // If the RECEIVING/WRITE/CONNECT states are different, we should switch |
160 if (prefs_cmp < 0) | 176 // regardless of the nominated state. Otherwise, do not switch if |a_conn| is |
161 return true; | 177 // nominated. |
162 if (prefs_cmp > 0) | 178 int state_cmp = CompareConnectionStates(a_conn, b_conn); |
| 179 if (state_cmp != 0) { |
| 180 return state_cmp < 0; |
| 181 } |
| 182 if (ice_role == cricket::ICEROLE_CONTROLLED && a_conn->nominated()) { |
| 183 LOG(LS_VERBOSE) << "Controlled side did not switch due to nominated status"; |
163 return false; | 184 return false; |
| 185 } |
| 186 |
| 187 int prefs_cmp = CompareConnectionCandidates(a_conn, b_conn); |
| 188 if (prefs_cmp != 0) { |
| 189 return prefs_cmp < 0; |
| 190 } |
164 | 191 |
165 return b_conn->rtt() <= a_conn->rtt() + kMinImprovement; | 192 return b_conn->rtt() <= a_conn->rtt() + kMinImprovement; |
166 } | 193 } |
167 | 194 |
168 } // unnamed namespace | 195 } // unnamed namespace |
169 | 196 |
170 namespace cricket { | 197 namespace cricket { |
171 | 198 |
172 P2PTransportChannel::P2PTransportChannel(const std::string& content_name, | 199 P2PTransportChannel::P2PTransportChannel(const std::string& content_name, |
173 int component, | 200 int component, |
174 P2PTransport* transport, | 201 P2PTransport* transport, |
175 PortAllocator *allocator) : | 202 PortAllocator* allocator) |
176 TransportChannelImpl(content_name, component), | 203 : TransportChannelImpl(content_name, component), |
177 transport_(transport), | 204 transport_(transport), |
178 allocator_(allocator), | 205 allocator_(allocator), |
179 worker_thread_(rtc::Thread::Current()), | 206 worker_thread_(rtc::Thread::Current()), |
180 incoming_only_(false), | 207 incoming_only_(false), |
181 waiting_for_signaling_(false), | 208 waiting_for_signaling_(false), |
182 error_(0), | 209 error_(0), |
183 best_connection_(NULL), | 210 best_connection_(nullptr), |
184 pending_best_connection_(NULL), | 211 pending_best_connection_(nullptr), |
185 sort_dirty_(false), | 212 sort_dirty_(false), |
186 was_writable_(false), | 213 was_writable_(false), |
187 remote_ice_mode_(ICEMODE_FULL), | 214 remote_ice_mode_(ICEMODE_FULL), |
188 ice_role_(ICEROLE_UNKNOWN), | 215 ice_role_(ICEROLE_UNKNOWN), |
189 tiebreaker_(0), | 216 tiebreaker_(0), |
190 remote_candidate_generation_(0), | 217 remote_candidate_generation_(0), |
191 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), | 218 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), |
192 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) { | 219 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50), |
193 } | 220 last_ping_sent_(0) {} |
194 | 221 |
195 P2PTransportChannel::~P2PTransportChannel() { | 222 P2PTransportChannel::~P2PTransportChannel() { |
196 ASSERT(worker_thread_ == rtc::Thread::Current()); | 223 ASSERT(worker_thread_ == rtc::Thread::Current()); |
197 | 224 |
198 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) | 225 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) |
199 delete allocator_sessions_[i]; | 226 delete allocator_sessions_[i]; |
200 } | 227 } |
201 | 228 |
202 // Add the allocator session to our list so that we know which sessions | 229 // Add the allocator session to our list so that we know which sessions |
203 // are still active. | 230 // are still active. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 if (!ports_.empty()) { | 276 if (!ports_.empty()) { |
250 LOG(LS_ERROR) | 277 LOG(LS_ERROR) |
251 << "Attempt to change tiebreaker after Port has been allocated."; | 278 << "Attempt to change tiebreaker after Port has been allocated."; |
252 return; | 279 return; |
253 } | 280 } |
254 | 281 |
255 tiebreaker_ = tiebreaker; | 282 tiebreaker_ = tiebreaker; |
256 } | 283 } |
257 | 284 |
258 // Currently a channel is considered ICE completed once there is no | 285 // Currently a channel is considered ICE completed once there is no |
259 // more than one connection per Network. This works for a single NIC | 286 // more than one connection per Network that is not pruned. |
260 // with both IPv4 and IPv6 enabled. However, this condition won't | 287 // If all connections are pruned, declare transport failure. |
261 // happen when there are multiple NICs and all of them have | |
262 // connectivity. | |
263 // TODO(guoweis): Change Completion to be driven by a channel level | |
264 // timer. | |
265 TransportChannelState P2PTransportChannel::GetState() const { | 288 TransportChannelState P2PTransportChannel::GetState() const { |
266 std::set<rtc::Network*> networks; | 289 std::set<rtc::Network*> networks_with_unpruned_connections; |
267 | 290 for (const Connection* connection : connections_) { |
268 if (connections_.size() == 0) { | 291 if (connection->pruned()) { |
269 return TransportChannelState::STATE_FAILED; | 292 continue; |
270 } | 293 } |
271 | 294 rtc::Network* network = connection->port()->Network(); |
272 for (uint32 i = 0; i < connections_.size(); ++i) { | 295 if (networks_with_unpruned_connections.find(network) == |
273 rtc::Network* network = connections_[i]->port()->Network(); | 296 networks_with_unpruned_connections.end()) { |
274 if (networks.find(network) == networks.end()) { | 297 networks_with_unpruned_connections.insert(network); |
275 networks.insert(network); | |
276 } else { | 298 } else { |
277 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " | 299 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " |
278 << network->ToString() | 300 << network->ToString() |
279 << " has more than 1 connection."; | 301 << " has more than 1 connection."; |
280 return TransportChannelState::STATE_CONNECTING; | 302 return TransportChannelState::STATE_CONNECTING; |
281 } | 303 } |
282 } | 304 } |
| 305 if (networks_with_unpruned_connections.size() == 0) { |
| 306 return TransportChannelState::STATE_FAILED; |
| 307 } |
| 308 |
283 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel."; | 309 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel."; |
284 | |
285 return TransportChannelState::STATE_COMPLETED; | 310 return TransportChannelState::STATE_COMPLETED; |
286 } | 311 } |
287 | 312 |
288 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag, | 313 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag, |
289 const std::string& ice_pwd) { | 314 const std::string& ice_pwd) { |
290 ASSERT(worker_thread_ == rtc::Thread::Current()); | 315 ASSERT(worker_thread_ == rtc::Thread::Current()); |
291 bool ice_restart = false; | 316 bool ice_restart = false; |
292 if (!ice_ufrag_.empty() && !ice_pwd_.empty()) { | 317 if (!ice_ufrag_.empty() && !ice_pwd_.empty()) { |
293 // Restart candidate allocation if there is any change in either | 318 // Restart candidate allocation if there is any change in either |
294 // ice ufrag or password. | 319 // ice ufrag or password. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
340 } | 365 } |
341 receiving_timeout_ = receiving_timeout_ms; | 366 receiving_timeout_ = receiving_timeout_ms; |
342 check_receiving_delay_ = | 367 check_receiving_delay_ = |
343 std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); | 368 std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); |
344 | 369 |
345 for (Connection* connection : connections_) { | 370 for (Connection* connection : connections_) { |
346 connection->set_receiving_timeout(receiving_timeout_); | 371 connection->set_receiving_timeout(receiving_timeout_); |
347 } | 372 } |
348 LOG(LS_VERBOSE) << "Set ICE receiving timeout to " << receiving_timeout_ | 373 LOG(LS_VERBOSE) << "Set ICE receiving timeout to " << receiving_timeout_ |
349 << " milliseconds"; | 374 << " milliseconds"; |
| 375 for (Connection* connection : connections_) { |
| 376 connection->set_receiving_timeout(receiving_timeout_); |
| 377 } |
350 } | 378 } |
351 | 379 |
352 // Go into the state of processing candidates, and running in general | 380 // Go into the state of processing candidates, and running in general |
353 void P2PTransportChannel::Connect() { | 381 void P2PTransportChannel::Connect() { |
354 ASSERT(worker_thread_ == rtc::Thread::Current()); | 382 ASSERT(worker_thread_ == rtc::Thread::Current()); |
355 if (ice_ufrag_.empty() || ice_pwd_.empty()) { | 383 if (ice_ufrag_.empty() || ice_pwd_.empty()) { |
356 ASSERT(false); | 384 ASSERT(false); |
357 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " | 385 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " |
358 << "ice_pwd_ are not set."; | 386 << "ice_pwd_ are not set."; |
359 return; | 387 return; |
360 } | 388 } |
361 | 389 |
362 // Kick off an allocator session | 390 // Kick off an allocator session |
363 Allocate(); | 391 Allocate(); |
364 | 392 |
365 // Start pinging as the ports come in. | 393 // Start pinging as the ports come in. |
366 thread()->Post(this, MSG_PING); | 394 thread()->Post(this, MSG_CHECK_AND_PING); |
367 | |
368 thread()->PostDelayed( | |
369 check_receiving_delay_, this, MSG_CHECK_RECEIVING); | |
370 } | 395 } |
371 | 396 |
372 // A new port is available, attempt to make connections for it | 397 // A new port is available, attempt to make connections for it |
373 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session, | 398 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session, |
374 PortInterface* port) { | 399 PortInterface* port) { |
375 ASSERT(worker_thread_ == rtc::Thread::Current()); | 400 ASSERT(worker_thread_ == rtc::Thread::Current()); |
376 | 401 |
377 // Set in-effect options on the new port | 402 // Set in-effect options on the new port |
378 for (OptionMap::const_iterator it = options_.begin(); | 403 for (OptionMap::const_iterator it = options_.begin(); |
379 it != options_.end(); | 404 it != options_.end(); |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
841 } | 866 } |
842 | 867 |
843 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { | 868 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { |
844 ASSERT(worker_thread_ == rtc::Thread::Current()); | 869 ASSERT(worker_thread_ == rtc::Thread::Current()); |
845 // Gather connection infos. | 870 // Gather connection infos. |
846 infos->clear(); | 871 infos->clear(); |
847 | 872 |
848 std::vector<Connection *>::const_iterator it; | 873 std::vector<Connection *>::const_iterator it; |
849 for (it = connections_.begin(); it != connections_.end(); ++it) { | 874 for (it = connections_.begin(); it != connections_.end(); ++it) { |
850 Connection *connection = *it; | 875 Connection *connection = *it; |
| 876 if (connection->pruned() && !connection->receiving()) { |
| 877 continue; |
| 878 } |
851 ConnectionInfo info; | 879 ConnectionInfo info; |
852 info.best_connection = (best_connection_ == connection); | 880 info.best_connection = (best_connection_ == connection); |
853 info.receiving = connection->receiving(); | 881 info.receiving = connection->receiving(); |
854 info.writable = | 882 info.writable = |
855 (connection->write_state() == Connection::STATE_WRITABLE); | 883 (connection->write_state() == Connection::STATE_WRITABLE); |
856 info.timeout = | 884 info.timeout = |
857 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); | 885 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); |
858 info.new_connection = !connection->reported(); | 886 info.new_connection = !connection->reported(); |
859 connection->set_reported(true); | 887 connection->set_reported(true); |
860 info.rtt = connection->rtt(); | 888 info.rtt = connection->rtt(); |
(...skipping 23 matching lines...) Expand all Loading... |
884 // Begin allocate (or immediately re-allocate, if MSG_ALLOCATE pending) | 912 // Begin allocate (or immediately re-allocate, if MSG_ALLOCATE pending) |
885 void P2PTransportChannel::Allocate() { | 913 void P2PTransportChannel::Allocate() { |
886 // Time for a new allocator, lets make sure we have a signalling channel | 914 // Time for a new allocator, lets make sure we have a signalling channel |
887 // to communicate candidates through first. | 915 // to communicate candidates through first. |
888 waiting_for_signaling_ = true; | 916 waiting_for_signaling_ = true; |
889 SignalRequestSignaling(this); | 917 SignalRequestSignaling(this); |
890 } | 918 } |
891 | 919 |
892 // Monitor connection states. | 920 // Monitor connection states. |
893 void P2PTransportChannel::UpdateConnectionStates() { | 921 void P2PTransportChannel::UpdateConnectionStates() { |
894 uint32 now = rtc::Time(); | |
895 | |
896 // We need to copy the list of connections since some may delete themselves | 922 // We need to copy the list of connections since some may delete themselves |
897 // when we call UpdateState. | 923 // when we call UpdateState. |
| 924 uint32 now = rtc::Time(); |
898 for (uint32 i = 0; i < connections_.size(); ++i) | 925 for (uint32 i = 0; i < connections_.size(); ++i) |
899 connections_[i]->UpdateState(now); | 926 connections_[i]->UpdateState(now); |
900 } | 927 } |
901 | 928 |
902 // Prepare for best candidate sorting. | 929 // Prepare for best candidate sorting. |
903 void P2PTransportChannel::RequestSort() { | 930 void P2PTransportChannel::RequestSort() { |
904 if (!sort_dirty_) { | 931 if (!sort_dirty_) { |
905 worker_thread_->Post(this, MSG_SORT); | 932 worker_thread_->Post(this, MSG_SORT); |
906 sort_dirty_ = true; | 933 sort_dirty_ = true; |
907 } | 934 } |
(...skipping 10 matching lines...) Expand all Loading... |
918 | 945 |
919 // Any changes after this point will require a re-sort. | 946 // Any changes after this point will require a re-sort. |
920 sort_dirty_ = false; | 947 sort_dirty_ = false; |
921 | 948 |
922 // Find the best alternative connection by sorting. It is important to note | 949 // Find the best alternative connection by sorting. It is important to note |
923 // that amongst equal preference, writable connections, this will choose the | 950 // that amongst equal preference, writable connections, this will choose the |
924 // one whose estimated latency is lowest. So it is the only one that we | 951 // one whose estimated latency is lowest. So it is the only one that we |
925 // need to consider switching to. | 952 // need to consider switching to. |
926 ConnectionCompare cmp; | 953 ConnectionCompare cmp; |
927 std::stable_sort(connections_.begin(), connections_.end(), cmp); | 954 std::stable_sort(connections_.begin(), connections_.end(), cmp); |
928 LOG(LS_VERBOSE) << "Sorting available connections:"; | 955 LOG(LS_VERBOSE) << "Sorting " << connections_.size() |
| 956 << " available connections:"; |
929 for (uint32 i = 0; i < connections_.size(); ++i) { | 957 for (uint32 i = 0; i < connections_.size(); ++i) { |
930 LOG(LS_VERBOSE) << connections_[i]->ToString(); | 958 LOG(LS_VERBOSE) << connections_[i]->ToString(); |
931 } | 959 } |
932 | 960 |
933 Connection* top_connection = | 961 Connection* top_connection = |
934 (connections_.size() > 0) ? connections_[0] : nullptr; | 962 (connections_.size() > 0) ? connections_[0] : nullptr; |
935 | 963 |
936 // If necessary, switch to the new choice. | 964 // If necessary, switch to the new choice. |
937 // Note that |top_connection| doesn't have to be writable to become the best | 965 // Note that |top_connection| doesn't have to be writable to become the best |
938 // connection although it will have higher priority if it is writable. | 966 // connection although it will have higher priority if it is writable. |
939 // The controlled side can switch the best connection only if the current | 967 if (ShouldSwitch(best_connection_, top_connection, ice_role_)) { |
940 // |best connection_| has not been nominated by the controlling side yet. | |
941 if ((ice_role_ == ICEROLE_CONTROLLING || !best_nominated_connection()) && | |
942 ShouldSwitch(best_connection_, top_connection)) { | |
943 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); | 968 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); |
944 SwitchBestConnectionTo(top_connection); | 969 SwitchBestConnectionTo(top_connection); |
945 } | 970 } |
946 | 971 |
947 // Controlled side can prune only if the best connection has been nominated. | 972 // Controlled side can prune only if the best connection has been nominated. |
948 // because otherwise it may delete the connection that will be selected by | 973 // because otherwise it may delete the connection that will be selected by |
949 // the controlling side. | 974 // the controlling side. |
950 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { | 975 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { |
951 PruneConnections(); | 976 PruneConnections(); |
952 } | 977 } |
(...skipping 27 matching lines...) Expand all Loading... |
980 : nullptr; | 1005 : nullptr; |
981 } | 1006 } |
982 | 1007 |
983 void P2PTransportChannel::PruneConnections() { | 1008 void P2PTransportChannel::PruneConnections() { |
984 // We can prune any connection for which there is a connected, writable | 1009 // We can prune any connection for which there is a connected, writable |
985 // connection on the same network with better or equal priority. We leave | 1010 // connection on the same network with better or equal priority. We leave |
986 // those with better priority just in case they become writable later (at | 1011 // those with better priority just in case they become writable later (at |
987 // which point, we would prune out the current best connection). We leave | 1012 // which point, we would prune out the current best connection). We leave |
988 // connections on other networks because they may not be using the same | 1013 // connections on other networks because they may not be using the same |
989 // resources and they may represent very distinct paths over which we can | 1014 // resources and they may represent very distinct paths over which we can |
990 // switch. If the |primier| connection is not connected, we may be | 1015 // switch. If the |premier| connection is not connected, we may be |
991 // reconnecting a TCP connection and temporarily do not prune connections in | 1016 // reconnecting a TCP connection and temporarily do not prune connections in |
992 // this network. See the big comment in CompareConnections. | 1017 // this network. See the big comment in CompareConnections. |
993 | 1018 |
994 // Get a list of the networks that we are using. | 1019 // Get a list of the networks that we are using. |
995 std::set<rtc::Network*> networks; | 1020 std::set<rtc::Network*> networks; |
996 for (const Connection* conn : connections_) { | 1021 for (const Connection* conn : connections_) { |
997 networks.insert(conn->port()->Network()); | 1022 networks.insert(conn->port()->Network()); |
998 } | 1023 } |
999 for (rtc::Network* network : networks) { | 1024 for (rtc::Network* network : networks) { |
1000 Connection* primier = GetBestConnectionOnNetwork(network); | 1025 Connection* premier = GetBestConnectionOnNetwork(network); |
1001 if (!(primier && primier->writable() && primier->connected())) { | 1026 if (!(premier && premier->writable() && premier->connected())) { |
1002 continue; | 1027 continue; |
1003 } | 1028 } |
1004 | 1029 premier->Unprune(); // Un-prune the premier connection. |
1005 for (Connection* conn : connections_) { | 1030 for (Connection* conn : connections_) { |
1006 if ((conn != primier) && (conn->port()->Network() == network) && | 1031 if ((conn != premier) && (conn->port()->Network() == network) && |
1007 (CompareConnectionCandidates(primier, conn) >= 0)) { | 1032 (CompareConnectionCandidates(premier, conn) >= 0)) { |
1008 conn->Prune(); | 1033 conn->Prune(); |
1009 } | 1034 } |
1010 } | 1035 } |
1011 } | 1036 } |
1012 } | 1037 } |
1013 | 1038 |
1014 // Track the best connection, and let listeners know | 1039 // Track the best connection, and let listeners know |
1015 void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) { | 1040 void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) { |
1016 // Note: if conn is NULL, the previous best_connection_ has been destroyed, | 1041 // Note: if conn is NULL, the previous best_connection_ has been destroyed, |
1017 // so don't use it. | 1042 // so don't use it. |
1018 Connection* old_best_connection = best_connection_; | 1043 Connection* old_best_connection = best_connection_; |
1019 best_connection_ = conn; | 1044 best_connection_ = conn; |
1020 if (best_connection_) { | 1045 if (best_connection_) { |
1021 if (old_best_connection) { | 1046 if (old_best_connection) { |
1022 LOG_J(LS_INFO, this) << "Previous best connection: " | 1047 LOG_J(LS_INFO, this) << "Previous best connection: " |
1023 << old_best_connection->ToString(); | 1048 << old_best_connection->ToString(); |
1024 } | 1049 } |
1025 LOG_J(LS_INFO, this) << "New best connection: " | 1050 LOG_J(LS_INFO, this) << "New best connection: " |
1026 << best_connection_->ToString(); | 1051 << best_connection_->ToString(); |
1027 SignalRouteChange(this, best_connection_->remote_candidate()); | 1052 SignalRouteChange(this, best_connection_->remote_candidate()); |
1028 set_receiving(best_connection_->receiving()); | 1053 set_receiving(best_connection_->receiving()); |
1029 } else { | 1054 } else { |
1030 LOG_J(LS_INFO, this) << "No best connection"; | 1055 LOG_J(LS_INFO, this) << "No best connection"; |
1031 } | 1056 } |
1032 } | 1057 } |
1033 | 1058 |
1034 void P2PTransportChannel::UpdateChannelState() { | 1059 void P2PTransportChannel::UpdateChannelState() { |
1035 // The Handle* functions already set the writable state. We'll just double- | 1060 // The Handle* functions already set the writable state. We'll just double- |
1036 // check it here. | 1061 // check it here. |
1037 bool writable = ((best_connection_ != NULL) && | 1062 bool writable = best_connection_ && best_connection_->writable(); |
1038 (best_connection_->write_state() == | |
1039 Connection::STATE_WRITABLE)); | |
1040 ASSERT(writable == this->writable()); | 1063 ASSERT(writable == this->writable()); |
1041 if (writable != this->writable()) | 1064 if (writable != this->writable()) |
1042 LOG(LS_ERROR) << "UpdateChannelState: writable state mismatch"; | 1065 LOG(LS_ERROR) << "UpdateChannelState: writable state mismatch"; |
1043 | 1066 |
1044 // TODO(honghaiz): The channel receiving state is set in OnCheckReceiving. | 1067 bool receiving = |
1045 // Will revisit in a subsequent code change. | 1068 std::any_of(connections_.begin(), connections_.end(), |
| 1069 [](const Connection* conn) { return conn->receiving(); }); |
| 1070 set_receiving(receiving); |
1046 } | 1071 } |
1047 | 1072 |
1048 // We checked the status of our connections and we had at least one that | 1073 // We checked the status of our connections and we had at least one that |
1049 // was writable, go into the writable state. | 1074 // was writable, go into the writable state. |
1050 void P2PTransportChannel::HandleWritable() { | 1075 void P2PTransportChannel::HandleWritable() { |
1051 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1076 ASSERT(worker_thread_ == rtc::Thread::Current()); |
1052 if (!writable()) { | 1077 if (!writable()) { |
1053 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) { | 1078 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) { |
1054 if (allocator_sessions_[i]->IsGettingPorts()) { | 1079 if (allocator_sessions_[i]->IsGettingPorts()) { |
1055 allocator_sessions_[i]->StopGettingPorts(); | 1080 allocator_sessions_[i]->StopGettingPorts(); |
(...skipping 12 matching lines...) Expand all Loading... |
1068 was_writable_ = false; | 1093 was_writable_ = false; |
1069 set_writable(false); | 1094 set_writable(false); |
1070 } | 1095 } |
1071 } | 1096 } |
1072 | 1097 |
1073 void P2PTransportChannel::HandleAllTimedOut() { | 1098 void P2PTransportChannel::HandleAllTimedOut() { |
1074 // Currently we are treating this as channel not writable. | 1099 // Currently we are treating this as channel not writable. |
1075 HandleNotWritable(); | 1100 HandleNotWritable(); |
1076 } | 1101 } |
1077 | 1102 |
| 1103 bool P2PTransportChannel::Weak() const { |
| 1104 return !(best_connection_ && best_connection_->receiving() && writable()); |
| 1105 } |
| 1106 |
1078 // If we have a best connection, return it, otherwise return top one in the | 1107 // If we have a best connection, return it, otherwise return top one in the |
1079 // list (later we will mark it best). | 1108 // list (later we will mark it best). |
1080 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( | 1109 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( |
1081 rtc::Network* network) const { | 1110 rtc::Network* network) const { |
1082 // If the best connection is on this network, then it wins. | 1111 // If the best connection is on this network, then it wins. |
1083 if (best_connection_ && (best_connection_->port()->Network() == network)) | 1112 if (best_connection_ && (best_connection_->port()->Network() == network)) |
1084 return best_connection_; | 1113 return best_connection_; |
1085 | 1114 |
1086 // Otherwise, we return the top-most in sorted order. | 1115 // Otherwise, we return the top-most in sorted order. |
1087 for (uint32 i = 0; i < connections_.size(); ++i) { | 1116 for (uint32 i = 0; i < connections_.size(); ++i) { |
1088 if (connections_[i]->port()->Network() == network) | 1117 if (connections_[i]->port()->Network() == network) |
1089 return connections_[i]; | 1118 return connections_[i]; |
1090 } | 1119 } |
1091 | 1120 |
1092 return NULL; | 1121 return NULL; |
1093 } | 1122 } |
1094 | 1123 |
1095 // Handle any queued up requests | 1124 // Handle any queued up requests |
1096 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { | 1125 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { |
1097 switch (pmsg->message_id) { | 1126 switch (pmsg->message_id) { |
1098 case MSG_SORT: | 1127 case MSG_SORT: |
1099 OnSort(); | 1128 OnSort(); |
1100 break; | 1129 break; |
1101 case MSG_PING: | 1130 case MSG_CHECK_AND_PING: |
1102 OnPing(); | 1131 OnCheckAndPing(); |
1103 break; | |
1104 case MSG_CHECK_RECEIVING: | |
1105 OnCheckReceiving(); | |
1106 break; | 1132 break; |
1107 default: | 1133 default: |
1108 ASSERT(false); | 1134 ASSERT(false); |
1109 break; | 1135 break; |
1110 } | 1136 } |
1111 } | 1137 } |
1112 | 1138 |
1113 // Handle queued up sort request | 1139 // Handle queued up sort request |
1114 void P2PTransportChannel::OnSort() { | 1140 void P2PTransportChannel::OnSort() { |
1115 // Resort the connections based on the new statistics. | 1141 // Resort the connections based on the new statistics. |
1116 SortConnections(); | 1142 SortConnections(); |
1117 } | 1143 } |
1118 | 1144 |
1119 // Handle queued up ping request | 1145 // Handle queued up check-and-ping request |
1120 void P2PTransportChannel::OnPing() { | 1146 void P2PTransportChannel::OnCheckAndPing() { |
1121 // Make sure the states of the connections are up-to-date (since this affects | 1147 // Make sure the states of the connections are up-to-date (since this affects |
1122 // which ones are pingable). | 1148 // which ones are pingable). |
1123 UpdateConnectionStates(); | 1149 UpdateConnectionStates(); |
1124 | 1150 // When the best connection is either not receiving or not writable, |
1125 // Find the oldest pingable connection and have it do a ping. | 1151 // switch to weak ping delay. |
1126 Connection* conn = FindNextPingableConnection(); | 1152 int ping_delay = Weak() ? WEAK_PING_DELAY : STRONG_PING_DELAY; |
1127 if (conn) | 1153 if (rtc::Time() >= last_ping_sent_ + ping_delay) { |
1128 PingConnection(conn); | 1154 Connection* conn = FindNextPingableConnection(); |
1129 | 1155 if (conn) { |
1130 // Post ourselves a message to perform the next ping. | 1156 PingConnection(conn); |
1131 uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY; | 1157 } |
1132 thread()->PostDelayed(delay, this, MSG_PING); | |
1133 } | |
1134 | |
1135 void P2PTransportChannel::OnCheckReceiving() { | |
1136 if (best_connection_) { | |
1137 bool receiving = rtc::Time() <= | |
1138 best_connection_->last_received() + receiving_timeout_; | |
1139 set_receiving(receiving); | |
1140 } | 1158 } |
1141 | 1159 int check_delay = std::min(ping_delay, check_receiving_delay_); |
1142 thread()->PostDelayed(check_receiving_delay_, this, MSG_CHECK_RECEIVING); | 1160 thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING); |
1143 } | 1161 } |
1144 | 1162 |
1145 // Is the connection in a state for us to even consider pinging the other side? | 1163 // Is the connection in a state for us to even consider pinging the other side? |
1146 // We consider a connection pingable even if it's not connected because that's | 1164 // We consider a connection pingable even if it's not connected because that's |
1147 // how a TCP connection is kicked into reconnecting on the active side. | 1165 // how a TCP connection is kicked into reconnecting on the active side. |
1148 bool P2PTransportChannel::IsPingable(Connection* conn) { | 1166 bool P2PTransportChannel::IsPingable(Connection* conn) { |
1149 const Candidate& remote = conn->remote_candidate(); | 1167 const Candidate& remote = conn->remote_candidate(); |
1150 // We should never get this far with an empty remote ufrag. | 1168 // We should never get this far with an empty remote ufrag. |
1151 ASSERT(!remote.username().empty()); | 1169 ASSERT(!remote.username().empty()); |
1152 if (remote.username().empty() || remote.password().empty()) { | 1170 if (remote.username().empty() || remote.password().empty()) { |
1153 // If we don't have an ICE ufrag and pwd, there's no way we can ping. | 1171 // If we don't have an ICE ufrag and pwd, there's no way we can ping. |
1154 return false; | 1172 return false; |
1155 } | 1173 } |
1156 | 1174 |
1157 // An never connected connection cannot be written to at all, so pinging is | 1175 // An never connected connection cannot be written to at all, so pinging is |
1158 // out of the question. However, if it has become WRITABLE, it is in the | 1176 // out of the question. However, if it has become WRITABLE, it is in the |
1159 // reconnecting state so ping is needed. | 1177 // reconnecting state so ping is needed. |
1160 if (!conn->connected() && !conn->writable()) { | 1178 if (!conn->connected() && !conn->writable()) { |
1161 return false; | 1179 return false; |
1162 } | 1180 } |
1163 | 1181 |
1164 // If the channel is not writable, ping all candidates. Otherwise, we only | 1182 // If the channel is weak, ping all candidates. Otherwise, ping only |
1165 // want to ping connections that have not timed out on writing. | 1183 // un-pruned and not-write-timed-out candidates. |
1166 return !writable() || conn->write_state() != Connection::STATE_WRITE_TIMEOUT; | 1184 return Weak() || (!conn->pruned() && !conn->write_timed_out()); |
1167 } | 1185 } |
1168 | 1186 |
1169 // Returns the next pingable connection to ping. This will be the oldest | 1187 // Returns the next pingable connection to ping. This will be the oldest |
1170 // pingable connection unless we have a connected, writable connection that is | 1188 // pingable connection unless we have a connected, writable connection that is |
1171 // past the maximum acceptable ping delay. When reconnecting a TCP connection, | 1189 // past the maximum acceptable ping delay. When reconnecting a TCP connection, |
1172 // the best connection is disconnected, although still WRITABLE while | 1190 // the best connection is disconnected, although still WRITABLE while |
1173 // reconnecting. The newly created connection should be selected as the ping | 1191 // reconnecting. The newly created connection should be selected as the ping |
1174 // target to become writable instead. See the big comment in CompareConnections. | 1192 // target to become writable instead. See the big comment in CompareConnections. |
1175 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1193 Connection* P2PTransportChannel::FindNextPingableConnection() { |
1176 uint32 now = rtc::Time(); | 1194 uint32 now = rtc::Time(); |
1177 if (best_connection_ && best_connection_->connected() && | 1195 if (best_connection_ && best_connection_->connected() && |
1178 (best_connection_->write_state() == Connection::STATE_WRITABLE) && | 1196 best_connection_->writable() && |
1179 (best_connection_->last_ping_sent() + MAX_CURRENT_WRITABLE_DELAY <= | 1197 (best_connection_->last_ping_sent() + MAX_CURRENT_WRITABLE_DELAY <= |
1180 now)) { | 1198 now)) { |
1181 return best_connection_; | 1199 return best_connection_; |
1182 } | 1200 } |
1183 | 1201 |
1184 // First, find "triggered checks". We ping first those connections | 1202 // First, find "triggered checks". We ping first those connections |
1185 // that have received a ping but have not sent a ping since receiving | 1203 // that have received a ping but have not sent a ping since receiving |
1186 // it (last_received_ping > last_sent_ping). But we shouldn't do | 1204 // it (last_received_ping > last_sent_ping). But we shouldn't do |
1187 // triggered checks if the connection is already writable. | 1205 // triggered checks if the connection is already writable. |
1188 Connection* oldest_needing_triggered_check = nullptr; | 1206 Connection* oldest_needing_triggered_check = nullptr; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1229 bool use_candidate = false; | 1247 bool use_candidate = false; |
1230 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { | 1248 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { |
1231 use_candidate = (conn == best_connection_) || | 1249 use_candidate = (conn == best_connection_) || |
1232 (best_connection_ == NULL) || | 1250 (best_connection_ == NULL) || |
1233 (!best_connection_->writable()) || | 1251 (!best_connection_->writable()) || |
1234 (conn->priority() > best_connection_->priority()); | 1252 (conn->priority() > best_connection_->priority()); |
1235 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { | 1253 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { |
1236 use_candidate = best_connection_->writable(); | 1254 use_candidate = best_connection_->writable(); |
1237 } | 1255 } |
1238 conn->set_use_candidate_attr(use_candidate); | 1256 conn->set_use_candidate_attr(use_candidate); |
1239 conn->Ping(rtc::Time()); | 1257 last_ping_sent_ = rtc::Time(); |
| 1258 conn->Ping(last_ping_sent_); |
1240 } | 1259 } |
1241 | 1260 |
1242 // When a connection's state changes, we need to figure out who to use as | 1261 // When a connection's state changes, we need to figure out who to use as |
1243 // the best connection again. It could have become usable, or become unusable. | 1262 // the best connection again. It could have become usable, or become unusable. |
1244 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { | 1263 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { |
1245 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1264 ASSERT(worker_thread_ == rtc::Thread::Current()); |
1246 | 1265 |
1247 // Update the best connection if the state change is from pending best | 1266 // Update the best connection if the state change is from pending best |
1248 // connection and role is controlled. | 1267 // connection and role is controlled. |
1249 if (ice_role_ == ICEROLE_CONTROLLED) { | 1268 if (ice_role_ == ICEROLE_CONTROLLED) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1316 const rtc::PacketTime& packet_time) { | 1335 const rtc::PacketTime& packet_time) { |
1317 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1336 ASSERT(worker_thread_ == rtc::Thread::Current()); |
1318 | 1337 |
1319 // Do not deliver, if packet doesn't belong to the correct transport channel. | 1338 // Do not deliver, if packet doesn't belong to the correct transport channel. |
1320 if (!FindConnection(connection)) | 1339 if (!FindConnection(connection)) |
1321 return; | 1340 return; |
1322 | 1341 |
1323 // Let the client know of an incoming packet | 1342 // Let the client know of an incoming packet |
1324 SignalReadPacket(this, data, len, packet_time, 0); | 1343 SignalReadPacket(this, data, len, packet_time, 0); |
1325 | 1344 |
1326 // May need to switch the sending connection based on the receiving media path | 1345 // If the receiving connection is different from the sending connection, |
1327 // if this is the controlled side. | 1346 // may need to switch the sending connection based on the receiving media |
1328 if (ice_role_ == ICEROLE_CONTROLLED && !best_nominated_connection() && | 1347 // path if this is the controlled side. It will not switch if the sending |
1329 connection->writable() && best_connection_ != connection) { | 1348 // connection is nominated but the receiving connection is not nominated. |
| 1349 if (best_connection_ != connection && ice_role_ == ICEROLE_CONTROLLED && |
| 1350 (!best_nominated_connection() || connection->nominated()) && |
| 1351 connection->writable()) { |
1330 SwitchBestConnectionTo(connection); | 1352 SwitchBestConnectionTo(connection); |
1331 } | 1353 } |
1332 } | 1354 } |
1333 | 1355 |
1334 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1356 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
1335 if (connection == best_connection_ && writable()) { | 1357 if (connection == best_connection_ && writable()) { |
1336 SignalReadyToSend(this); | 1358 SignalReadyToSend(this); |
1337 } | 1359 } |
1338 } | 1360 } |
1339 | 1361 |
1340 } // namespace cricket | 1362 } // namespace cricket |
OLD | NEW |