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

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

Issue 1380563002: Thinning out the Transport class. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Typo Created 5 years, 2 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
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 new_desc.ice_ufrag, new_desc.ice_pwd); 65 new_desc.ice_ufrag, new_desc.ice_pwd);
66 } 66 }
67 67
68 Transport::Transport(const std::string& name, PortAllocator* allocator) 68 Transport::Transport(const std::string& name, PortAllocator* allocator)
69 : name_(name), allocator_(allocator) {} 69 : name_(name), allocator_(allocator) {}
70 70
71 Transport::~Transport() { 71 Transport::~Transport() {
72 ASSERT(channels_destroyed_); 72 ASSERT(channels_destroyed_);
73 } 73 }
74 74
75 bool Transport::AllChannelsCompleted() const {
76 // We aren't completed until at least one channel is complete, so if there
77 // are no channels, we aren't complete yet.
78 if (channels_.empty()) {
79 LOG(LS_INFO) << name() << " transport is not complete"
80 << " because it has no TransportChannels";
81 return false;
82 }
83
84 // A Transport's ICE process is completed if all of its channels are writable,
85 // have finished allocating candidates, and have pruned all but one of their
86 // connections.
87 for (const auto& iter : channels_) {
88 const TransportChannelImpl* channel = iter.second.get();
89 bool complete =
90 channel->writable() &&
91 channel->GetState() == TransportChannelState::STATE_COMPLETED &&
92 channel->GetIceRole() == ICEROLE_CONTROLLING &&
93 channel->gathering_state() == kIceGatheringComplete;
94 if (!complete) {
95 LOG(LS_INFO) << name() << " transport is not complete"
96 << " because a channel is still incomplete.";
97 return false;
98 }
99 }
100
101 return true;
102 }
103
104 bool Transport::AnyChannelFailed() const {
105 for (const auto& iter : channels_) {
106 if (iter.second->GetState() == TransportChannelState::STATE_FAILED) {
107 return true;
108 }
109 }
110 return false;
111 }
112
113 void Transport::SetIceRole(IceRole role) { 75 void Transport::SetIceRole(IceRole role) {
114 ice_role_ = role; 76 ice_role_ = role;
115 for (auto& iter : channels_) { 77 for (auto& iter : channels_) {
116 iter.second->SetIceRole(ice_role_); 78 iter.second->SetIceRole(ice_role_);
117 } 79 }
118 } 80 }
119 81
120 bool Transport::GetRemoteSSLCertificate(rtc::SSLCertificate** cert) { 82 bool Transport::GetRemoteSSLCertificate(rtc::SSLCertificate** cert) {
121 if (channels_.empty()) 83 if (channels_.empty())
122 return false; 84 return false;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 impl->SetIceConfig(ice_config_); 194 impl->SetIceConfig(ice_config_);
233 // TODO(ronghuawu): Change CreateChannel to be able to return error since 195 // TODO(ronghuawu): Change CreateChannel to be able to return error since
234 // below Apply**Description calls can fail. 196 // below Apply**Description calls can fail.
235 if (local_description_) 197 if (local_description_)
236 ApplyLocalTransportDescription(impl, NULL); 198 ApplyLocalTransportDescription(impl, NULL);
237 if (remote_description_) 199 if (remote_description_)
238 ApplyRemoteTransportDescription(impl, NULL); 200 ApplyRemoteTransportDescription(impl, NULL);
239 if (local_description_ && remote_description_) 201 if (local_description_ && remote_description_)
240 ApplyNegotiatedTransportDescription(impl, NULL); 202 ApplyNegotiatedTransportDescription(impl, NULL);
241 203
242 impl->SignalWritableState.connect(this, &Transport::OnChannelWritableState);
243 impl->SignalReceivingState.connect(this, &Transport::OnChannelReceivingState);
244 impl->SignalGatheringState.connect(this, &Transport::OnChannelGatheringState);
245 impl->SignalCandidateGathered.connect(this,
246 &Transport::OnChannelCandidateGathered);
247 impl->SignalRouteChange.connect(this, &Transport::OnChannelRouteChange);
248 impl->SignalRoleConflict.connect(this, &Transport::OnRoleConflict);
249 impl->SignalConnectionRemoved.connect(
250 this, &Transport::OnChannelConnectionRemoved);
251
252 if (connect_requested_) { 204 if (connect_requested_) {
253 impl->Connect(); 205 impl->Connect();
254 if (channels_.size() == 1) {
255 // If this is the first channel, then indicate that we have started
256 // connecting.
257 SignalConnecting(this);
258 }
259 } 206 }
260 return impl; 207 return impl;
261 } 208 }
262 209
263 TransportChannelImpl* Transport::GetChannel(int component) { 210 TransportChannelImpl* Transport::GetChannel(int component) {
264 ChannelMap::iterator iter = channels_.find(component); 211 ChannelMap::iterator iter = channels_.find(component);
265 return (iter != channels_.end()) ? iter->second.get() : NULL; 212 return (iter != channels_.end()) ? iter->second.get() : NULL;
266 } 213 }
267 214
268 bool Transport::HasChannels() { 215 bool Transport::HasChannels() {
269 return !channels_.empty(); 216 return !channels_.empty();
270 } 217 }
271 218
272 void Transport::DestroyChannel(int component) { 219 bool Transport::DestroyChannel(int component) {
273 ChannelMap::iterator iter = channels_.find(component); 220 ChannelMap::iterator iter = channels_.find(component);
274 if (iter == channels_.end()) 221 if (iter == channels_.end())
275 return; 222 return false;
276 223
277 TransportChannelImpl* impl = NULL; 224 TransportChannelImpl* impl = NULL;
278 225
279 iter->second.DecRef(); 226 iter->second.DecRef();
280 if (!iter->second.ref()) { 227 if (!iter->second.ref()) {
281 impl = iter->second.get(); 228 impl = iter->second.get();
282 channels_.erase(iter); 229 channels_.erase(iter);
283 } 230 }
284 231
285 if (connect_requested_ && channels_.empty()) {
286 // We're no longer attempting to connect.
287 SignalConnecting(this);
288 }
289
290 if (impl) { 232 if (impl) {
291 DestroyTransportChannel(impl); 233 DestroyTransportChannel(impl);
292 // Need to update aggregate state after destroying a channel, 234 return true;
293 // for example if it was the only one that wasn't yet writable.
294 UpdateWritableState();
295 UpdateReceivingState();
296 UpdateGatheringState();
297 MaybeSignalCompleted();
298 } 235 }
236 return false;
299 } 237 }
300 238
301 void Transport::ConnectChannels() { 239 void Transport::ConnectChannels() {
302 if (connect_requested_ || channels_.empty()) 240 if (connect_requested_ || channels_.empty())
303 return; 241 return;
304 242
305 connect_requested_ = true; 243 connect_requested_ = true;
306 244
307 if (!local_description_) { 245 if (!local_description_) {
308 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here. 246 // TOOD(mallinath) : TransportDescription(TD) shouldn't be generated here.
309 // As Transport must know TD is offer or answer and cricket::Transport 247 // As Transport must know TD is offer or answer and cricket::Transport
310 // doesn't have the capability to decide it. This should be set by the 248 // doesn't have the capability to decide it. This should be set by the
311 // Session. 249 // Session.
312 // Session must generate local TD before remote candidates pushed when 250 // Session must generate local TD before remote candidates pushed when
313 // initiate request initiated by the remote. 251 // initiate request initiated by the remote.
314 LOG(LS_INFO) << "Transport::ConnectChannels: No local description has " 252 LOG(LS_INFO) << "Transport::ConnectChannels: No local description has "
315 << "been set. Will generate one."; 253 << "been set. Will generate one.";
316 TransportDescription desc( 254 TransportDescription desc(
317 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH), 255 std::vector<std::string>(), rtc::CreateRandomString(ICE_UFRAG_LENGTH),
318 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL, 256 rtc::CreateRandomString(ICE_PWD_LENGTH), ICEMODE_FULL,
319 CONNECTIONROLE_NONE, NULL, Candidates()); 257 CONNECTIONROLE_NONE, NULL, Candidates());
320 SetLocalTransportDescription(desc, CA_OFFER, NULL); 258 SetLocalTransportDescription(desc, CA_OFFER, NULL);
321 } 259 }
322 260
323 CallChannels(&TransportChannelImpl::Connect); 261 CallChannels(&TransportChannelImpl::Connect);
324 if (HasChannels()) {
325 SignalConnecting(this);
326 }
327 } 262 }
328 263
329 void Transport::MaybeStartGathering() { 264 void Transport::MaybeStartGathering() {
330 if (connect_requested_) { 265 if (connect_requested_) {
331 CallChannels(&TransportChannelImpl::MaybeStartGathering); 266 CallChannels(&TransportChannelImpl::MaybeStartGathering);
332 } 267 }
333 } 268 }
334 269
335 void Transport::DestroyAllChannels() { 270 void Transport::DestroyAllChannels() {
336 std::vector<TransportChannelImpl*> impls; 271 std::vector<TransportChannelImpl*> impls;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
422 iter != candidates.end(); 357 iter != candidates.end();
423 ++iter) { 358 ++iter) {
424 TransportChannelImpl* channel = GetChannel(iter->component()); 359 TransportChannelImpl* channel = GetChannel(iter->component());
425 if (channel != NULL) { 360 if (channel != NULL) {
426 channel->AddRemoteCandidate(*iter); 361 channel->AddRemoteCandidate(*iter);
427 } 362 }
428 } 363 }
429 return true; 364 return true;
430 } 365 }
431 366
432 void Transport::OnChannelWritableState(TransportChannel* channel) {
433 LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
434 << " writability changed to " << channel->writable()
435 << ". Check if transport is complete.";
436 UpdateWritableState();
437 MaybeSignalCompleted();
438 }
439
440 void Transport::OnChannelReceivingState(TransportChannel* channel) {
441 UpdateReceivingState();
442 }
443
444 TransportState Transport::GetTransportState(TransportStateType state_type) {
445 bool any = false;
446 bool all = !channels_.empty();
447 for (const auto iter : channels_) {
448 bool b = false;
449 switch (state_type) {
450 case TRANSPORT_WRITABLE_STATE:
451 b = iter.second->writable();
452 break;
453 case TRANSPORT_RECEIVING_STATE:
454 b = iter.second->receiving();
455 break;
456 default:
457 ASSERT(false);
458 }
459 any |= b;
460 all &= b;
461 }
462
463 if (all) {
464 return TRANSPORT_STATE_ALL;
465 } else if (any) {
466 return TRANSPORT_STATE_SOME;
467 }
468
469 return TRANSPORT_STATE_NONE;
470 }
471
472 void Transport::OnChannelGatheringState(TransportChannelImpl* channel) {
473 ASSERT(channels_.find(channel->component()) != channels_.end());
474 UpdateGatheringState();
475 if (gathering_state_ == kIceGatheringComplete) {
476 // If UpdateGatheringState brought us to kIceGatheringComplete, check if
477 // our connection state is also "Completed". Otherwise, there's no point in
478 // checking (since it would only produce log messages).
479 MaybeSignalCompleted();
480 }
481 }
482
483 void Transport::OnChannelCandidateGathered(TransportChannelImpl* channel,
484 const Candidate& candidate) {
485 // We should never signal peer-reflexive candidates.
486 if (candidate.type() == PRFLX_PORT_TYPE) {
487 ASSERT(false);
488 return;
489 }
490
491 ASSERT(connect_requested_);
492 std::vector<Candidate> candidates;
493 candidates.push_back(candidate);
494 SignalCandidatesGathered(this, candidates);
495 }
496
497 void Transport::OnChannelRouteChange(TransportChannel* channel,
498 const Candidate& remote_candidate) {
499 SignalRouteChange(this, remote_candidate.component(), remote_candidate);
500 }
501
502 void Transport::OnRoleConflict(TransportChannelImpl* channel) {
503 SignalRoleConflict();
504 }
505
506 void Transport::OnChannelConnectionRemoved(TransportChannelImpl* channel) {
507 LOG(LS_INFO) << name() << " TransportChannel " << channel->component()
508 << " connection removed. Check if transport is complete.";
509 MaybeSignalCompleted();
510
511 // Check if the state is now Failed.
512 // Failed is only available in the Controlling ICE role.
513 if (channel->GetIceRole() != ICEROLE_CONTROLLING) {
514 return;
515 }
516
517 // Failed can only occur after candidate gathering has stopped.
518 if (channel->gathering_state() != kIceGatheringComplete) {
519 return;
520 }
521
522 if (channel->GetState() == TransportChannelState::STATE_FAILED) {
523 // A Transport has failed if any of its channels have no remaining
524 // connections.
525 SignalFailed(this);
526 }
527 }
528
529 void Transport::MaybeSignalCompleted() {
530 if (AllChannelsCompleted()) {
531 LOG(LS_INFO) << name() << " transport is complete"
532 << " because all the channels are complete.";
533 SignalCompleted(this);
534 }
535 // TODO(deadbeef): Should we do anything if we previously were completed,
536 // but now are not (if, for example, a new remote candidate is added)?
537 }
538
539 void Transport::UpdateGatheringState() {
540 IceGatheringState new_state = kIceGatheringNew;
541 bool any_gathering = false;
542 bool all_complete = !channels_.empty();
543 for (const auto& kv : channels_) {
544 any_gathering =
545 any_gathering || kv.second->gathering_state() != kIceGatheringNew;
546 all_complete =
547 all_complete && kv.second->gathering_state() == kIceGatheringComplete;
548 }
549 if (all_complete) {
550 new_state = kIceGatheringComplete;
551 } else if (any_gathering) {
552 new_state = kIceGatheringGathering;
553 }
554
555 if (gathering_state_ != new_state) {
556 gathering_state_ = new_state;
557 if (gathering_state_ == kIceGatheringGathering) {
558 LOG(LS_INFO) << "Transport: " << name_ << ", gathering candidates";
559 } else if (gathering_state_ == kIceGatheringComplete) {
560 LOG(LS_INFO) << "Transport " << name() << " gathering complete.";
561 }
562 SignalGatheringState(this);
563 }
564 }
565
566 void Transport::UpdateReceivingState() {
567 TransportState receiving = GetTransportState(TRANSPORT_RECEIVING_STATE);
568 if (receiving_ != receiving) {
569 receiving_ = receiving;
570 SignalReceivingState(this);
571 }
572 }
573
574 void Transport::UpdateWritableState() {
575 TransportState writable = GetTransportState(TRANSPORT_WRITABLE_STATE);
576 LOG(LS_INFO) << name() << " transport writable state changed? " << writable_
577 << " => " << writable;
578 if (writable_ != writable) {
579 was_writable_ = (writable_ == TRANSPORT_STATE_ALL);
580 writable_ = writable;
581 SignalWritableState(this);
582 }
583 }
584
585 bool Transport::ApplyLocalTransportDescription(TransportChannelImpl* ch, 367 bool Transport::ApplyLocalTransportDescription(TransportChannelImpl* ch,
586 std::string* error_desc) { 368 std::string* error_desc) {
587 ch->SetIceCredentials(local_description_->ice_ufrag, 369 ch->SetIceCredentials(local_description_->ice_ufrag,
588 local_description_->ice_pwd); 370 local_description_->ice_pwd);
589 return true; 371 return true;
590 } 372 }
591 373
592 bool Transport::ApplyRemoteTransportDescription(TransportChannelImpl* ch, 374 bool Transport::ApplyRemoteTransportDescription(TransportChannelImpl* ch,
593 std::string* error_desc) { 375 std::string* error_desc) {
594 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag, 376 ch->SetRemoteIceCredentials(remote_description_->ice_ufrag,
(...skipping 29 matching lines...) Expand all
624 // creation, we have the negotiation state saved until a new 406 // creation, we have the negotiation state saved until a new
625 // negotiation happens. 407 // negotiation happens.
626 for (auto& iter : channels_) { 408 for (auto& iter : channels_) {
627 if (!ApplyNegotiatedTransportDescription(iter.second.get(), error_desc)) 409 if (!ApplyNegotiatedTransportDescription(iter.second.get(), error_desc))
628 return false; 410 return false;
629 } 411 }
630 return true; 412 return true;
631 } 413 }
632 414
633 } // namespace cricket 415 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698