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

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: Merge with master again.. 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
« 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
(...skipping 14 matching lines...) Expand all
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 // 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(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) {
41 return conn->local_candidate().relay_protocol() == cricket::UDP_PROTOCOL_NAME; 41 return conn->local_candidate().relay_protocol() == cricket::UDP_PROTOCOL_NAME;
42 } 42 }
43 43
44 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, 44 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port,
45 cricket::PortInterface* origin_port) { 45 cricket::PortInterface* origin_port) {
46 if (!origin_port) 46 if (!origin_port)
47 return cricket::PortInterface::ORIGIN_MESSAGE; 47 return cricket::PortInterface::ORIGIN_MESSAGE;
48 else if (port == origin_port) 48 else if (port == origin_port)
49 return cricket::PortInterface::ORIGIN_THIS_PORT; 49 return cricket::PortInterface::ORIGIN_THIS_PORT;
50 else 50 else
51 return cricket::PortInterface::ORIGIN_OTHER_PORT; 51 return cricket::PortInterface::ORIGIN_OTHER_PORT;
52 } 52 }
53 53
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 54 } // unnamed namespace
204 55
205 namespace cricket { 56 namespace cricket {
206 57
207 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) 58 // 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 59 // 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 60 // 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 61 // well on a 28.8K modem, which is the slowest connection on which the voice
211 // quality is reasonable at all. 62 // quality is reasonable at all.
212 static const int PING_PACKET_SIZE = 60 * 8; 63 static const int PING_PACKET_SIZE = 60 * 8;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 sort_dirty_(false), 95 sort_dirty_(false),
245 remote_ice_mode_(ICEMODE_FULL), 96 remote_ice_mode_(ICEMODE_FULL),
246 ice_role_(ICEROLE_UNKNOWN), 97 ice_role_(ICEROLE_UNKNOWN),
247 tiebreaker_(0), 98 tiebreaker_(0),
248 gathering_state_(kIceGatheringNew), 99 gathering_state_(kIceGatheringNew),
249 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), 100 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5),
250 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, 101 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */,
251 0 /* backup_connection_ping_interval */, 102 0 /* backup_connection_ping_interval */,
252 false /* gather_continually */, 103 false /* gather_continually */,
253 false /* prioritize_most_likely_candidate_pairs */, 104 false /* prioritize_most_likely_candidate_pairs */,
254 STABLE_WRITABLE_CONNECTION_PING_INTERVAL) { 105 STABLE_WRITABLE_CONNECTION_PING_INTERVAL,
106 true /* presume_writable_when_fully_relayed */) {
255 uint32_t weak_ping_interval = ::strtoul( 107 uint32_t weak_ping_interval = ::strtoul(
256 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), 108 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(),
257 nullptr, 10); 109 nullptr, 10);
258 if (weak_ping_interval) { 110 if (weak_ping_interval) {
259 weak_ping_interval_ = static_cast<int>(weak_ping_interval); 111 weak_ping_interval_ = static_cast<int>(weak_ping_interval);
260 } 112 }
261 } 113 }
262 114
263 P2PTransportChannel::~P2PTransportChannel() { 115 P2PTransportChannel::~P2PTransportChannel() {
264 ASSERT(worker_thread_ == rtc::Thread::Current()); 116 ASSERT(worker_thread_ == rtc::Thread::Current());
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 << config_.prioritize_most_likely_candidate_pairs; 291 << config_.prioritize_most_likely_candidate_pairs;
440 292
441 if (config.stable_writable_connection_ping_interval >= 0 && 293 if (config.stable_writable_connection_ping_interval >= 0 &&
442 config_.stable_writable_connection_ping_interval != 294 config_.stable_writable_connection_ping_interval !=
443 config.stable_writable_connection_ping_interval) { 295 config.stable_writable_connection_ping_interval) {
444 config_.stable_writable_connection_ping_interval = 296 config_.stable_writable_connection_ping_interval =
445 config.stable_writable_connection_ping_interval; 297 config.stable_writable_connection_ping_interval;
446 LOG(LS_INFO) << "Set stable_writable_connection_ping_interval to " 298 LOG(LS_INFO) << "Set stable_writable_connection_ping_interval to "
447 << config_.stable_writable_connection_ping_interval; 299 << config_.stable_writable_connection_ping_interval;
448 } 300 }
301
302 if (config.presume_writable_when_fully_relayed !=
303 config_.presume_writable_when_fully_relayed) {
304 if (!connections_.empty()) {
305 LOG(LS_ERROR) << "Trying to change 'presume writable' "
306 << "while connections already exist!";
307 } else {
308 config_.presume_writable_when_fully_relayed =
309 config.presume_writable_when_fully_relayed;
310 LOG(LS_INFO) << "Set presume writable when fully relayed to "
311 << config_.presume_writable_when_fully_relayed;
312 }
313 }
449 } 314 }
450 315
451 const IceConfig& P2PTransportChannel::config() const { 316 const IceConfig& P2PTransportChannel::config() const {
452 return config_; 317 return config_;
453 } 318 }
454 319
455 // Go into the state of processing candidates, and running in general 320 // Go into the state of processing candidates, and running in general
456 void P2PTransportChannel::Connect() { 321 void P2PTransportChannel::Connect() {
457 ASSERT(worker_thread_ == rtc::Thread::Current()); 322 ASSERT(worker_thread_ == rtc::Thread::Current());
458 if (ice_ufrag_.empty() || ice_pwd_.empty()) { 323 if (ice_ufrag_.empty() || ice_pwd_.empty()) {
(...skipping 583 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 } 907 }
1043 908
1044 // Prepare for best candidate sorting. 909 // Prepare for best candidate sorting.
1045 void P2PTransportChannel::RequestSort() { 910 void P2PTransportChannel::RequestSort() {
1046 if (!sort_dirty_) { 911 if (!sort_dirty_) {
1047 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT); 912 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT);
1048 sort_dirty_ = true; 913 sort_dirty_ = true;
1049 } 914 }
1050 } 915 }
1051 916
917 // Compare two connections based on their writing, receiving, and connected
918 // states.
919 int P2PTransportChannel::CompareConnectionStates(const Connection* a,
920 const Connection* b) const {
921 static constexpr int a_is_better = 1;
922 static constexpr int b_is_better = -1;
923
924 // First, prefer a connection that's writable or presumed writable over
925 // one that's not writable.
926 bool a_writable = a->writable() || PresumedWritable(a);
927 bool b_writable = b->writable() || PresumedWritable(b);
928 if (a_writable && !b_writable) {
929 return a_is_better;
930 }
931 if (!a_writable && b_writable) {
932 return b_is_better;
933 }
934
935 // Sort based on write-state. Better states have lower values.
936 if (a->write_state() < b->write_state()) {
937 return a_is_better;
938 }
939 if (b->write_state() < a->write_state()) {
940 return b_is_better;
941 }
942
943 // We prefer a receiving connection to a non-receiving, higher-priority
944 // connection when sorting connections and choosing which connection to
945 // switch to.
946 if (a->receiving() && !b->receiving()) {
947 return a_is_better;
948 }
949 if (!a->receiving() && b->receiving()) {
950 return b_is_better;
951 }
952
953 // WARNING: Some complexity here about TCP reconnecting.
954 // When a TCP connection fails because of a TCP socket disconnecting, the
955 // active side of the connection will attempt to reconnect for 5 seconds while
956 // pretending to be writable (the connection is not set to the unwritable
957 // state). On the passive side, the connection also remains writable even
958 // though it is disconnected, and a new connection is created when the active
959 // side connects. At that point, there are two TCP connections on the passive
960 // side: 1. the old, disconnected one that is pretending to be writable, and
961 // 2. the new, connected one that is maybe not yet writable. For purposes of
962 // pruning, pinging, and selecting the best connection, we want to treat the
963 // new connection as "better" than the old one. We could add a method called
964 // something like Connection::ImReallyBadEvenThoughImWritable, but that is
965 // equivalent to the existing Connection::connected(), which we already have.
966 // So, in code throughout this file, we'll check whether the connection is
967 // connected() or not, and if it is not, treat it as "worse" than a connected
968 // one, even though it's writable. In the code below, we're doing so to make
969 // sure we treat a new writable connection as better than an old disconnected
970 // connection.
971
972 // In the case where we reconnect TCP connections, the original best
973 // connection is disconnected without changing to WRITE_TIMEOUT. In this case,
974 // the new connection, when it becomes writable, should have higher priority.
975 if (a->write_state() == Connection::STATE_WRITABLE &&
976 b->write_state() == Connection::STATE_WRITABLE) {
977 if (a->connected() && !b->connected()) {
978 return a_is_better;
979 }
980 if (!a->connected() && b->connected()) {
981 return b_is_better;
982 }
983 }
984 return 0;
985 }
986
987 // Compares two connections based only on the candidate and network information.
988 // Returns positive if |a| is better than |b|.
989 int P2PTransportChannel::CompareConnectionCandidates(
990 const Connection* a,
991 const Connection* b) const {
992 // Prefer lower network cost.
993 uint32_t a_cost = a->ComputeNetworkCost();
994 uint32_t b_cost = b->ComputeNetworkCost();
995 // Smaller cost is better.
996 if (a_cost < b_cost) {
997 return 1;
998 }
999 if (a_cost > b_cost) {
1000 return -1;
1001 }
1002
1003 // Compare connection priority. Lower values get sorted last.
1004 if (a->priority() > b->priority()) {
1005 return 1;
1006 }
1007 if (a->priority() < b->priority()) {
1008 return -1;
1009 }
1010
1011 // If we're still tied at this point, prefer a younger generation.
1012 // (Younger generation means a larger generation number).
1013 return (a->remote_candidate().generation() + a->port()->generation()) -
1014 (b->remote_candidate().generation() + b->port()->generation());
1015 }
1016
1017 int P2PTransportChannel::CompareConnections(const Connection* a,
1018 const Connection* b) const {
1019 // Compare first on writability and static preferences.
1020 int state_cmp = CompareConnectionStates(a, b);
1021 if (state_cmp != 0) {
1022 return state_cmp;
1023 }
1024 // Then compare the candidate information.
1025 int candidates_cmp = CompareConnectionCandidates(a, b);
1026 if (candidates_cmp != 0) {
1027 return candidates_cmp;
1028 }
1029 // Otherwise, compare based on latency estimate.
1030 return b->rtt() - a->rtt();
1031
1032 // Should we bother checking for the last connection that last received
1033 // data? It would help rendezvous on the connection that is also receiving
1034 // packets.
1035 //
1036 // TODO(deadbeef): Yes we should definitely do this. The TCP protocol gains
1037 // efficiency by being used bidirectionally, as opposed to two separate
1038 // unidirectional streams. This test should probably occur before
1039 // comparison of local prefs (assuming combined prefs are the same). We
1040 // need to be careful though, not to bounce back and forth with both sides
1041 // trying to rendevous with the other.
1042 }
1043
1044 bool P2PTransportChannel::PresumedWritable(
1045 const cricket::Connection* conn) const {
1046 return (conn->write_state() == Connection::STATE_WRITE_INIT &&
1047 config_.presume_writable_when_fully_relayed &&
1048 conn->local_candidate().type() == RELAY_PORT_TYPE &&
1049 (conn->remote_candidate().type() == RELAY_PORT_TYPE ||
1050 conn->remote_candidate().type() == PRFLX_PORT_TYPE));
1051 }
1052
1053 // Determines whether we should switch between two connections, based first on
1054 // connection states, static preferences, and then (if those are equal) on
1055 // latency estimates.
1056 bool P2PTransportChannel::ShouldSwitchSelectedConnection(
1057 const Connection* selected,
1058 const Connection* conn) const {
1059 if (selected == conn) {
1060 return false;
1061 }
1062
1063 if (!selected || !conn) { // don't think the latter should happen
1064 return true;
1065 }
1066
1067 // We prefer to switch to a writable and receiving connection over a
1068 // non-writable or non-receiving connection, even if the latter has
1069 // been nominated by the controlling side.
1070 int state_cmp = CompareConnectionStates(selected, conn);
1071 if (state_cmp != 0) {
1072 return state_cmp < 0;
1073 }
1074 if (ice_role_ == ICEROLE_CONTROLLED && selected->nominated()) {
1075 LOG(LS_VERBOSE) << "Controlled side did not switch due to nominated status";
1076 return false;
1077 }
1078
1079 int prefs_cmp = CompareConnectionCandidates(selected, conn);
1080 if (prefs_cmp != 0) {
1081 return prefs_cmp < 0;
1082 }
1083
1084 return selected->rtt() - conn->rtt() >= kMinImprovement;
1085 }
1086
1052 // Sort the available connections to find the best one. We also monitor 1087 // Sort the available connections to find the best one. We also monitor
1053 // the number of available connections and the current state. 1088 // the number of available connections and the current state.
1054 void P2PTransportChannel::SortConnections() { 1089 void P2PTransportChannel::SortConnections() {
1055 ASSERT(worker_thread_ == rtc::Thread::Current()); 1090 ASSERT(worker_thread_ == rtc::Thread::Current());
1056 1091
1057 // Make sure the connection states are up-to-date since this affects how they 1092 // Make sure the connection states are up-to-date since this affects how they
1058 // will be sorted. 1093 // will be sorted.
1059 UpdateConnectionStates(); 1094 UpdateConnectionStates();
1060 1095
1061 // Any changes after this point will require a re-sort. 1096 // Any changes after this point will require a re-sort.
1062 sort_dirty_ = false; 1097 sort_dirty_ = false;
1063 1098
1064 // Find the best alternative connection by sorting. It is important to note 1099 // Find the best alternative connection by sorting. It is important to note
1065 // that amongst equal preference, writable connections, this will choose the 1100 // that amongst equal preference, writable connections, this will choose the
1066 // one whose estimated latency is lowest. So it is the only one that we 1101 // one whose estimated latency is lowest. So it is the only one that we
1067 // need to consider switching to. 1102 // need to consider switching to.
1068 ConnectionCompare cmp; 1103 std::stable_sort(connections_.begin(), connections_.end(),
1069 std::stable_sort(connections_.begin(), connections_.end(), cmp); 1104 [this](const Connection* a, const Connection* b) {
1105 return CompareConnections(a, b) > 0;
1106 });
1070 LOG(LS_VERBOSE) << "Sorting " << connections_.size() 1107 LOG(LS_VERBOSE) << "Sorting " << connections_.size()
1071 << " available connections:"; 1108 << " available connections:";
1072 for (size_t i = 0; i < connections_.size(); ++i) { 1109 for (size_t i = 0; i < connections_.size(); ++i) {
1073 LOG(LS_VERBOSE) << connections_[i]->ToString(); 1110 LOG(LS_VERBOSE) << connections_[i]->ToString();
1074 } 1111 }
1075 1112
1076 Connection* top_connection = 1113 Connection* top_connection =
1077 (connections_.size() > 0) ? connections_[0] : nullptr; 1114 (connections_.size() > 0) ? connections_[0] : nullptr;
1078 1115
1079 // If necessary, switch to the new choice. 1116 // If necessary, switch to the new choice.
1080 // Note that |top_connection| doesn't have to be writable to become the best 1117 // Note that |top_connection| doesn't have to be writable to become the best
1081 // connection although it will have higher priority if it is writable. 1118 // connection although it will have higher priority if it is writable.
1082 if (ShouldSwitch(best_connection_, top_connection, ice_role_)) { 1119 if (ShouldSwitchSelectedConnection(best_connection_, top_connection)) {
1083 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); 1120 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString();
1084 SwitchBestConnectionTo(top_connection); 1121 SwitchBestConnectionTo(top_connection);
1085 } 1122 }
1086 1123
1087 // Controlled side can prune only if the best connection has been nominated. 1124 // Controlled side can prune only if the best connection has been nominated.
1088 // because otherwise it may delete the connection that will be selected by 1125 // because otherwise it may delete the connection that will be selected by
1089 // the controlling side. 1126 // the controlling side.
1090 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { 1127 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) {
1091 PruneConnections(); 1128 PruneConnections();
1092 } 1129 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 << old_best_connection->ToString(); 1198 << old_best_connection->ToString();
1162 } 1199 }
1163 LOG_J(LS_INFO, this) << "New best connection: " 1200 LOG_J(LS_INFO, this) << "New best connection: "
1164 << best_connection_->ToString(); 1201 << best_connection_->ToString();
1165 SignalRouteChange(this, best_connection_->remote_candidate()); 1202 SignalRouteChange(this, best_connection_->remote_candidate());
1166 // This is a temporary, but safe fix to webrtc issue 5705. 1203 // This is a temporary, but safe fix to webrtc issue 5705.
1167 // TODO(honghaiz): Make all EWOULDBLOCK error routed through the transport 1204 // TODO(honghaiz): Make all EWOULDBLOCK error routed through the transport
1168 // channel so that it knows whether the media channel is allowed to 1205 // channel so that it knows whether the media channel is allowed to
1169 // send; then it will only signal ready-to-send if the media channel 1206 // send; then it will only signal ready-to-send if the media channel
1170 // has been disallowed to send. 1207 // has been disallowed to send.
1171 if (best_connection_->writable()) { 1208 if (best_connection_->writable() || PresumedWritable(best_connection_)) {
1172 SignalReadyToSend(this); 1209 SignalReadyToSend(this);
1173 } 1210 }
1174 } else { 1211 } else {
1175 LOG_J(LS_INFO, this) << "No best connection"; 1212 LOG_J(LS_INFO, this) << "No best connection";
1176 } 1213 }
1177 // TODO(honghaiz): rename best_connection_ with selected_connection_ or 1214 // TODO(honghaiz): rename best_connection_ with selected_connection_ or
1178 // selected_candidate pair_. 1215 // selected_candidate pair_.
1179 SignalSelectedCandidatePairChanged(this, best_connection_, 1216 SignalSelectedCandidatePairChanged(this, best_connection_,
1180 last_sent_packet_id_); 1217 last_sent_packet_id_);
1181 } 1218 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1216 RTC_DCHECK(state == STATE_CONNECTING || state == STATE_COMPLETED); 1253 RTC_DCHECK(state == STATE_CONNECTING || state == STATE_COMPLETED);
1217 break; 1254 break;
1218 default: 1255 default:
1219 RTC_DCHECK(false); 1256 RTC_DCHECK(false);
1220 break; 1257 break;
1221 } 1258 }
1222 state_ = state; 1259 state_ = state;
1223 SignalStateChanged(this); 1260 SignalStateChanged(this);
1224 } 1261 }
1225 1262
1226 bool writable = best_connection_ && best_connection_->writable(); 1263 // If our best connection is "presumed writable" (TURN-TURN with no
1227 set_writable(writable); 1264 // CreatePermission required), act like we're already writable to the upper
1265 // layers, so they can start media quicker.
1266 set_writable(best_connection_ && (best_connection_->writable() ||
1267 PresumedWritable(best_connection_)));
1228 1268
1229 bool receiving = false; 1269 bool receiving = false;
1230 for (const Connection* connection : connections_) { 1270 for (const Connection* connection : connections_) {
1231 if (connection->receiving()) { 1271 if (connection->receiving()) {
1232 receiving = true; 1272 receiving = true;
1233 break; 1273 break;
1234 } 1274 }
1235 } 1275 }
1236 set_receiving(receiving); 1276 set_receiving(receiving);
1237 } 1277 }
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1715 1755
1716 // During the initial state when nothing has been pinged yet, return the first 1756 // During the initial state when nothing has been pinged yet, return the first
1717 // one in the ordered |connections_|. 1757 // one in the ordered |connections_|.
1718 return *(std::find_if(connections_.begin(), connections_.end(), 1758 return *(std::find_if(connections_.begin(), connections_.end(),
1719 [conn1, conn2](Connection* conn) { 1759 [conn1, conn2](Connection* conn) {
1720 return conn == conn1 || conn == conn2; 1760 return conn == conn1 || conn == conn2;
1721 })); 1761 }));
1722 } 1762 }
1723 1763
1724 } // namespace cricket 1764 } // 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