OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 ASSERT(worker_thread_ == rtc::Thread::Current()); | 279 ASSERT(worker_thread_ == rtc::Thread::Current()); |
280 if (!ports_.empty()) { | 280 if (!ports_.empty()) { |
281 LOG(LS_ERROR) | 281 LOG(LS_ERROR) |
282 << "Attempt to change tiebreaker after Port has been allocated."; | 282 << "Attempt to change tiebreaker after Port has been allocated."; |
283 return; | 283 return; |
284 } | 284 } |
285 | 285 |
286 tiebreaker_ = tiebreaker; | 286 tiebreaker_ = tiebreaker; |
287 } | 287 } |
288 | 288 |
289 // Currently a channel is considered ICE completed once there is no | 289 // A channel is considered ICE completed once there is at most one active |
290 // more than one connection per Network. This works for a single NIC | 290 // connection per network and at least one active connection. |
291 // with both IPv4 and IPv6 enabled. However, this condition won't | |
292 // happen when there are multiple NICs and all of them have | |
293 // connectivity. | |
294 // TODO(guoweis): Change Completion to be driven by a channel level | |
295 // timer. | |
296 TransportChannelState P2PTransportChannel::GetState() const { | 291 TransportChannelState P2PTransportChannel::GetState() const { |
297 std::set<rtc::Network*> networks; | 292 if (!had_connection_) { |
298 | 293 return TransportChannelState::STATE_INIT; |
299 if (connections_.empty()) { | |
300 return had_connection_ ? TransportChannelState::STATE_FAILED | |
301 : TransportChannelState::STATE_INIT; | |
302 } | 294 } |
303 | 295 |
304 for (uint32 i = 0; i < connections_.size(); ++i) { | 296 std::vector<Connection*> active_connections; |
305 rtc::Network* network = connections_[i]->port()->Network(); | 297 for (Connection* connection : connections_) { |
| 298 if (connection->active()) { |
| 299 active_connections.push_back(connection); |
| 300 } |
| 301 } |
| 302 if (active_connections.empty()) { |
| 303 return TransportChannelState::STATE_FAILED; |
| 304 } |
| 305 |
| 306 std::set<rtc::Network*> networks; |
| 307 for (Connection* connection : active_connections) { |
| 308 rtc::Network* network = connection->port()->Network(); |
306 if (networks.find(network) == networks.end()) { | 309 if (networks.find(network) == networks.end()) { |
307 networks.insert(network); | 310 networks.insert(network); |
308 } else { | 311 } else { |
309 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " | 312 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " |
310 << network->ToString() | 313 << network->ToString() |
311 << " has more than 1 connection."; | 314 << " has more than 1 connection."; |
312 return TransportChannelState::STATE_CONNECTING; | 315 return TransportChannelState::STATE_CONNECTING; |
313 } | 316 } |
314 } | 317 } |
| 318 |
315 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel."; | 319 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel."; |
316 | |
317 return TransportChannelState::STATE_COMPLETED; | 320 return TransportChannelState::STATE_COMPLETED; |
318 } | 321 } |
319 | 322 |
320 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag, | 323 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag, |
321 const std::string& ice_pwd) { | 324 const std::string& ice_pwd) { |
322 ASSERT(worker_thread_ == rtc::Thread::Current()); | 325 ASSERT(worker_thread_ == rtc::Thread::Current()); |
323 ice_ufrag_ = ice_ufrag; | 326 ice_ufrag_ = ice_ufrag; |
324 ice_pwd_ = ice_pwd; | 327 ice_pwd_ = ice_pwd; |
325 // Note: Candidate gathering will restart when MaybeStartGathering is next | 328 // Note: Candidate gathering will restart when MaybeStartGathering is next |
326 // called. | 329 // called. |
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 } | 868 } |
866 return sent; | 869 return sent; |
867 } | 870 } |
868 | 871 |
869 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { | 872 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { |
870 ASSERT(worker_thread_ == rtc::Thread::Current()); | 873 ASSERT(worker_thread_ == rtc::Thread::Current()); |
871 // Gather connection infos. | 874 // Gather connection infos. |
872 infos->clear(); | 875 infos->clear(); |
873 | 876 |
874 std::vector<Connection *>::const_iterator it; | 877 std::vector<Connection *>::const_iterator it; |
875 for (it = connections_.begin(); it != connections_.end(); ++it) { | 878 for (Connection* connection : connections_) { |
876 Connection* connection = *it; | |
877 ConnectionInfo info; | 879 ConnectionInfo info; |
878 info.best_connection = (best_connection_ == connection); | 880 info.best_connection = (best_connection_ == connection); |
879 info.receiving = connection->receiving(); | 881 info.receiving = connection->receiving(); |
880 info.writable = | 882 info.writable = |
881 (connection->write_state() == Connection::STATE_WRITABLE); | 883 (connection->write_state() == Connection::STATE_WRITABLE); |
882 info.timeout = | 884 info.timeout = |
883 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); | 885 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); |
884 info.new_connection = !connection->reported(); | 886 info.new_connection = !connection->reported(); |
885 connection->set_reported(true); | 887 connection->set_reported(true); |
886 info.rtt = connection->rtt(); | 888 info.rtt = connection->rtt(); |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 | 1011 |
1010 // Get a list of the networks that we are using. | 1012 // Get a list of the networks that we are using. |
1011 std::set<rtc::Network*> networks; | 1013 std::set<rtc::Network*> networks; |
1012 for (const Connection* conn : connections_) { | 1014 for (const Connection* conn : connections_) { |
1013 networks.insert(conn->port()->Network()); | 1015 networks.insert(conn->port()->Network()); |
1014 } | 1016 } |
1015 for (rtc::Network* network : networks) { | 1017 for (rtc::Network* network : networks) { |
1016 Connection* premier = GetBestConnectionOnNetwork(network); | 1018 Connection* premier = GetBestConnectionOnNetwork(network); |
1017 // Do not prune connections if the current best connection is weak on this | 1019 // Do not prune connections if the current best connection is weak on this |
1018 // network. Otherwise, it may delete connections prematurely. | 1020 // network. Otherwise, it may delete connections prematurely. |
1019 if (!premier || premier->Weak()) { | 1021 if (!premier || premier->weak()) { |
1020 continue; | 1022 continue; |
1021 } | 1023 } |
1022 | 1024 |
1023 for (Connection* conn : connections_) { | 1025 for (Connection* conn : connections_) { |
1024 if ((conn != premier) && (conn->port()->Network() == network) && | 1026 if ((conn != premier) && (conn->port()->Network() == network) && |
1025 (CompareConnectionCandidates(premier, conn) >= 0)) { | 1027 (CompareConnectionCandidates(premier, conn) >= 0)) { |
1026 conn->Prune(); | 1028 conn->Prune(); |
1027 } | 1029 } |
1028 } | 1030 } |
1029 } | 1031 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 was_writable_ = false; | 1100 was_writable_ = false; |
1099 set_writable(false); | 1101 set_writable(false); |
1100 } | 1102 } |
1101 } | 1103 } |
1102 | 1104 |
1103 void P2PTransportChannel::HandleAllTimedOut() { | 1105 void P2PTransportChannel::HandleAllTimedOut() { |
1104 // Currently we are treating this as channel not writable. | 1106 // Currently we are treating this as channel not writable. |
1105 HandleNotWritable(); | 1107 HandleNotWritable(); |
1106 } | 1108 } |
1107 | 1109 |
1108 bool P2PTransportChannel::Weak() const { | 1110 bool P2PTransportChannel::weak() const { |
1109 return !best_connection_ || best_connection_->Weak(); | 1111 return !best_connection_ || best_connection_->weak(); |
1110 } | 1112 } |
1111 | 1113 |
1112 // If we have a best connection, return it, otherwise return top one in the | 1114 // If we have a best connection, return it, otherwise return top one in the |
1113 // list (later we will mark it best). | 1115 // list (later we will mark it best). |
1114 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( | 1116 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( |
1115 rtc::Network* network) const { | 1117 rtc::Network* network) const { |
1116 // If the best connection is on this network, then it wins. | 1118 // If the best connection is on this network, then it wins. |
1117 if (best_connection_ && (best_connection_->port()->Network() == network)) | 1119 if (best_connection_ && (best_connection_->port()->Network() == network)) |
1118 return best_connection_; | 1120 return best_connection_; |
1119 | 1121 |
(...skipping 27 matching lines...) Expand all Loading... |
1147 SortConnections(); | 1149 SortConnections(); |
1148 } | 1150 } |
1149 | 1151 |
1150 // Handle queued up check-and-ping request | 1152 // Handle queued up check-and-ping request |
1151 void P2PTransportChannel::OnCheckAndPing() { | 1153 void P2PTransportChannel::OnCheckAndPing() { |
1152 // Make sure the states of the connections are up-to-date (since this affects | 1154 // Make sure the states of the connections are up-to-date (since this affects |
1153 // which ones are pingable). | 1155 // which ones are pingable). |
1154 UpdateConnectionStates(); | 1156 UpdateConnectionStates(); |
1155 // When the best connection is either not receiving or not writable, | 1157 // When the best connection is either not receiving or not writable, |
1156 // switch to weak ping delay. | 1158 // switch to weak ping delay. |
1157 int ping_delay = Weak() ? WEAK_PING_DELAY : STRONG_PING_DELAY; | 1159 int ping_delay = weak() ? WEAK_PING_DELAY : STRONG_PING_DELAY; |
1158 if (rtc::Time() >= last_ping_sent_ms_ + ping_delay) { | 1160 if (rtc::Time() >= last_ping_sent_ms_ + ping_delay) { |
1159 Connection* conn = FindNextPingableConnection(); | 1161 Connection* conn = FindNextPingableConnection(); |
1160 if (conn) { | 1162 if (conn) { |
1161 PingConnection(conn); | 1163 PingConnection(conn); |
1162 } | 1164 } |
1163 } | 1165 } |
1164 int check_delay = std::min(ping_delay, check_receiving_delay_); | 1166 int check_delay = std::min(ping_delay, check_receiving_delay_); |
1165 thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING); | 1167 thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING); |
1166 } | 1168 } |
1167 | 1169 |
(...skipping 11 matching lines...) Expand all Loading... |
1179 | 1181 |
1180 // An never connected connection cannot be written to at all, so pinging is | 1182 // An never connected connection cannot be written to at all, so pinging is |
1181 // out of the question. However, if it has become WRITABLE, it is in the | 1183 // out of the question. However, if it has become WRITABLE, it is in the |
1182 // reconnecting state so ping is needed. | 1184 // reconnecting state so ping is needed. |
1183 if (!conn->connected() && !conn->writable()) { | 1185 if (!conn->connected() && !conn->writable()) { |
1184 return false; | 1186 return false; |
1185 } | 1187 } |
1186 | 1188 |
1187 // If the channel is weak, ping all candidates. Otherwise, we only | 1189 // If the channel is weak, ping all candidates. Otherwise, we only |
1188 // want to ping connections that have not timed out on writing. | 1190 // want to ping connections that have not timed out on writing. |
1189 return Weak() || conn->write_state() != Connection::STATE_WRITE_TIMEOUT; | 1191 return weak() || conn->write_state() != Connection::STATE_WRITE_TIMEOUT; |
1190 } | 1192 } |
1191 | 1193 |
1192 // Returns the next pingable connection to ping. This will be the oldest | 1194 // Returns the next pingable connection to ping. This will be the oldest |
1193 // pingable connection unless we have a connected, writable connection that is | 1195 // pingable connection unless we have a connected, writable connection that is |
1194 // past the maximum acceptable ping delay. When reconnecting a TCP connection, | 1196 // past the maximum acceptable ping delay. When reconnecting a TCP connection, |
1195 // the best connection is disconnected, although still WRITABLE while | 1197 // the best connection is disconnected, although still WRITABLE while |
1196 // reconnecting. The newly created connection should be selected as the ping | 1198 // reconnecting. The newly created connection should be selected as the ping |
1197 // target to become writable instead. See the big comment in CompareConnections. | 1199 // target to become writable instead. See the big comment in CompareConnections. |
1198 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1200 Connection* P2PTransportChannel::FindNextPingableConnection() { |
1199 uint32 now = rtc::Time(); | 1201 uint32 now = rtc::Time(); |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1354 } | 1356 } |
1355 } | 1357 } |
1356 | 1358 |
1357 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1359 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
1358 if (connection == best_connection_ && writable()) { | 1360 if (connection == best_connection_ && writable()) { |
1359 SignalReadyToSend(this); | 1361 SignalReadyToSend(this); |
1360 } | 1362 } |
1361 } | 1363 } |
1362 | 1364 |
1363 } // namespace cricket | 1365 } // namespace cricket |
OLD | NEW |