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