Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2015 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/transportcontroller.h" | 11 #include "webrtc/p2p/base/transportcontroller.h" |
| 12 | 12 |
| 13 #include <algorithm> | |
| 14 | |
| 13 #include "webrtc/base/bind.h" | 15 #include "webrtc/base/bind.h" |
| 14 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
| 15 #include "webrtc/base/thread.h" | 17 #include "webrtc/base/thread.h" |
| 16 #include "webrtc/p2p/base/dtlstransport.h" | 18 #include "webrtc/p2p/base/dtlstransport.h" |
| 17 #include "webrtc/p2p/base/p2ptransport.h" | 19 #include "webrtc/p2p/base/p2ptransport.h" |
| 20 #include "webrtc/p2p/base/port.h" | |
| 18 | 21 |
| 19 namespace cricket { | 22 namespace cricket { |
| 20 | 23 |
| 21 enum { | 24 enum { |
| 22 MSG_ICECONNECTIONSTATE, | 25 MSG_ICECONNECTIONSTATE, |
| 23 MSG_RECEIVING, | 26 MSG_RECEIVING, |
| 24 MSG_ICEGATHERINGSTATE, | 27 MSG_ICEGATHERINGSTATE, |
| 25 MSG_CANDIDATESGATHERED, | 28 MSG_CANDIDATESGATHERED, |
| 26 }; | 29 }; |
| 27 | 30 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 TransportStats* stats) { | 136 TransportStats* stats) { |
| 134 return worker_thread_->Invoke<bool>( | 137 return worker_thread_->Invoke<bool>( |
| 135 rtc::Bind(&TransportController::GetStats_w, this, transport_name, stats)); | 138 rtc::Bind(&TransportController::GetStats_w, this, transport_name, stats)); |
| 136 } | 139 } |
| 137 | 140 |
| 138 TransportChannel* TransportController::CreateTransportChannel_w( | 141 TransportChannel* TransportController::CreateTransportChannel_w( |
| 139 const std::string& transport_name, | 142 const std::string& transport_name, |
| 140 int component) { | 143 int component) { |
| 141 RTC_DCHECK(worker_thread_->IsCurrent()); | 144 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 142 | 145 |
| 143 Transport* transport = GetOrCreateTransport_w(transport_name); | 146 auto it = FindChannel_w(transport_name, component); |
| 144 return transport->CreateChannel(component); | 147 if (it == channels_.end()) { |
| 148 // Need to create a new channel. | |
| 149 Transport* transport = GetOrCreateTransport_w(transport_name); | |
| 150 TransportChannelImpl* channel = transport->CreateChannel(component); | |
| 151 channel->SignalWritableState.connect( | |
| 152 this, &TransportController::OnChannelWritableState_w); | |
| 153 channel->SignalReceivingState.connect( | |
| 154 this, &TransportController::OnChannelReceivingState_w); | |
| 155 channel->SignalGatheringState.connect( | |
| 156 this, &TransportController::OnChannelGatheringState_w); | |
| 157 channel->SignalCandidateGathered.connect( | |
| 158 this, &TransportController::OnChannelCandidateGathered_w); | |
| 159 channel->SignalRoleConflict.connect( | |
| 160 this, &TransportController::OnChannelRoleConflict_w); | |
| 161 channel->SignalConnectionRemoved.connect( | |
| 162 this, &TransportController::OnChannelConnectionRemoved_w); | |
| 163 channels_.insert(channels_.end(), RefCountedChannel(channel))->AddRef(); | |
| 164 // Adding a channel could cause aggregate state to change. | |
| 165 UpdateAggregateStates_w(); | |
| 166 return channel; | |
| 167 } | |
| 168 // Channel already exists; increment reference count and return. | |
| 169 it->AddRef(); | |
| 170 return it->get(); | |
|
pthatcher1
2015/09/29 23:50:58
Might be easier to read the other way around:
if
Taylor Brandstetter
2015/09/30 01:01:20
Done.
| |
| 145 } | 171 } |
| 146 | 172 |
| 147 void TransportController::DestroyTransportChannel_w( | 173 void TransportController::DestroyTransportChannel_w( |
| 148 const std::string& transport_name, | 174 const std::string& transport_name, |
| 149 int component) { | 175 int component) { |
| 150 RTC_DCHECK(worker_thread_->IsCurrent()); | 176 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 151 | 177 |
| 152 Transport* transport = GetTransport_w(transport_name); | 178 auto it = FindChannel_w(transport_name, component); |
| 153 if (!transport) { | 179 if (it == channels_.end()) { |
| 154 ASSERT(false); | 180 LOG(LS_WARNING) << "Attempting to delete " << transport_name |
| 181 << " TransportChannel " << component | |
| 182 << ", which doesn't exist."; | |
| 155 return; | 183 return; |
| 156 } | 184 } |
| 157 transport->DestroyChannel(component); | |
| 158 | 185 |
| 159 // Just as we create a Transport when its first channel is created, | 186 it->DecRef(); |
| 160 // we delete it when its last channel is deleted. | 187 if (it->ref() == 0) { |
|
pthatcher1
2015/09/29 23:50:58
Same here:
if (it->ref() > 0) {
return;
}
chan
Taylor Brandstetter
2015/09/30 01:01:20
Done.
| |
| 161 if (!transport->HasChannels()) { | 188 channels_.erase(it); |
| 162 DestroyTransport_w(transport_name); | 189 Transport* transport = GetTransport_w(transport_name); |
| 190 transport->DestroyChannel(component); | |
| 191 // Just as we create a Transport when its first channel is created, | |
| 192 // we delete it when its last channel is deleted. | |
| 193 if (!transport->HasChannels()) { | |
| 194 DestroyTransport_w(transport_name); | |
| 195 } | |
| 196 // Removing a channel could cause aggregate state to change. | |
| 197 UpdateAggregateStates_w(); | |
| 163 } | 198 } |
| 164 } | 199 } |
| 165 | 200 |
| 166 const rtc::scoped_refptr<rtc::RTCCertificate>& | 201 const rtc::scoped_refptr<rtc::RTCCertificate>& |
| 167 TransportController::certificate_for_testing() { | 202 TransportController::certificate_for_testing() { |
| 168 return certificate_; | 203 return certificate_; |
| 169 } | 204 } |
| 170 | 205 |
| 171 Transport* TransportController::CreateTransport_w( | 206 Transport* TransportController::CreateTransport_w( |
| 172 const std::string& transport_name) { | 207 const std::string& transport_name) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 214 CandidatesData* data = static_cast<CandidatesData*>(pmsg->pdata); | 249 CandidatesData* data = static_cast<CandidatesData*>(pmsg->pdata); |
| 215 SignalCandidatesGathered(data->transport_name, data->candidates); | 250 SignalCandidatesGathered(data->transport_name, data->candidates); |
| 216 delete data; | 251 delete data; |
| 217 break; | 252 break; |
| 218 } | 253 } |
| 219 default: | 254 default: |
| 220 ASSERT(false); | 255 ASSERT(false); |
| 221 } | 256 } |
| 222 } | 257 } |
| 223 | 258 |
| 259 std::vector<TransportController::RefCountedChannel>::iterator | |
| 260 TransportController::FindChannel_w(const std::string& transport_name, | |
| 261 int component) { | |
| 262 return std::find_if( | |
| 263 channels_.begin(), channels_.end(), | |
| 264 [transport_name, component](const RefCountedChannel& channel) { | |
| 265 return channel->transport_name() == transport_name && | |
| 266 channel->component() == component; | |
| 267 }); | |
| 268 } | |
| 269 | |
| 224 Transport* TransportController::GetOrCreateTransport_w( | 270 Transport* TransportController::GetOrCreateTransport_w( |
| 225 const std::string& transport_name) { | 271 const std::string& transport_name) { |
| 226 RTC_DCHECK(worker_thread_->IsCurrent()); | 272 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 227 | 273 |
| 228 Transport* transport = GetTransport_w(transport_name); | 274 Transport* transport = GetTransport_w(transport_name); |
| 229 if (transport) { | 275 if (transport) { |
| 230 return transport; | 276 return transport; |
| 231 } | 277 } |
| 232 | 278 |
| 233 transport = CreateTransport_w(transport_name); | 279 transport = CreateTransport_w(transport_name); |
| 234 // The stuff below happens outside of CreateTransport_w so that unit tests | 280 // The stuff below happens outside of CreateTransport_w so that unit tests |
| 235 // can override CreateTransport_w to return a different type of transport. | 281 // can override CreateTransport_w to return a different type of transport. |
| 236 transport->SetSslMaxProtocolVersion(ssl_max_version_); | 282 transport->SetSslMaxProtocolVersion(ssl_max_version_); |
| 237 transport->SetIceConfig(ice_config_); | 283 transport->SetIceConfig(ice_config_); |
| 238 transport->SetIceRole(ice_role_); | 284 transport->SetIceRole(ice_role_); |
| 239 transport->SetIceTiebreaker(ice_tiebreaker_); | 285 transport->SetIceTiebreaker(ice_tiebreaker_); |
| 240 if (certificate_) { | 286 if (certificate_) { |
| 241 transport->SetLocalCertificate(certificate_); | 287 transport->SetLocalCertificate(certificate_); |
| 242 } | 288 } |
| 243 transport->SignalConnecting.connect( | |
| 244 this, &TransportController::OnTransportConnecting_w); | |
| 245 transport->SignalWritableState.connect( | |
| 246 this, &TransportController::OnTransportWritableState_w); | |
| 247 transport->SignalReceivingState.connect( | |
| 248 this, &TransportController::OnTransportReceivingState_w); | |
| 249 transport->SignalCompleted.connect( | |
| 250 this, &TransportController::OnTransportCompleted_w); | |
| 251 transport->SignalFailed.connect(this, | |
| 252 &TransportController::OnTransportFailed_w); | |
| 253 transport->SignalGatheringState.connect( | |
| 254 this, &TransportController::OnTransportGatheringState_w); | |
| 255 transport->SignalCandidatesGathered.connect( | |
| 256 this, &TransportController::OnTransportCandidatesGathered_w); | |
| 257 transport->SignalRoleConflict.connect( | |
| 258 this, &TransportController::OnTransportRoleConflict_w); | |
| 259 transports_[transport_name] = transport; | 289 transports_[transport_name] = transport; |
| 260 | 290 |
| 261 return transport; | 291 return transport; |
| 262 } | 292 } |
| 263 | 293 |
| 264 void TransportController::DestroyTransport_w( | 294 void TransportController::DestroyTransport_w( |
| 265 const std::string& transport_name) { | 295 const std::string& transport_name) { |
| 266 RTC_DCHECK(worker_thread_->IsCurrent()); | 296 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 267 | 297 |
| 268 auto iter = transports_.find(transport_name); | 298 auto iter = transports_.find(transport_name); |
| 269 if (iter != transports_.end()) { | 299 if (iter != transports_.end()) { |
| 270 delete iter->second; | 300 delete iter->second; |
| 271 transports_.erase(transport_name); | 301 transports_.erase(transport_name); |
| 272 } | 302 } |
| 273 // Destroying a transport may cause aggregate state to change. | |
| 274 UpdateAggregateStates_w(); | |
| 275 } | 303 } |
| 276 | 304 |
| 277 void TransportController::DestroyAllTransports_w() { | 305 void TransportController::DestroyAllTransports_w() { |
| 278 RTC_DCHECK(worker_thread_->IsCurrent()); | 306 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 279 | 307 |
| 280 for (const auto& kv : transports_) { | 308 for (const auto& kv : transports_) { |
| 281 delete kv.second; | 309 delete kv.second; |
| 282 } | 310 } |
| 283 transports_.clear(); | 311 transports_.clear(); |
| 284 } | 312 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 TransportStats* stats) { | 468 TransportStats* stats) { |
| 441 RTC_DCHECK(worker_thread()->IsCurrent()); | 469 RTC_DCHECK(worker_thread()->IsCurrent()); |
| 442 | 470 |
| 443 Transport* transport = GetTransport_w(transport_name); | 471 Transport* transport = GetTransport_w(transport_name); |
| 444 if (!transport) { | 472 if (!transport) { |
| 445 return false; | 473 return false; |
| 446 } | 474 } |
| 447 return transport->GetStats(stats); | 475 return transport->GetStats(stats); |
| 448 } | 476 } |
| 449 | 477 |
| 450 void TransportController::OnTransportConnecting_w(Transport* transport) { | 478 void TransportController::OnChannelWritableState_w(TransportChannel* channel) { |
| 479 RTC_DCHECK(worker_thread_->IsCurrent()); | |
| 480 LOG(LS_INFO) << channel->transport_name() << " TransportChannel " | |
| 481 << channel->component() << " writability changed to " | |
| 482 << channel->writable() << "."; | |
| 483 UpdateAggregateStates_w(); | |
| 484 } | |
| 485 | |
| 486 void TransportController::OnChannelReceivingState_w(TransportChannel* channel) { | |
| 451 RTC_DCHECK(worker_thread_->IsCurrent()); | 487 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 452 UpdateAggregateStates_w(); | 488 UpdateAggregateStates_w(); |
| 453 } | 489 } |
| 454 | 490 |
| 455 void TransportController::OnTransportWritableState_w(Transport* transport) { | 491 void TransportController::OnChannelGatheringState_w( |
| 492 TransportChannelImpl* channel) { | |
| 456 RTC_DCHECK(worker_thread_->IsCurrent()); | 493 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 457 UpdateAggregateStates_w(); | 494 UpdateAggregateStates_w(); |
| 458 } | 495 } |
| 459 | 496 |
| 460 void TransportController::OnTransportReceivingState_w(Transport* transport) { | 497 void TransportController::OnChannelCandidateGathered_w( |
| 498 TransportChannelImpl* channel, | |
| 499 const Candidate& candidate) { | |
| 461 RTC_DCHECK(worker_thread_->IsCurrent()); | 500 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 462 UpdateAggregateStates_w(); | |
| 463 } | |
| 464 | 501 |
| 465 void TransportController::OnTransportCompleted_w(Transport* transport) { | 502 // We should never signal peer-reflexive candidates. |
| 466 RTC_DCHECK(worker_thread_->IsCurrent()); | 503 if (candidate.type() == PRFLX_PORT_TYPE) { |
| 467 UpdateAggregateStates_w(); | 504 RTC_DCHECK(false); |
| 468 } | 505 return; |
| 469 | 506 } |
| 470 void TransportController::OnTransportFailed_w(Transport* transport) { | 507 std::vector<Candidate> candidates; |
| 471 RTC_DCHECK(worker_thread_->IsCurrent()); | 508 candidates.push_back(candidate); |
| 472 UpdateAggregateStates_w(); | 509 CandidatesData* data = |
| 473 } | 510 new CandidatesData(channel->transport_name(), candidates); |
| 474 | |
| 475 void TransportController::OnTransportGatheringState_w(Transport* transport) { | |
| 476 RTC_DCHECK(worker_thread_->IsCurrent()); | |
| 477 UpdateAggregateStates_w(); | |
| 478 } | |
| 479 | |
| 480 void TransportController::OnTransportCandidatesGathered_w( | |
| 481 Transport* transport, | |
| 482 const std::vector<Candidate>& candidates) { | |
| 483 RTC_DCHECK(worker_thread_->IsCurrent()); | |
| 484 CandidatesData* data = new CandidatesData(transport->name(), candidates); | |
| 485 signaling_thread_->Post(this, MSG_CANDIDATESGATHERED, data); | 511 signaling_thread_->Post(this, MSG_CANDIDATESGATHERED, data); |
| 486 } | 512 } |
| 487 | 513 |
| 488 void TransportController::OnTransportRoleConflict_w() { | 514 void TransportController::OnChannelRoleConflict_w( |
| 515 TransportChannelImpl* channel) { | |
| 489 RTC_DCHECK(worker_thread_->IsCurrent()); | 516 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 490 | 517 |
| 491 if (ice_role_switch_) { | 518 if (ice_role_switch_) { |
| 492 LOG(LS_WARNING) << "Repeat of role conflict signal from Transport."; | 519 LOG(LS_WARNING) |
| 520 << "Repeat of role conflict signal from TransportChannelImpl."; | |
| 493 return; | 521 return; |
| 494 } | 522 } |
| 495 | 523 |
| 496 ice_role_switch_ = true; | 524 ice_role_switch_ = true; |
| 497 IceRole reversed_role = (ice_role_ == ICEROLE_CONTROLLING) | 525 IceRole reversed_role = (ice_role_ == ICEROLE_CONTROLLING) |
| 498 ? ICEROLE_CONTROLLED | 526 ? ICEROLE_CONTROLLED |
| 499 : ICEROLE_CONTROLLING; | 527 : ICEROLE_CONTROLLING; |
| 500 for (const auto& kv : transports_) { | 528 for (const auto& kv : transports_) { |
| 501 kv.second->SetIceRole(reversed_role); | 529 kv.second->SetIceRole(reversed_role); |
| 502 } | 530 } |
| 503 } | 531 } |
| 504 | 532 |
| 533 void TransportController::OnChannelConnectionRemoved_w( | |
| 534 TransportChannelImpl* channel) { | |
| 535 RTC_DCHECK(worker_thread_->IsCurrent()); | |
| 536 LOG(LS_INFO) << channel->transport_name() << " TransportChannel " | |
| 537 << channel->component() | |
| 538 << " connection removed. Check if state is complete."; | |
| 539 UpdateAggregateStates_w(); | |
| 540 } | |
| 541 | |
| 505 void TransportController::UpdateAggregateStates_w() { | 542 void TransportController::UpdateAggregateStates_w() { |
| 506 RTC_DCHECK(worker_thread_->IsCurrent()); | 543 RTC_DCHECK(worker_thread_->IsCurrent()); |
| 507 | 544 |
| 508 IceConnectionState new_connection_state = kIceConnectionConnecting; | 545 IceConnectionState new_connection_state = kIceConnectionConnecting; |
| 509 IceGatheringState new_gathering_state = kIceGatheringNew; | 546 IceGatheringState new_gathering_state = kIceGatheringNew; |
| 510 bool any_receiving = false; | 547 bool any_receiving = false; |
| 511 bool any_failed = false; | 548 bool any_failed = false; |
| 512 bool all_connected = HasChannels_w(); | 549 bool all_connected = !channels_.empty(); |
| 513 bool all_completed = HasChannels_w(); | 550 bool all_completed = !channels_.empty(); |
| 514 bool any_gathering = false; | 551 bool any_gathering = false; |
| 515 bool all_done_gathering = HasChannels_w(); | 552 bool all_done_gathering = !channels_.empty(); |
| 516 for (const auto& kv : transports_) { | 553 for (const auto& channel : channels_) { |
| 517 // Ignore transports without channels since they're about to be deleted, | 554 any_receiving = any_receiving || channel->receiving(); |
| 518 // and their state is meaningless. | 555 any_failed = any_failed || |
| 519 if (!kv.second->HasChannels()) { | 556 channel->GetState() == TransportChannelState::STATE_FAILED; |
| 520 continue; | 557 all_connected = all_connected && channel->writable(); |
| 521 } | 558 all_completed = |
| 522 any_receiving = any_receiving || kv.second->any_channel_receiving(); | 559 all_completed && channel->writable() && |
| 523 any_failed = any_failed || kv.second->AnyChannelFailed(); | 560 channel->GetState() == TransportChannelState::STATE_COMPLETED && |
| 524 all_connected = all_connected && kv.second->all_channels_writable(); | 561 channel->GetIceRole() == ICEROLE_CONTROLLING && |
| 525 all_completed = all_completed && kv.second->AllChannelsCompleted(); | 562 channel->gathering_state() == kIceGatheringComplete; |
| 526 any_gathering = | 563 any_gathering = |
| 527 any_gathering || kv.second->gathering_state() != kIceGatheringNew; | 564 any_gathering || channel->gathering_state() != kIceGatheringNew; |
| 528 all_done_gathering = all_done_gathering && | 565 all_done_gathering = all_done_gathering && |
| 529 kv.second->gathering_state() == kIceGatheringComplete; | 566 channel->gathering_state() == kIceGatheringComplete; |
| 530 } | 567 } |
| 531 | 568 |
| 532 if (any_failed) { | 569 if (any_failed) { |
| 533 new_connection_state = kIceConnectionFailed; | 570 new_connection_state = kIceConnectionFailed; |
| 534 } else if (all_completed) { | 571 } else if (all_completed) { |
| 535 new_connection_state = kIceConnectionCompleted; | 572 new_connection_state = kIceConnectionCompleted; |
| 536 } else if (all_connected) { | 573 } else if (all_connected) { |
| 537 new_connection_state = kIceConnectionConnected; | 574 new_connection_state = kIceConnectionConnected; |
| 538 } | 575 } |
| 539 if (connection_state_ != new_connection_state) { | 576 if (connection_state_ != new_connection_state) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 555 new_gathering_state = kIceGatheringGathering; | 592 new_gathering_state = kIceGatheringGathering; |
| 556 } | 593 } |
| 557 if (gathering_state_ != new_gathering_state) { | 594 if (gathering_state_ != new_gathering_state) { |
| 558 gathering_state_ = new_gathering_state; | 595 gathering_state_ = new_gathering_state; |
| 559 signaling_thread_->Post( | 596 signaling_thread_->Post( |
| 560 this, MSG_ICEGATHERINGSTATE, | 597 this, MSG_ICEGATHERINGSTATE, |
| 561 new rtc::TypedMessageData<IceGatheringState>(new_gathering_state)); | 598 new rtc::TypedMessageData<IceGatheringState>(new_gathering_state)); |
| 562 } | 599 } |
| 563 } | 600 } |
| 564 | 601 |
| 565 bool TransportController::HasChannels_w() { | |
| 566 for (const auto& kv : transports_) { | |
| 567 if (kv.second->HasChannels()) { | |
| 568 return true; | |
| 569 } | |
| 570 } | |
| 571 return false; | |
| 572 } | |
| 573 | |
| 574 } // namespace cricket | 602 } // namespace cricket |
| OLD | NEW |