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

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

Issue 1246913005: TransportController refactoring (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fixing problems with "failed" state; a channel isn't failed if it's never added a connection Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/p2p/base/p2ptransportchannel.h" 11 #include "webrtc/p2p/base/p2ptransportchannel.h"
12 12
13 #include <set> 13 #include <set>
14 #include <algorithm>
14 #include "webrtc/p2p/base/common.h" 15 #include "webrtc/p2p/base/common.h"
15 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE. 16 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE.
16 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE. 17 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE.
17 #include "webrtc/base/common.h" 18 #include "webrtc/base/common.h"
18 #include "webrtc/base/crc32.h" 19 #include "webrtc/base/crc32.h"
19 #include "webrtc/base/logging.h" 20 #include "webrtc/base/logging.h"
20 #include "webrtc/base/stringencode.h" 21 #include "webrtc/base/stringencode.h"
21 22
22 namespace { 23 namespace {
23 24
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 return b_conn->rtt() <= a_conn->rtt() + kMinImprovement; 174 return b_conn->rtt() <= a_conn->rtt() + kMinImprovement;
174 } 175 }
175 176
176 } // unnamed namespace 177 } // unnamed namespace
177 178
178 namespace cricket { 179 namespace cricket {
179 180
180 P2PTransportChannel::P2PTransportChannel(const std::string& content_name, 181 P2PTransportChannel::P2PTransportChannel(const std::string& content_name,
181 int component, 182 int component,
182 P2PTransport* transport, 183 P2PTransport* transport,
183 PortAllocator *allocator) : 184 PortAllocator* allocator)
184 TransportChannelImpl(content_name, component), 185 : TransportChannelImpl(content_name, component),
185 transport_(transport), 186 transport_(transport),
186 allocator_(allocator), 187 allocator_(allocator),
187 worker_thread_(rtc::Thread::Current()), 188 worker_thread_(rtc::Thread::Current()),
188 incoming_only_(false), 189 incoming_only_(false),
189 waiting_for_signaling_(false), 190 error_(0),
190 error_(0), 191 best_connection_(NULL),
191 best_connection_(NULL), 192 pending_best_connection_(NULL),
192 pending_best_connection_(NULL), 193 sort_dirty_(false),
193 sort_dirty_(false), 194 was_writable_(false),
194 was_writable_(false), 195 protocol_type_(ICEPROTO_HYBRID),
195 protocol_type_(ICEPROTO_HYBRID), 196 remote_ice_mode_(ICEMODE_FULL),
196 remote_ice_mode_(ICEMODE_FULL), 197 ice_role_(ICEROLE_UNKNOWN),
197 ice_role_(ICEROLE_UNKNOWN), 198 tiebreaker_(0),
198 tiebreaker_(0), 199 remote_candidate_generation_(0),
199 remote_candidate_generation_(0), 200 gathering_state_(kIceGatheringNew),
200 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), 201 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5),
201 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) { 202 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) {
202 } 203 }
203 204
204 P2PTransportChannel::~P2PTransportChannel() { 205 P2PTransportChannel::~P2PTransportChannel() {
205 ASSERT(worker_thread_ == rtc::Thread::Current()); 206 ASSERT(worker_thread_ == rtc::Thread::Current());
206 207
207 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) 208 for (uint32 i = 0; i < allocator_sessions_.size(); ++i)
208 delete allocator_sessions_[i]; 209 delete allocator_sessions_[i];
209 } 210 }
210 211
211 // Add the allocator session to our list so that we know which sessions 212 // Add the allocator session to our list so that we know which sessions
(...skipping 21 matching lines...) Expand all
233 connection->SignalReadPacket.connect( 234 connection->SignalReadPacket.connect(
234 this, &P2PTransportChannel::OnReadPacket); 235 this, &P2PTransportChannel::OnReadPacket);
235 connection->SignalReadyToSend.connect( 236 connection->SignalReadyToSend.connect(
236 this, &P2PTransportChannel::OnReadyToSend); 237 this, &P2PTransportChannel::OnReadyToSend);
237 connection->SignalStateChange.connect( 238 connection->SignalStateChange.connect(
238 this, &P2PTransportChannel::OnConnectionStateChange); 239 this, &P2PTransportChannel::OnConnectionStateChange);
239 connection->SignalDestroyed.connect( 240 connection->SignalDestroyed.connect(
240 this, &P2PTransportChannel::OnConnectionDestroyed); 241 this, &P2PTransportChannel::OnConnectionDestroyed);
241 connection->SignalUseCandidate.connect( 242 connection->SignalUseCandidate.connect(
242 this, &P2PTransportChannel::OnUseCandidate); 243 this, &P2PTransportChannel::OnUseCandidate);
244 had_connection_ = true;
243 } 245 }
244 246
245 void P2PTransportChannel::SetIceRole(IceRole ice_role) { 247 void P2PTransportChannel::SetIceRole(IceRole ice_role) {
246 ASSERT(worker_thread_ == rtc::Thread::Current()); 248 ASSERT(worker_thread_ == rtc::Thread::Current());
247 if (ice_role_ != ice_role) { 249 if (ice_role_ != ice_role) {
248 ice_role_ = ice_role; 250 ice_role_ = ice_role;
249 for (std::vector<PortInterface *>::iterator it = ports_.begin(); 251 for (std::vector<PortInterface *>::iterator it = ports_.begin();
250 it != ports_.end(); ++it) { 252 it != ports_.end(); ++it) {
251 (*it)->SetIceRole(ice_role); 253 (*it)->SetIceRole(ice_role);
252 } 254 }
(...skipping 14 matching lines...) Expand all
267 // Currently a channel is considered ICE completed once there is no 269 // Currently a channel is considered ICE completed once there is no
268 // more than one connection per Network. This works for a single NIC 270 // more than one connection per Network. This works for a single NIC
269 // with both IPv4 and IPv6 enabled. However, this condition won't 271 // with both IPv4 and IPv6 enabled. However, this condition won't
270 // happen when there are multiple NICs and all of them have 272 // happen when there are multiple NICs and all of them have
271 // connectivity. 273 // connectivity.
272 // TODO(guoweis): Change Completion to be driven by a channel level 274 // TODO(guoweis): Change Completion to be driven by a channel level
273 // timer. 275 // timer.
274 TransportChannelState P2PTransportChannel::GetState() const { 276 TransportChannelState P2PTransportChannel::GetState() const {
275 std::set<rtc::Network*> networks; 277 std::set<rtc::Network*> networks;
276 278
277 if (connections_.size() == 0) { 279 if (connections_.size() == 0) {
pthatcher1 2015/08/25 18:40:39 Could you change this to .empty() while you're her
Taylor Brandstetter 2015/08/25 20:39:54 Done.
278 return TransportChannelState::STATE_FAILED; 280 return had_connection_ ? TransportChannelState::STATE_FAILED
281 : TransportChannelState::STATE_NEW;
279 } 282 }
280 283
281 for (uint32 i = 0; i < connections_.size(); ++i) { 284 for (uint32 i = 0; i < connections_.size(); ++i) {
282 rtc::Network* network = connections_[i]->port()->Network(); 285 rtc::Network* network = connections_[i]->port()->Network();
283 if (networks.find(network) == networks.end()) { 286 if (networks.find(network) == networks.end()) {
284 networks.insert(network); 287 networks.insert(network);
285 } else { 288 } else {
286 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " 289 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as "
287 << network->ToString() 290 << network->ToString()
288 << " has more than 1 connection."; 291 << " has more than 1 connection.";
(...skipping 29 matching lines...) Expand all
318 // ice ufrag or password. 321 // ice ufrag or password.
319 ice_restart = 322 ice_restart =
320 IceCredentialsChanged(ice_ufrag_, ice_pwd_, ice_ufrag, ice_pwd); 323 IceCredentialsChanged(ice_ufrag_, ice_pwd_, ice_ufrag, ice_pwd);
321 } 324 }
322 325
323 ice_ufrag_ = ice_ufrag; 326 ice_ufrag_ = ice_ufrag;
324 ice_pwd_ = ice_pwd; 327 ice_pwd_ = ice_pwd;
325 328
326 if (ice_restart) { 329 if (ice_restart) {
327 // Restart candidate gathering. 330 // Restart candidate gathering.
328 Allocate(); 331 StartGatheringCandidates();
329 } 332 }
330 } 333 }
331 334
332 void P2PTransportChannel::SetRemoteIceCredentials(const std::string& ice_ufrag, 335 void P2PTransportChannel::SetRemoteIceCredentials(const std::string& ice_ufrag,
333 const std::string& ice_pwd) { 336 const std::string& ice_pwd) {
334 ASSERT(worker_thread_ == rtc::Thread::Current()); 337 ASSERT(worker_thread_ == rtc::Thread::Current());
335 bool ice_restart = false; 338 bool ice_restart = false;
336 if (!remote_ice_ufrag_.empty() && !remote_ice_pwd_.empty()) { 339 if (!remote_ice_ufrag_.empty() && !remote_ice_pwd_.empty()) {
337 ice_restart = (remote_ice_ufrag_ != ice_ufrag) || 340 ice_restart = (remote_ice_ufrag_ != ice_ufrag) ||
338 (remote_ice_pwd_!= ice_pwd); 341 (remote_ice_pwd_!= ice_pwd);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 void P2PTransportChannel::Connect() { 377 void P2PTransportChannel::Connect() {
375 ASSERT(worker_thread_ == rtc::Thread::Current()); 378 ASSERT(worker_thread_ == rtc::Thread::Current());
376 if (ice_ufrag_.empty() || ice_pwd_.empty()) { 379 if (ice_ufrag_.empty() || ice_pwd_.empty()) {
377 ASSERT(false); 380 ASSERT(false);
378 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " 381 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the "
379 << "ice_pwd_ are not set."; 382 << "ice_pwd_ are not set.";
380 return; 383 return;
381 } 384 }
382 385
383 // Kick off an allocator session 386 // Kick off an allocator session
384 Allocate(); 387 StartGatheringCandidates();
385 388
386 // Start pinging as the ports come in. 389 // Start pinging as the ports come in.
387 thread()->Post(this, MSG_PING); 390 thread()->Post(this, MSG_PING);
388 391
389 thread()->PostDelayed( 392 thread()->PostDelayed(
390 check_receiving_delay_, this, MSG_CHECK_RECEIVING); 393 check_receiving_delay_, this, MSG_CHECK_RECEIVING);
391 } 394 }
392 395
393 // A new port is available, attempt to make connections for it 396 // A new port is available, attempt to make connections for it
394 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session, 397 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session,
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 for (iter = remote_candidates_.begin(); iter != remote_candidates_.end(); 431 for (iter = remote_candidates_.begin(); iter != remote_candidates_.end();
429 ++iter) { 432 ++iter) {
430 CreateConnection(port, *iter, iter->origin_port(), false); 433 CreateConnection(port, *iter, iter->origin_port(), false);
431 } 434 }
432 435
433 SortConnections(); 436 SortConnections();
434 } 437 }
435 438
436 // A new candidate is available, let listeners know 439 // A new candidate is available, let listeners know
437 void P2PTransportChannel::OnCandidatesReady( 440 void P2PTransportChannel::OnCandidatesReady(
438 PortAllocatorSession *session, const std::vector<Candidate>& candidates) { 441 PortAllocatorSession* session,
442 const std::vector<Candidate>& candidates) {
439 ASSERT(worker_thread_ == rtc::Thread::Current()); 443 ASSERT(worker_thread_ == rtc::Thread::Current());
440 for (size_t i = 0; i < candidates.size(); ++i) { 444 for (size_t i = 0; i < candidates.size(); ++i) {
441 SignalCandidateReady(this, candidates[i]); 445 SignalCandidateGathered(this, candidates[i]);
442 } 446 }
443 } 447 }
444 448
445 void P2PTransportChannel::OnCandidatesAllocationDone( 449 void P2PTransportChannel::OnCandidatesAllocationDone(
446 PortAllocatorSession* session) { 450 PortAllocatorSession* session) {
447 ASSERT(worker_thread_ == rtc::Thread::Current()); 451 ASSERT(worker_thread_ == rtc::Thread::Current());
448 SignalCandidatesAllocationDone(this); 452 gathering_state_ = kIceGatheringComplete;
453 LOG(LS_INFO) << "P2PTransportChannel: " << content_name() << ", component "
454 << component() << " gathering complete";
455 SignalGatheringState(this);
449 } 456 }
450 457
451 // Handle stun packets 458 // Handle stun packets
452 void P2PTransportChannel::OnUnknownAddress( 459 void P2PTransportChannel::OnUnknownAddress(
453 PortInterface* port, 460 PortInterface* port,
454 const rtc::SocketAddress& address, ProtocolType proto, 461 const rtc::SocketAddress& address, ProtocolType proto,
455 IceMessage* stun_msg, const std::string &remote_username, 462 IceMessage* stun_msg, const std::string &remote_username,
456 bool port_muxed) { 463 bool port_muxed) {
457 ASSERT(worker_thread_ == rtc::Thread::Current()); 464 ASSERT(worker_thread_ == rtc::Thread::Current());
458 465
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 // connection in question. 631 // connection in question.
625 SortConnections(); 632 SortConnections();
626 } 633 }
627 } 634 }
628 635
629 void P2PTransportChannel::OnRoleConflict(PortInterface* port) { 636 void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
630 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called 637 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called
631 // from Transport. 638 // from Transport.
632 } 639 }
633 640
634 // When the signalling channel is ready, we can really kick off the allocator
635 void P2PTransportChannel::OnSignalingReady() {
636 ASSERT(worker_thread_ == rtc::Thread::Current());
637 if (waiting_for_signaling_) {
638 waiting_for_signaling_ = false;
639 AddAllocatorSession(allocator_->CreateSession(
640 SessionId(), content_name(), component(), ice_ufrag_, ice_pwd_));
641 }
642 }
643
644 void P2PTransportChannel::OnUseCandidate(Connection* conn) { 641 void P2PTransportChannel::OnUseCandidate(Connection* conn) {
645 ASSERT(worker_thread_ == rtc::Thread::Current()); 642 ASSERT(worker_thread_ == rtc::Thread::Current());
646 ASSERT(ice_role_ == ICEROLE_CONTROLLED); 643 ASSERT(ice_role_ == ICEROLE_CONTROLLED);
647 ASSERT(protocol_type_ == ICEPROTO_RFC5245); 644 ASSERT(protocol_type_ == ICEPROTO_RFC5245);
648 645
649 if (conn->write_state() == Connection::STATE_WRITABLE) { 646 if (conn->write_state() == Connection::STATE_WRITABLE) {
650 if (best_connection_ != conn) { 647 if (best_connection_ != conn) {
651 pending_best_connection_ = NULL; 648 pending_best_connection_ = NULL;
652 LOG(LS_INFO) << "Switching best connection on controlled side: " 649 LOG(LS_INFO) << "Switching best connection on controlled side: "
653 << conn->ToString(); 650 << conn->ToString();
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 return sent; 907 return sent;
911 } 908 }
912 909
913 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { 910 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) {
914 ASSERT(worker_thread_ == rtc::Thread::Current()); 911 ASSERT(worker_thread_ == rtc::Thread::Current());
915 // Gather connection infos. 912 // Gather connection infos.
916 infos->clear(); 913 infos->clear();
917 914
918 std::vector<Connection *>::const_iterator it; 915 std::vector<Connection *>::const_iterator it;
919 for (it = connections_.begin(); it != connections_.end(); ++it) { 916 for (it = connections_.begin(); it != connections_.end(); ++it) {
920 Connection *connection = *it; 917 Connection* connection = *it;
921 ConnectionInfo info; 918 ConnectionInfo info;
922 info.best_connection = (best_connection_ == connection); 919 info.best_connection = (best_connection_ == connection);
923 info.readable = 920 info.readable =
924 (connection->read_state() == Connection::STATE_READABLE); 921 (connection->read_state() == Connection::STATE_READABLE);
925 info.writable = 922 info.writable =
926 (connection->write_state() == Connection::STATE_WRITABLE); 923 (connection->write_state() == Connection::STATE_WRITABLE);
927 info.timeout = 924 info.timeout =
928 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); 925 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT);
929 info.new_connection = !connection->reported(); 926 info.new_connection = !connection->reported();
930 connection->set_reported(true); 927 connection->set_reported(true);
(...skipping 14 matching lines...) Expand all
945 } 942 }
946 943
947 rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const { 944 rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const {
948 OptionMap::const_iterator it = options_.find(rtc::Socket::OPT_DSCP); 945 OptionMap::const_iterator it = options_.find(rtc::Socket::OPT_DSCP);
949 if (it == options_.end()) { 946 if (it == options_.end()) {
950 return rtc::DSCP_NO_CHANGE; 947 return rtc::DSCP_NO_CHANGE;
951 } 948 }
952 return static_cast<rtc::DiffServCodePoint> (it->second); 949 return static_cast<rtc::DiffServCodePoint> (it->second);
953 } 950 }
954 951
955 // Begin allocate (or immediately re-allocate, if MSG_ALLOCATE pending) 952 void P2PTransportChannel::StartGatheringCandidates() {
956 void P2PTransportChannel::Allocate() { 953 // Time for a new allocator
957 // Time for a new allocator, lets make sure we have a signalling channel 954 if (gathering_state_ != kIceGatheringGathering) {
958 // to communicate candidates through first. 955 gathering_state_ = kIceGatheringGathering;
959 waiting_for_signaling_ = true; 956 SignalGatheringState(this);
960 SignalRequestSignaling(this); 957 }
958 AddAllocatorSession(allocator_->CreateSession(
959 SessionId(), content_name(), component(), ice_ufrag_, ice_pwd_));
961 } 960 }
962 961
963 // Monitor connection states. 962 // Monitor connection states.
964 void P2PTransportChannel::UpdateConnectionStates() { 963 void P2PTransportChannel::UpdateConnectionStates() {
965 uint32 now = rtc::Time(); 964 uint32 now = rtc::Time();
966 965
967 // We need to copy the list of connections since some may delete themselves 966 // We need to copy the list of connections since some may delete themselves
968 // when we call UpdateState. 967 // when we call UpdateState.
969 for (uint32 i = 0; i < connections_.size(); ++i) 968 for (uint32 i = 0; i < connections_.size(); ++i)
970 connections_[i]->UpdateState(now); 969 connections_[i]->UpdateState(now);
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 std::vector<PortInterface*>::iterator iter = 1398 std::vector<PortInterface*>::iterator iter =
1400 std::find(ports_.begin(), ports_.end(), port); 1399 std::find(ports_.begin(), ports_.end(), port);
1401 if (iter != ports_.end()) 1400 if (iter != ports_.end())
1402 ports_.erase(iter); 1401 ports_.erase(iter);
1403 1402
1404 LOG(INFO) << "Removed port from p2p socket: " 1403 LOG(INFO) << "Removed port from p2p socket: "
1405 << static_cast<int>(ports_.size()) << " remaining"; 1404 << static_cast<int>(ports_.size()) << " remaining";
1406 } 1405 }
1407 1406
1408 // We data is available, let listeners know 1407 // We data is available, let listeners know
1409 void P2PTransportChannel::OnReadPacket( 1408 void P2PTransportChannel::OnReadPacket(Connection* connection,
1410 Connection *connection, const char *data, size_t len, 1409 const char* data,
1411 const rtc::PacketTime& packet_time) { 1410 size_t len,
1411 const rtc::PacketTime& packet_time) {
1412 ASSERT(worker_thread_ == rtc::Thread::Current()); 1412 ASSERT(worker_thread_ == rtc::Thread::Current());
1413 1413
1414 // Do not deliver, if packet doesn't belong to the correct transport channel. 1414 // Do not deliver, if packet doesn't belong to the correct transport channel.
1415 if (!FindConnection(connection)) 1415 if (!FindConnection(connection))
1416 return; 1416 return;
1417 1417
1418 // Let the client know of an incoming packet 1418 // Let the client know of an incoming packet
1419 SignalReadPacket(this, data, len, packet_time, 0); 1419 SignalReadPacket(this, data, len, packet_time, 0);
1420 } 1420 }
1421 1421
1422 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1422 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
1423 if (connection == best_connection_ && writable()) { 1423 if (connection == best_connection_ && writable()) {
1424 SignalReadyToSend(this); 1424 SignalReadyToSend(this);
1425 } 1425 }
1426 } 1426 }
1427 1427
1428 } // namespace cricket 1428 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698