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

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

Issue 2563153002: Implement the "needs-ice-restart" logic for SetConfiguration. (Closed)
Patch Set: Fixing signed/unsigned comparison warning. Created 4 years 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
« no previous file with comments | « webrtc/p2p/base/transportcontroller.h ('k') | webrtc/p2p/base/transportcontroller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 RTC_FROM_HERE, 73 RTC_FROM_HERE,
74 rtc::Bind(&TransportController::SetIceConfig_n, this, config)); 74 rtc::Bind(&TransportController::SetIceConfig_n, this, config));
75 } 75 }
76 76
77 void TransportController::SetIceRole(IceRole ice_role) { 77 void TransportController::SetIceRole(IceRole ice_role) {
78 network_thread_->Invoke<void>( 78 network_thread_->Invoke<void>(
79 RTC_FROM_HERE, 79 RTC_FROM_HERE,
80 rtc::Bind(&TransportController::SetIceRole_n, this, ice_role)); 80 rtc::Bind(&TransportController::SetIceRole_n, this, ice_role));
81 } 81 }
82 82
83 void TransportController::SetNeedsIceRestartFlag() {
84 for (auto& kv : transports_) {
85 kv.second->SetNeedsIceRestartFlag();
86 }
87 }
88
89 bool TransportController::NeedsIceRestart(
90 const std::string& transport_name) const {
91 const JsepTransport* transport = GetJsepTransport(transport_name);
92 if (!transport) {
93 return false;
94 }
95 return transport->NeedsIceRestart();
96 }
97
83 bool TransportController::GetSslRole(const std::string& transport_name, 98 bool TransportController::GetSslRole(const std::string& transport_name,
84 rtc::SSLRole* role) const { 99 rtc::SSLRole* role) const {
85 return network_thread_->Invoke<bool>( 100 return network_thread_->Invoke<bool>(
86 RTC_FROM_HERE, rtc::Bind(&TransportController::GetSslRole_n, this, 101 RTC_FROM_HERE, rtc::Bind(&TransportController::GetSslRole_n, this,
87 transport_name, role)); 102 transport_name, role));
88 } 103 }
89 104
90 bool TransportController::SetLocalCertificate( 105 bool TransportController::SetLocalCertificate(
91 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 106 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
92 return network_thread_->Invoke<bool>( 107 return network_thread_->Invoke<bool>(
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 RTC_DCHECK(network_thread_->IsCurrent()); 195 RTC_DCHECK(network_thread_->IsCurrent());
181 196
182 RefCountedChannel* existing_channel = GetChannel_n(transport_name, component); 197 RefCountedChannel* existing_channel = GetChannel_n(transport_name, component);
183 if (existing_channel) { 198 if (existing_channel) {
184 // Channel already exists; increment reference count and return. 199 // Channel already exists; increment reference count and return.
185 existing_channel->AddRef(); 200 existing_channel->AddRef();
186 return existing_channel->dtls(); 201 return existing_channel->dtls();
187 } 202 }
188 203
189 // Need to create a new channel. 204 // Need to create a new channel.
190 JsepTransport* transport = GetOrCreateJsepTransport_n(transport_name); 205 JsepTransport* transport = GetOrCreateJsepTransport(transport_name);
191 206
192 // Create DTLS channel wrapping ICE channel, and configure it. 207 // Create DTLS channel wrapping ICE channel, and configure it.
193 TransportChannelImpl* ice = 208 TransportChannelImpl* ice =
194 CreateIceTransportChannel_n(transport_name, component); 209 CreateIceTransportChannel_n(transport_name, component);
195 // TODO(deadbeef): To support QUIC, would need to create a 210 // TODO(deadbeef): To support QUIC, would need to create a
196 // QuicTransportChannel here. What is "dtls" in this file would then become 211 // QuicTransportChannel here. What is "dtls" in this file would then become
197 // "dtls or quic". 212 // "dtls or quic".
198 TransportChannelImpl* dtls = 213 TransportChannelImpl* dtls =
199 CreateDtlsTransportChannel_n(transport_name, component, ice); 214 CreateDtlsTransportChannel_n(transport_name, component, ice);
200 dtls->SetMetricsObserver(metrics_observer_); 215 dtls->SetMetricsObserver(metrics_observer_);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 << " TransportChannel " << component 259 << " TransportChannel " << component
245 << ", which doesn't exist."; 260 << ", which doesn't exist.";
246 return; 261 return;
247 } 262 }
248 it->DecRef(); 263 it->DecRef();
249 if (it->ref() > 0) { 264 if (it->ref() > 0) {
250 return; 265 return;
251 } 266 }
252 channels_.erase(it); 267 channels_.erase(it);
253 268
254 JsepTransport* t = GetJsepTransport_n(transport_name); 269 JsepTransport* t = GetJsepTransport(transport_name);
255 bool channel_removed = t->RemoveChannel(component); 270 bool channel_removed = t->RemoveChannel(component);
256 RTC_DCHECK(channel_removed); 271 RTC_DCHECK(channel_removed);
257 // Just as we create a Transport when its first channel is created, 272 // Just as we create a Transport when its first channel is created,
258 // we delete it when its last channel is deleted. 273 // we delete it when its last channel is deleted.
259 if (!t->HasChannels()) { 274 if (!t->HasChannels()) {
260 transports_.erase(transport_name); 275 transports_.erase(transport_name);
261 } 276 }
262 277
263 // Removing a channel could cause aggregate state to change. 278 // Removing a channel could cause aggregate state to change.
264 UpdateAggregateStates_n(); 279 UpdateAggregateStates_n();
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 int component) const { 370 int component) const {
356 RTC_DCHECK(network_thread_->IsCurrent()); 371 RTC_DCHECK(network_thread_->IsCurrent());
357 return std::find_if( 372 return std::find_if(
358 channels_.begin(), channels_.end(), 373 channels_.begin(), channels_.end(),
359 [transport_name, component](const RefCountedChannel& channel) { 374 [transport_name, component](const RefCountedChannel& channel) {
360 return channel.dtls()->transport_name() == transport_name && 375 return channel.dtls()->transport_name() == transport_name &&
361 channel.dtls()->component() == component; 376 channel.dtls()->component() == component;
362 }); 377 });
363 } 378 }
364 379
365 const JsepTransport* TransportController::GetJsepTransport_n( 380 const JsepTransport* TransportController::GetJsepTransport(
366 const std::string& transport_name) const { 381 const std::string& transport_name) const {
367 RTC_DCHECK(network_thread_->IsCurrent());
368 auto it = transports_.find(transport_name); 382 auto it = transports_.find(transport_name);
369 return (it == transports_.end()) ? nullptr : it->second.get(); 383 return (it == transports_.end()) ? nullptr : it->second.get();
370 } 384 }
371 385
372 JsepTransport* TransportController::GetJsepTransport_n( 386 JsepTransport* TransportController::GetJsepTransport(
373 const std::string& transport_name) { 387 const std::string& transport_name) {
374 RTC_DCHECK(network_thread_->IsCurrent());
375 auto it = transports_.find(transport_name); 388 auto it = transports_.find(transport_name);
376 return (it == transports_.end()) ? nullptr : it->second.get(); 389 return (it == transports_.end()) ? nullptr : it->second.get();
377 } 390 }
378 391
379 const TransportController::RefCountedChannel* TransportController::GetChannel_n( 392 const TransportController::RefCountedChannel* TransportController::GetChannel_n(
380 const std::string& transport_name, 393 const std::string& transport_name,
381 int component) const { 394 int component) const {
382 RTC_DCHECK(network_thread_->IsCurrent()); 395 RTC_DCHECK(network_thread_->IsCurrent());
383 auto it = GetChannelIterator_n(transport_name, component); 396 auto it = GetChannelIterator_n(transport_name, component);
384 return (it == channels_.end()) ? nullptr : &(*it); 397 return (it == channels_.end()) ? nullptr : &(*it);
385 } 398 }
386 399
387 TransportController::RefCountedChannel* TransportController::GetChannel_n( 400 TransportController::RefCountedChannel* TransportController::GetChannel_n(
388 const std::string& transport_name, 401 const std::string& transport_name,
389 int component) { 402 int component) {
390 RTC_DCHECK(network_thread_->IsCurrent()); 403 RTC_DCHECK(network_thread_->IsCurrent());
391 auto it = GetChannelIterator_n(transport_name, component); 404 auto it = GetChannelIterator_n(transport_name, component);
392 return (it == channels_.end()) ? nullptr : &(*it); 405 return (it == channels_.end()) ? nullptr : &(*it);
393 } 406 }
394 407
395 JsepTransport* TransportController::GetOrCreateJsepTransport_n( 408 JsepTransport* TransportController::GetOrCreateJsepTransport(
396 const std::string& transport_name) { 409 const std::string& transport_name) {
397 RTC_DCHECK(network_thread_->IsCurrent()); 410 RTC_DCHECK(network_thread_->IsCurrent());
398 411
399 JsepTransport* transport = GetJsepTransport_n(transport_name); 412 JsepTransport* transport = GetJsepTransport(transport_name);
400 if (transport) { 413 if (transport) {
401 return transport; 414 return transport;
402 } 415 }
403 416
404 transport = new JsepTransport(transport_name, certificate_); 417 transport = new JsepTransport(transport_name, certificate_);
405 transports_[transport_name] = std::unique_ptr<JsepTransport>(transport); 418 transports_[transport_name] = std::unique_ptr<JsepTransport>(transport);
406 return transport; 419 return transport;
407 } 420 }
408 421
409 void TransportController::DestroyAllChannels_n() { 422 void TransportController::DestroyAllChannels_n() {
(...skipping 30 matching lines...) Expand all
440 ice_role_ = ice_role; 453 ice_role_ = ice_role;
441 for (auto& channel : channels_) { 454 for (auto& channel : channels_) {
442 channel.dtls()->SetIceRole(ice_role_); 455 channel.dtls()->SetIceRole(ice_role_);
443 } 456 }
444 } 457 }
445 458
446 bool TransportController::GetSslRole_n(const std::string& transport_name, 459 bool TransportController::GetSslRole_n(const std::string& transport_name,
447 rtc::SSLRole* role) const { 460 rtc::SSLRole* role) const {
448 RTC_DCHECK(network_thread_->IsCurrent()); 461 RTC_DCHECK(network_thread_->IsCurrent());
449 462
450 const JsepTransport* t = GetJsepTransport_n(transport_name); 463 const JsepTransport* t = GetJsepTransport(transport_name);
451 if (!t) { 464 if (!t) {
452 return false; 465 return false;
453 } 466 }
454 t->GetSslRole(role); 467 t->GetSslRole(role);
455 return true; 468 return true;
456 } 469 }
457 470
458 bool TransportController::SetLocalCertificate_n( 471 bool TransportController::SetLocalCertificate_n(
459 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) { 472 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
460 RTC_DCHECK(network_thread_->IsCurrent()); 473 RTC_DCHECK(network_thread_->IsCurrent());
(...skipping 15 matching lines...) Expand all
476 RTC_DCHECK(set_cert_success); 489 RTC_DCHECK(set_cert_success);
477 } 490 }
478 return true; 491 return true;
479 } 492 }
480 493
481 bool TransportController::GetLocalCertificate_n( 494 bool TransportController::GetLocalCertificate_n(
482 const std::string& transport_name, 495 const std::string& transport_name,
483 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const { 496 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const {
484 RTC_DCHECK(network_thread_->IsCurrent()); 497 RTC_DCHECK(network_thread_->IsCurrent());
485 498
486 const JsepTransport* t = GetJsepTransport_n(transport_name); 499 const JsepTransport* t = GetJsepTransport(transport_name);
487 if (!t) { 500 if (!t) {
488 return false; 501 return false;
489 } 502 }
490 return t->GetLocalCertificate(certificate); 503 return t->GetLocalCertificate(certificate);
491 } 504 }
492 505
493 std::unique_ptr<rtc::SSLCertificate> 506 std::unique_ptr<rtc::SSLCertificate>
494 TransportController::GetRemoteSSLCertificate_n( 507 TransportController::GetRemoteSSLCertificate_n(
495 const std::string& transport_name) const { 508 const std::string& transport_name) const {
496 RTC_DCHECK(network_thread_->IsCurrent()); 509 RTC_DCHECK(network_thread_->IsCurrent());
497 510
498 // Get the certificate from the RTP channel's DTLS handshake. Should be 511 // Get the certificate from the RTP channel's DTLS handshake. Should be
499 // identical to the RTCP channel's, since they were given the same remote 512 // identical to the RTCP channel's, since they were given the same remote
500 // fingerprint. 513 // fingerprint.
501 const RefCountedChannel* ch = GetChannel_n(transport_name, 1); 514 const RefCountedChannel* ch = GetChannel_n(transport_name, 1);
502 if (!ch) { 515 if (!ch) {
503 return nullptr; 516 return nullptr;
504 } 517 }
505 return ch->dtls()->GetRemoteSSLCertificate(); 518 return ch->dtls()->GetRemoteSSLCertificate();
506 } 519 }
507 520
508 bool TransportController::SetLocalTransportDescription_n( 521 bool TransportController::SetLocalTransportDescription_n(
509 const std::string& transport_name, 522 const std::string& transport_name,
510 const TransportDescription& tdesc, 523 const TransportDescription& tdesc,
511 ContentAction action, 524 ContentAction action,
512 std::string* err) { 525 std::string* err) {
513 RTC_DCHECK(network_thread_->IsCurrent()); 526 RTC_DCHECK(network_thread_->IsCurrent());
514 527
515 JsepTransport* transport = GetJsepTransport_n(transport_name); 528 JsepTransport* transport = GetJsepTransport(transport_name);
516 if (!transport) { 529 if (!transport) {
517 // If we didn't find a transport, that's not an error; 530 // If we didn't find a transport, that's not an error;
518 // it could have been deleted as a result of bundling. 531 // it could have been deleted as a result of bundling.
519 // TODO(deadbeef): Make callers smarter so they won't attempt to set a 532 // TODO(deadbeef): Make callers smarter so they won't attempt to set a
520 // description on a deleted transport. 533 // description on a deleted transport.
521 return true; 534 return true;
522 } 535 }
523 536
524 // Older versions of Chrome expect the ICE role to be re-determined when an 537 // Older versions of Chrome expect the ICE role to be re-determined when an
525 // ICE restart occurs, and also don't perform conflict resolution correctly, 538 // ICE restart occurs, and also don't perform conflict resolution correctly,
(...skipping 23 matching lines...) Expand all
549 RTC_DCHECK(network_thread_->IsCurrent()); 562 RTC_DCHECK(network_thread_->IsCurrent());
550 563
551 // If our role is ICEROLE_CONTROLLED and the remote endpoint supports only 564 // If our role is ICEROLE_CONTROLLED and the remote endpoint supports only
552 // ice_lite, this local endpoint should take the CONTROLLING role. 565 // ice_lite, this local endpoint should take the CONTROLLING role.
553 // TODO(deadbeef): This is a session-level attribute, so it really shouldn't 566 // TODO(deadbeef): This is a session-level attribute, so it really shouldn't
554 // be in a TransportDescription in the first place... 567 // be in a TransportDescription in the first place...
555 if (ice_role_ == ICEROLE_CONTROLLED && tdesc.ice_mode == ICEMODE_LITE) { 568 if (ice_role_ == ICEROLE_CONTROLLED && tdesc.ice_mode == ICEMODE_LITE) {
556 SetIceRole_n(ICEROLE_CONTROLLING); 569 SetIceRole_n(ICEROLE_CONTROLLING);
557 } 570 }
558 571
559 JsepTransport* transport = GetJsepTransport_n(transport_name); 572 JsepTransport* transport = GetJsepTransport(transport_name);
560 if (!transport) { 573 if (!transport) {
561 // If we didn't find a transport, that's not an error; 574 // If we didn't find a transport, that's not an error;
562 // it could have been deleted as a result of bundling. 575 // it could have been deleted as a result of bundling.
563 // TODO(deadbeef): Make callers smarter so they won't attempt to set a 576 // TODO(deadbeef): Make callers smarter so they won't attempt to set a
564 // description on a deleted transport. 577 // description on a deleted transport.
565 return true; 578 return true;
566 } 579 }
567 580
568 LOG(LS_INFO) << "Set remote transport description on " << transport_name; 581 LOG(LS_INFO) << "Set remote transport description on " << transport_name;
569 return transport->SetRemoteTransportDescription(tdesc, action, err); 582 return transport->SetRemoteTransportDescription(tdesc, action, err);
570 } 583 }
571 584
572 void TransportController::MaybeStartGathering_n() { 585 void TransportController::MaybeStartGathering_n() {
573 for (auto& channel : channels_) { 586 for (auto& channel : channels_) {
574 channel.dtls()->MaybeStartGathering(); 587 channel.dtls()->MaybeStartGathering();
575 } 588 }
576 } 589 }
577 590
578 bool TransportController::AddRemoteCandidates_n( 591 bool TransportController::AddRemoteCandidates_n(
579 const std::string& transport_name, 592 const std::string& transport_name,
580 const Candidates& candidates, 593 const Candidates& candidates,
581 std::string* err) { 594 std::string* err) {
582 RTC_DCHECK(network_thread_->IsCurrent()); 595 RTC_DCHECK(network_thread_->IsCurrent());
583 596
584 // Verify each candidate before passing down to the transport layer. 597 // Verify each candidate before passing down to the transport layer.
585 if (!VerifyCandidates(candidates, err)) { 598 if (!VerifyCandidates(candidates, err)) {
586 return false; 599 return false;
587 } 600 }
588 601
589 JsepTransport* transport = GetJsepTransport_n(transport_name); 602 JsepTransport* transport = GetJsepTransport(transport_name);
590 if (!transport) { 603 if (!transport) {
591 // If we didn't find a transport, that's not an error; 604 // If we didn't find a transport, that's not an error;
592 // it could have been deleted as a result of bundling. 605 // it could have been deleted as a result of bundling.
593 return true; 606 return true;
594 } 607 }
595 608
596 for (const Candidate& candidate : candidates) { 609 for (const Candidate& candidate : candidates) {
597 RefCountedChannel* channel = 610 RefCountedChannel* channel =
598 GetChannel_n(transport_name, candidate.component()); 611 GetChannel_n(transport_name, candidate.component());
599 if (!channel) { 612 if (!channel) {
(...skipping 18 matching lines...) Expand all
618 std::map<std::string, Candidates> candidates_by_transport_name; 631 std::map<std::string, Candidates> candidates_by_transport_name;
619 for (const Candidate& cand : candidates) { 632 for (const Candidate& cand : candidates) {
620 RTC_DCHECK(!cand.transport_name().empty()); 633 RTC_DCHECK(!cand.transport_name().empty());
621 candidates_by_transport_name[cand.transport_name()].push_back(cand); 634 candidates_by_transport_name[cand.transport_name()].push_back(cand);
622 } 635 }
623 636
624 bool result = true; 637 bool result = true;
625 for (const auto& kv : candidates_by_transport_name) { 638 for (const auto& kv : candidates_by_transport_name) {
626 const std::string& transport_name = kv.first; 639 const std::string& transport_name = kv.first;
627 const Candidates& candidates = kv.second; 640 const Candidates& candidates = kv.second;
628 JsepTransport* transport = GetJsepTransport_n(transport_name); 641 JsepTransport* transport = GetJsepTransport(transport_name);
629 if (!transport) { 642 if (!transport) {
630 // If we didn't find a transport, that's not an error; 643 // If we didn't find a transport, that's not an error;
631 // it could have been deleted as a result of bundling. 644 // it could have been deleted as a result of bundling.
632 continue; 645 continue;
633 } 646 }
634 for (const Candidate& candidate : candidates) { 647 for (const Candidate& candidate : candidates) {
635 RefCountedChannel* channel = 648 RefCountedChannel* channel =
636 GetChannel_n(transport_name, candidate.component()); 649 GetChannel_n(transport_name, candidate.component());
637 if (channel) { 650 if (channel) {
638 channel->dtls()->RemoveRemoteCandidate(candidate); 651 channel->dtls()->RemoveRemoteCandidate(candidate);
639 } 652 }
640 } 653 }
641 } 654 }
642 return result; 655 return result;
643 } 656 }
644 657
645 bool TransportController::ReadyForRemoteCandidates_n( 658 bool TransportController::ReadyForRemoteCandidates_n(
646 const std::string& transport_name) const { 659 const std::string& transport_name) const {
647 RTC_DCHECK(network_thread_->IsCurrent()); 660 RTC_DCHECK(network_thread_->IsCurrent());
648 661
649 const JsepTransport* transport = GetJsepTransport_n(transport_name); 662 const JsepTransport* transport = GetJsepTransport(transport_name);
650 if (!transport) { 663 if (!transport) {
651 return false; 664 return false;
652 } 665 }
653 return transport->ready_for_remote_candidates(); 666 return transport->ready_for_remote_candidates();
654 } 667 }
655 668
656 bool TransportController::GetStats_n(const std::string& transport_name, 669 bool TransportController::GetStats_n(const std::string& transport_name,
657 TransportStats* stats) { 670 TransportStats* stats) {
658 RTC_DCHECK(network_thread_->IsCurrent()); 671 RTC_DCHECK(network_thread_->IsCurrent());
659 672
660 JsepTransport* transport = GetJsepTransport_n(transport_name); 673 JsepTransport* transport = GetJsepTransport(transport_name);
661 if (!transport) { 674 if (!transport) {
662 return false; 675 return false;
663 } 676 }
664 return transport->GetStats(stats); 677 return transport->GetStats(stats);
665 } 678 }
666 679
667 void TransportController::SetMetricsObserver_n( 680 void TransportController::SetMetricsObserver_n(
668 webrtc::MetricsObserverInterface* metrics_observer) { 681 webrtc::MetricsObserverInterface* metrics_observer) {
669 RTC_DCHECK(network_thread_->IsCurrent()); 682 RTC_DCHECK(network_thread_->IsCurrent());
670 metrics_observer_ = metrics_observer; 683 metrics_observer_ = metrics_observer;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 RTC_FROM_HERE, this, MSG_ICEGATHERINGSTATE, 823 RTC_FROM_HERE, this, MSG_ICEGATHERINGSTATE,
811 new rtc::TypedMessageData<IceGatheringState>(new_gathering_state)); 824 new rtc::TypedMessageData<IceGatheringState>(new_gathering_state));
812 } 825 }
813 } 826 }
814 827
815 void TransportController::OnDtlsHandshakeError(rtc::SSLHandshakeError error) { 828 void TransportController::OnDtlsHandshakeError(rtc::SSLHandshakeError error) {
816 SignalDtlsHandshakeError(error); 829 SignalDtlsHandshakeError(error);
817 } 830 }
818 831
819 } // namespace cricket 832 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/transportcontroller.h ('k') | webrtc/p2p/base/transportcontroller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698