1 /*
2  *  Copyright 2015 The WebRTC Project Authors. All rights reserved.
3  *
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
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "webrtc/p2p/base/transportcontroller.h"
12 
13 #include <algorithm>
14 #include <memory>
15 
16 #include "webrtc/base/bind.h"
17 #include "webrtc/base/checks.h"
18 #include "webrtc/base/thread.h"
19 #include "webrtc/p2p/base/port.h"
20 
21 namespace {
22 
23 enum {
24   MSG_ICECONNECTIONSTATE,
25   MSG_RECEIVING,
26   MSG_ICEGATHERINGSTATE,
27   MSG_CANDIDATESGATHERED,
28 };
29 
30 struct CandidatesData : public rtc::MessageData {
CandidatesData__anon1ec14e520111::CandidatesData31   CandidatesData(const std::string& transport_name,
32                  const cricket::Candidates& candidates)
33       : transport_name(transport_name), candidates(candidates) {}
34 
35   std::string transport_name;
36   cricket::Candidates candidates;
37 };
38 
39 }  // namespace {
40 
41 namespace cricket {
42 
43 // This class groups the DTLS and ICE channels, and helps keep track of
44 // how many external objects (BaseChannels) reference each channel.
45 class TransportController::ChannelPair {
46  public:
47   // TODO(deadbeef): Change the types of |dtls| and |ice| to
48   // DtlsTransportChannelWrapper and P2PTransportChannelWrapper,
49   // once TransportChannelImpl is removed.
ChannelPair(TransportChannelImpl * dtls,IceTransportInternal * ice)50   ChannelPair(TransportChannelImpl* dtls, IceTransportInternal* ice)
51       : ice_(ice), dtls_(dtls) {}
52 
53   // Currently, all ICE-related calls still go through this DTLS channel. But
54   // that will change once we get rid of TransportChannelImpl, and the DTLS
55   // channel interface no longer includes ICE-specific methods.
dtls() const56   const TransportChannelImpl* dtls() const { return dtls_.get(); }
dtls()57   TransportChannelImpl* dtls() { return dtls_.get(); }
ice() const58   const IceTransportInternal* ice() const { return ice_.get(); }
ice()59   IceTransportInternal* ice() { return ice_.get(); }
60 
61  private:
62   std::unique_ptr<IceTransportInternal> ice_;
63   std::unique_ptr<TransportChannelImpl> dtls_;
64 
65   RTC_DISALLOW_COPY_AND_ASSIGN(ChannelPair);
66 };
67 
TransportController(rtc::Thread * signaling_thread,rtc::Thread * network_thread,PortAllocator * port_allocator,bool redetermine_role_on_ice_restart)68 TransportController::TransportController(rtc::Thread* signaling_thread,
69                                          rtc::Thread* network_thread,
70                                          PortAllocator* port_allocator,
71                                          bool redetermine_role_on_ice_restart)
72     : signaling_thread_(signaling_thread),
73       network_thread_(network_thread),
74       port_allocator_(port_allocator),
75       redetermine_role_on_ice_restart_(redetermine_role_on_ice_restart) {}
76 
TransportController(rtc::Thread * signaling_thread,rtc::Thread * network_thread,PortAllocator * port_allocator)77 TransportController::TransportController(rtc::Thread* signaling_thread,
78                                          rtc::Thread* network_thread,
79                                          PortAllocator* port_allocator)
80     : TransportController(signaling_thread,
81                           network_thread,
82                           port_allocator,
83                           true) {}
84 
~TransportController()85 TransportController::~TransportController() {
86   // Channel destructors may try to send packets, so this needs to happen on
87   // the network thread.
88   network_thread_->Invoke<void>(
89       RTC_FROM_HERE,
90       rtc::Bind(&TransportController::DestroyAllChannels_n, this));
91 }
92 
SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version)93 bool TransportController::SetSslMaxProtocolVersion(
94     rtc::SSLProtocolVersion version) {
95   return network_thread_->Invoke<bool>(
96       RTC_FROM_HERE, rtc::Bind(&TransportController::SetSslMaxProtocolVersion_n,
97                                this, version));
98 }
99 
SetIceConfig(const IceConfig & config)100 void TransportController::SetIceConfig(const IceConfig& config) {
101   network_thread_->Invoke<void>(
102       RTC_FROM_HERE,
103       rtc::Bind(&TransportController::SetIceConfig_n, this, config));
104 }
105 
SetIceRole(IceRole ice_role)106 void TransportController::SetIceRole(IceRole ice_role) {
107   network_thread_->Invoke<void>(
108       RTC_FROM_HERE,
109       rtc::Bind(&TransportController::SetIceRole_n, this, ice_role));
110 }
111 
SetNeedsIceRestartFlag()112 void TransportController::SetNeedsIceRestartFlag() {
113   for (auto& kv : transports_) {
114     kv.second->SetNeedsIceRestartFlag();
115   }
116 }
117 
NeedsIceRestart(const std::string & transport_name) const118 bool TransportController::NeedsIceRestart(
119     const std::string& transport_name) const {
120   const JsepTransport* transport = GetJsepTransport(transport_name);
121   if (!transport) {
122     return false;
123   }
124   return transport->NeedsIceRestart();
125 }
126 
GetSslRole(const std::string & transport_name,rtc::SSLRole * role) const127 bool TransportController::GetSslRole(const std::string& transport_name,
128                                      rtc::SSLRole* role) const {
129   return network_thread_->Invoke<bool>(
130       RTC_FROM_HERE, rtc::Bind(&TransportController::GetSslRole_n, this,
131                                transport_name, role));
132 }
133 
SetLocalCertificate(const rtc::scoped_refptr<rtc::RTCCertificate> & certificate)134 bool TransportController::SetLocalCertificate(
135     const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
136   return network_thread_->Invoke<bool>(
137       RTC_FROM_HERE, rtc::Bind(&TransportController::SetLocalCertificate_n,
138                                this, certificate));
139 }
140 
GetLocalCertificate(const std::string & transport_name,rtc::scoped_refptr<rtc::RTCCertificate> * certificate) const141 bool TransportController::GetLocalCertificate(
142     const std::string& transport_name,
143     rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const {
144   if (network_thread_->IsCurrent()) {
145     return GetLocalCertificate_n(transport_name, certificate);
146   }
147   return network_thread_->Invoke<bool>(
148       RTC_FROM_HERE, rtc::Bind(&TransportController::GetLocalCertificate_n,
149                                this, transport_name, certificate));
150 }
151 
152 std::unique_ptr<rtc::SSLCertificate>
GetRemoteSSLCertificate(const std::string & transport_name) const153 TransportController::GetRemoteSSLCertificate(
154     const std::string& transport_name) const {
155   if (network_thread_->IsCurrent()) {
156     return GetRemoteSSLCertificate_n(transport_name);
157   }
158   return network_thread_->Invoke<std::unique_ptr<rtc::SSLCertificate>>(
159       RTC_FROM_HERE, rtc::Bind(&TransportController::GetRemoteSSLCertificate_n,
160                                this, transport_name));
161 }
162 
SetLocalTransportDescription(const std::string & transport_name,const TransportDescription & tdesc,ContentAction action,std::string * err)163 bool TransportController::SetLocalTransportDescription(
164     const std::string& transport_name,
165     const TransportDescription& tdesc,
166     ContentAction action,
167     std::string* err) {
168   return network_thread_->Invoke<bool>(
169       RTC_FROM_HERE,
170       rtc::Bind(&TransportController::SetLocalTransportDescription_n, this,
171                 transport_name, tdesc, action, err));
172 }
173 
SetRemoteTransportDescription(const std::string & transport_name,const TransportDescription & tdesc,ContentAction action,std::string * err)174 bool TransportController::SetRemoteTransportDescription(
175     const std::string& transport_name,
176     const TransportDescription& tdesc,
177     ContentAction action,
178     std::string* err) {
179   return network_thread_->Invoke<bool>(
180       RTC_FROM_HERE,
181       rtc::Bind(&TransportController::SetRemoteTransportDescription_n, this,
182                 transport_name, tdesc, action, err));
183 }
184 
MaybeStartGathering()185 void TransportController::MaybeStartGathering() {
186   network_thread_->Invoke<void>(
187       RTC_FROM_HERE,
188       rtc::Bind(&TransportController::MaybeStartGathering_n, this));
189 }
190 
AddRemoteCandidates(const std::string & transport_name,const Candidates & candidates,std::string * err)191 bool TransportController::AddRemoteCandidates(const std::string& transport_name,
192                                               const Candidates& candidates,
193                                               std::string* err) {
194   return network_thread_->Invoke<bool>(
195       RTC_FROM_HERE, rtc::Bind(&TransportController::AddRemoteCandidates_n,
196                                this, transport_name, candidates, err));
197 }
198 
RemoveRemoteCandidates(const Candidates & candidates,std::string * err)199 bool TransportController::RemoveRemoteCandidates(const Candidates& candidates,
200                                                  std::string* err) {
201   return network_thread_->Invoke<bool>(
202       RTC_FROM_HERE, rtc::Bind(&TransportController::RemoveRemoteCandidates_n,
203                                this, candidates, err));
204 }
205 
ReadyForRemoteCandidates(const std::string & transport_name) const206 bool TransportController::ReadyForRemoteCandidates(
207     const std::string& transport_name) const {
208   return network_thread_->Invoke<bool>(
209       RTC_FROM_HERE, rtc::Bind(&TransportController::ReadyForRemoteCandidates_n,
210                                this, transport_name));
211 }
212 
GetStats(const std::string & transport_name,TransportStats * stats)213 bool TransportController::GetStats(const std::string& transport_name,
214                                    TransportStats* stats) {
215   if (network_thread_->IsCurrent()) {
216     return GetStats_n(transport_name, stats);
217   }
218   return network_thread_->Invoke<bool>(
219       RTC_FROM_HERE,
220       rtc::Bind(&TransportController::GetStats_n, this, transport_name, stats));
221 }
222 
SetMetricsObserver(webrtc::MetricsObserverInterface * metrics_observer)223 void TransportController::SetMetricsObserver(
224     webrtc::MetricsObserverInterface* metrics_observer) {
225   return network_thread_->Invoke<void>(
226       RTC_FROM_HERE, rtc::Bind(&TransportController::SetMetricsObserver_n, this,
227                                metrics_observer));
228 }
229 
CreateTransportChannel(const std::string & transport_name,int component)230 TransportChannel* TransportController::CreateTransportChannel(
231     const std::string& transport_name,
232     int component) {
233   return network_thread_->Invoke<TransportChannel*>(
234       RTC_FROM_HERE, rtc::Bind(&TransportController::CreateTransportChannel_n,
235                                this, transport_name, component));
236 }
237 
CreateTransportChannel_n(const std::string & transport_name,int component)238 TransportChannel* TransportController::CreateTransportChannel_n(
239     const std::string& transport_name,
240     int component) {
241   RTC_DCHECK(network_thread_->IsCurrent());
242 
243   RefCountedChannel* existing_channel = GetChannel_n(transport_name, component);
244   if (existing_channel) {
245     // Channel already exists; increment reference count and return.
246     existing_channel->AddRef();
247     return existing_channel->dtls();
248   }
249 
250   // Need to create a new channel.
251   JsepTransport* transport = GetOrCreateJsepTransport(transport_name);
252 
253   // Create DTLS channel wrapping ICE channel, and configure it.
254   IceTransportInternal* ice =
255       CreateIceTransportChannel_n(transport_name, component);
256   // TODO(deadbeef): To support QUIC, would need to create a
257   // QuicTransportChannel here. What is "dtls" in this file would then become
258   // "dtls or quic".
259   TransportChannelImpl* dtls =
260       CreateDtlsTransportChannel_n(transport_name, component, ice);
261   dtls->SetMetricsObserver(metrics_observer_);
262   dtls->SetIceRole(ice_role_);
263   dtls->SetIceTiebreaker(ice_tiebreaker_);
264   dtls->SetIceConfig(ice_config_);
265 
266   // Connect to signals offered by the channels. Currently, the DTLS channel
267   // forwards signals from the ICE channel, so we only need to connect to the
268   // DTLS channel. In the future this won't be the case.
269   dtls->SignalWritableState.connect(
270       this, &TransportController::OnChannelWritableState_n);
271   dtls->SignalReceivingState.connect(
272       this, &TransportController::OnChannelReceivingState_n);
273   dtls->SignalGatheringState.connect(
274       this, &TransportController::OnChannelGatheringState_n);
275   dtls->SignalCandidateGathered.connect(
276       this, &TransportController::OnChannelCandidateGathered_n);
277   dtls->SignalCandidatesRemoved.connect(
278       this, &TransportController::OnChannelCandidatesRemoved_n);
279   dtls->SignalRoleConflict.connect(
280       this, &TransportController::OnChannelRoleConflict_n);
281   dtls->SignalStateChanged.connect(
282       this, &TransportController::OnChannelStateChanged_n);
283   dtls->SignalDtlsHandshakeError.connect(
284       this, &TransportController::OnDtlsHandshakeError);
285   RefCountedChannel* new_pair = new RefCountedChannel(dtls, ice);
286   new_pair->AddRef();
287   channels_.insert(channels_.end(), new_pair);
288   bool channel_added = transport->AddChannel(dtls, component);
289   RTC_DCHECK(channel_added);
290   // Adding a channel could cause aggregate state to change.
291   UpdateAggregateStates_n();
292   return dtls;
293 }
294 
DestroyTransportChannel_n(const std::string & transport_name,int component)295 void TransportController::DestroyTransportChannel_n(
296     const std::string& transport_name,
297     int component) {
298   RTC_DCHECK(network_thread_->IsCurrent());
299   auto it = GetChannelIterator_n(transport_name, component);
300   if (it == channels_.end()) {
301     LOG(LS_WARNING) << "Attempting to delete " << transport_name
302                     << " TransportChannel " << component
303                     << ", which doesn't exist.";
304     return;
305   }
306   if ((*it)->Release() > 0) {
307     return;
308   }
309   channels_.erase(it);
310 
311   JsepTransport* t = GetJsepTransport(transport_name);
312   bool channel_removed = t->RemoveChannel(component);
313   RTC_DCHECK(channel_removed);
314   // Just as we create a Transport when its first channel is created,
315   // we delete it when its last channel is deleted.
316   if (!t->HasChannels()) {
317     transports_.erase(transport_name);
318   }
319   // Removing a channel could cause aggregate state to change.
320   UpdateAggregateStates_n();
321 }
322 
transport_names_for_testing()323 std::vector<std::string> TransportController::transport_names_for_testing() {
324   std::vector<std::string> ret;
325   for (const auto& kv : transports_) {
326     ret.push_back(kv.first);
327   }
328   return ret;
329 }
330 
channels_for_testing()331 std::vector<TransportChannelImpl*> TransportController::channels_for_testing() {
332   std::vector<TransportChannelImpl*> ret;
333   for (RefCountedChannel* channel : channels_) {
334     ret.push_back(channel->dtls());
335   }
336   return ret;
337 }
338 
get_channel_for_testing(const std::string & transport_name,int component)339 TransportChannelImpl* TransportController::get_channel_for_testing(
340     const std::string& transport_name,
341     int component) {
342   RefCountedChannel* ch = GetChannel_n(transport_name, component);
343   return ch ? ch->dtls() : nullptr;
344 }
345 
CreateIceTransportChannel_n(const std::string & transport_name,int component)346 IceTransportInternal* TransportController::CreateIceTransportChannel_n(
347     const std::string& transport_name,
348     int component) {
349   return new P2PTransportChannel(transport_name, component, port_allocator_);
350 }
351 
CreateDtlsTransportChannel_n(const std::string &,int,IceTransportInternal * ice)352 TransportChannelImpl* TransportController::CreateDtlsTransportChannel_n(
353     const std::string&,
354     int,
355     IceTransportInternal* ice) {
356   DtlsTransportChannelWrapper* dtls = new DtlsTransportChannelWrapper(ice);
357   dtls->SetSslMaxProtocolVersion(ssl_max_version_);
358   return dtls;
359 }
360 
OnMessage(rtc::Message * pmsg)361 void TransportController::OnMessage(rtc::Message* pmsg) {
362   RTC_DCHECK(signaling_thread_->IsCurrent());
363 
364   switch (pmsg->message_id) {
365     case MSG_ICECONNECTIONSTATE: {
366       rtc::TypedMessageData<IceConnectionState>* data =
367           static_cast<rtc::TypedMessageData<IceConnectionState>*>(pmsg->pdata);
368       SignalConnectionState(data->data());
369       delete data;
370       break;
371     }
372     case MSG_RECEIVING: {
373       rtc::TypedMessageData<bool>* data =
374           static_cast<rtc::TypedMessageData<bool>*>(pmsg->pdata);
375       SignalReceiving(data->data());
376       delete data;
377       break;
378     }
379     case MSG_ICEGATHERINGSTATE: {
380       rtc::TypedMessageData<IceGatheringState>* data =
381           static_cast<rtc::TypedMessageData<IceGatheringState>*>(pmsg->pdata);
382       SignalGatheringState(data->data());
383       delete data;
384       break;
385     }
386     case MSG_CANDIDATESGATHERED: {
387       CandidatesData* data = static_cast<CandidatesData*>(pmsg->pdata);
388       SignalCandidatesGathered(data->transport_name, data->candidates);
389       delete data;
390       break;
391     }
392     default:
393       RTC_NOTREACHED();
394   }
395 }
396 
397 std::vector<TransportController::RefCountedChannel*>::iterator
GetChannelIterator_n(const std::string & transport_name,int component)398 TransportController::GetChannelIterator_n(const std::string& transport_name,
399                                           int component) {
400   RTC_DCHECK(network_thread_->IsCurrent());
401   return std::find_if(channels_.begin(), channels_.end(),
402                       [transport_name, component](RefCountedChannel* channel) {
403                         return channel->dtls()->transport_name() ==
404                                    transport_name &&
405                                channel->dtls()->component() == component;
406                       });
407 }
408 
409 std::vector<TransportController::RefCountedChannel*>::const_iterator
GetChannelIterator_n(const std::string & transport_name,int component) const410 TransportController::GetChannelIterator_n(const std::string& transport_name,
411                                           int component) const {
412   RTC_DCHECK(network_thread_->IsCurrent());
413   return std::find_if(
414       channels_.begin(), channels_.end(),
415       [transport_name, component](const RefCountedChannel* channel) {
416         return channel->dtls()->transport_name() == transport_name &&
417                channel->dtls()->component() == component;
418       });
419 }
420 
GetJsepTransport(const std::string & transport_name) const421 const JsepTransport* TransportController::GetJsepTransport(
422     const std::string& transport_name) const {
423   auto it = transports_.find(transport_name);
424   return (it == transports_.end()) ? nullptr : it->second.get();
425 }
426 
GetJsepTransport(const std::string & transport_name)427 JsepTransport* TransportController::GetJsepTransport(
428     const std::string& transport_name) {
429   auto it = transports_.find(transport_name);
430   return (it == transports_.end()) ? nullptr : it->second.get();
431 }
432 
GetChannel_n(const std::string & transport_name,int component) const433 const TransportController::RefCountedChannel* TransportController::GetChannel_n(
434     const std::string& transport_name,
435     int component) const {
436   RTC_DCHECK(network_thread_->IsCurrent());
437   auto it = GetChannelIterator_n(transport_name, component);
438   return (it == channels_.end()) ? nullptr : *it;
439 }
440 
GetChannel_n(const std::string & transport_name,int component)441 TransportController::RefCountedChannel* TransportController::GetChannel_n(
442     const std::string& transport_name,
443     int component) {
444   RTC_DCHECK(network_thread_->IsCurrent());
445   auto it = GetChannelIterator_n(transport_name, component);
446   return (it == channels_.end()) ? nullptr : *it;
447 }
448 
GetOrCreateJsepTransport(const std::string & transport_name)449 JsepTransport* TransportController::GetOrCreateJsepTransport(
450     const std::string& transport_name) {
451   RTC_DCHECK(network_thread_->IsCurrent());
452 
453   JsepTransport* transport = GetJsepTransport(transport_name);
454   if (transport) {
455     return transport;
456   }
457 
458   transport = new JsepTransport(transport_name, certificate_);
459   transports_[transport_name] = std::unique_ptr<JsepTransport>(transport);
460   return transport;
461 }
462 
DestroyAllChannels_n()463 void TransportController::DestroyAllChannels_n() {
464   RTC_DCHECK(network_thread_->IsCurrent());
465   transports_.clear();
466   for (RefCountedChannel* channel : channels_) {
467     // Even though these objects are normally ref-counted, if
468     // TransportController is deleted while they still have references, just
469     // remove all references.
470     while (channel->Release() > 0) {
471     }
472   }
473   channels_.clear();
474 }
475 
SetSslMaxProtocolVersion_n(rtc::SSLProtocolVersion version)476 bool TransportController::SetSslMaxProtocolVersion_n(
477     rtc::SSLProtocolVersion version) {
478   RTC_DCHECK(network_thread_->IsCurrent());
479 
480   // Max SSL version can only be set before transports are created.
481   if (!transports_.empty()) {
482     return false;
483   }
484 
485   ssl_max_version_ = version;
486   return true;
487 }
488 
SetIceConfig_n(const IceConfig & config)489 void TransportController::SetIceConfig_n(const IceConfig& config) {
490   RTC_DCHECK(network_thread_->IsCurrent());
491 
492   ice_config_ = config;
493   for (auto& channel : channels_) {
494     channel->dtls()->SetIceConfig(ice_config_);
495   }
496 }
497 
SetIceRole_n(IceRole ice_role)498 void TransportController::SetIceRole_n(IceRole ice_role) {
499   RTC_DCHECK(network_thread_->IsCurrent());
500 
501   ice_role_ = ice_role;
502   for (auto& channel : channels_) {
503     channel->dtls()->SetIceRole(ice_role_);
504   }
505 }
506 
GetSslRole_n(const std::string & transport_name,rtc::SSLRole * role) const507 bool TransportController::GetSslRole_n(const std::string& transport_name,
508                                        rtc::SSLRole* role) const {
509   RTC_DCHECK(network_thread_->IsCurrent());
510 
511   const JsepTransport* t = GetJsepTransport(transport_name);
512   if (!t) {
513     return false;
514   }
515   t->GetSslRole(role);
516   return true;
517 }
518 
SetLocalCertificate_n(const rtc::scoped_refptr<rtc::RTCCertificate> & certificate)519 bool TransportController::SetLocalCertificate_n(
520     const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
521   RTC_DCHECK(network_thread_->IsCurrent());
522 
523   // Can't change a certificate, or set a null certificate.
524   if (certificate_ || !certificate) {
525     return false;
526   }
527   certificate_ = certificate;
528 
529   // Set certificate for JsepTransport, which verifies it matches the
530   // fingerprint in SDP, and only applies it to the DTLS transport if a
531   // fingerprint attribute is present in SDP. This is used for fallback from
532   // DTLS to SDES.
533   for (auto& kv : transports_) {
534     kv.second->SetLocalCertificate(certificate_);
535   }
536   return true;
537 }
538 
GetLocalCertificate_n(const std::string & transport_name,rtc::scoped_refptr<rtc::RTCCertificate> * certificate) const539 bool TransportController::GetLocalCertificate_n(
540     const std::string& transport_name,
541     rtc::scoped_refptr<rtc::RTCCertificate>* certificate) const {
542   RTC_DCHECK(network_thread_->IsCurrent());
543 
544   const JsepTransport* t = GetJsepTransport(transport_name);
545   if (!t) {
546     return false;
547   }
548   return t->GetLocalCertificate(certificate);
549 }
550 
551 std::unique_ptr<rtc::SSLCertificate>
GetRemoteSSLCertificate_n(const std::string & transport_name) const552 TransportController::GetRemoteSSLCertificate_n(
553     const std::string& transport_name) const {
554   RTC_DCHECK(network_thread_->IsCurrent());
555 
556   // Get the certificate from the RTP channel's DTLS handshake. Should be
557   // identical to the RTCP channel's, since they were given the same remote
558   // fingerprint.
559   const RefCountedChannel* ch = GetChannel_n(transport_name, 1);
560   if (!ch) {
561     return nullptr;
562   }
563   return ch->dtls()->GetRemoteSSLCertificate();
564 }
565 
SetLocalTransportDescription_n(const std::string & transport_name,const TransportDescription & tdesc,ContentAction action,std::string * err)566 bool TransportController::SetLocalTransportDescription_n(
567     const std::string& transport_name,
568     const TransportDescription& tdesc,
569     ContentAction action,
570     std::string* err) {
571   RTC_DCHECK(network_thread_->IsCurrent());
572 
573   JsepTransport* transport = GetJsepTransport(transport_name);
574   if (!transport) {
575     // If we didn't find a transport, that's not an error;
576     // it could have been deleted as a result of bundling.
577     // TODO(deadbeef): Make callers smarter so they won't attempt to set a
578     // description on a deleted transport.
579     return true;
580   }
581 
582   // Older versions of Chrome expect the ICE role to be re-determined when an
583   // ICE restart occurs, and also don't perform conflict resolution correctly,
584   // so for now we can't safely stop doing this, unless the application opts in
585   // by setting |redetermine_role_on_ice_restart_| to false.
586   // See: https://bugs.chromium.org/p/chromium/issues/detail?id=628676
587   // TODO(deadbeef): Remove this when these old versions of Chrome reach a low
588   // enough population.
589   if (redetermine_role_on_ice_restart_ && transport->local_description() &&
590       IceCredentialsChanged(transport->local_description()->ice_ufrag,
591                             transport->local_description()->ice_pwd,
592                             tdesc.ice_ufrag, tdesc.ice_pwd)) {
593     IceRole new_ice_role =
594         (action == CA_OFFER) ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED;
595     SetIceRole(new_ice_role);
596   }
597 
598   LOG(LS_INFO) << "Set local transport description on " << transport_name;
599   return transport->SetLocalTransportDescription(tdesc, action, err);
600 }
601 
SetRemoteTransportDescription_n(const std::string & transport_name,const TransportDescription & tdesc,ContentAction action,std::string * err)602 bool TransportController::SetRemoteTransportDescription_n(
603     const std::string& transport_name,
604     const TransportDescription& tdesc,
605     ContentAction action,
606     std::string* err) {
607   RTC_DCHECK(network_thread_->IsCurrent());
608 
609   // If our role is ICEROLE_CONTROLLED and the remote endpoint supports only
610   // ice_lite, this local endpoint should take the CONTROLLING role.
611   // TODO(deadbeef): This is a session-level attribute, so it really shouldn't
612   // be in a TransportDescription in the first place...
613   if (ice_role_ == ICEROLE_CONTROLLED && tdesc.ice_mode == ICEMODE_LITE) {
614     SetIceRole_n(ICEROLE_CONTROLLING);
615   }
616 
617   JsepTransport* transport = GetJsepTransport(transport_name);
618   if (!transport) {
619     // If we didn't find a transport, that's not an error;
620     // it could have been deleted as a result of bundling.
621     // TODO(deadbeef): Make callers smarter so they won't attempt to set a
622     // description on a deleted transport.
623     return true;
624   }
625 
626   LOG(LS_INFO) << "Set remote transport description on " << transport_name;
627   return transport->SetRemoteTransportDescription(tdesc, action, err);
628 }
629 
MaybeStartGathering_n()630 void TransportController::MaybeStartGathering_n() {
631   for (auto& channel : channels_) {
632     channel->dtls()->MaybeStartGathering();
633   }
634 }
635 
AddRemoteCandidates_n(const std::string & transport_name,const Candidates & candidates,std::string * err)636 bool TransportController::AddRemoteCandidates_n(
637     const std::string& transport_name,
638     const Candidates& candidates,
639     std::string* err) {
640   RTC_DCHECK(network_thread_->IsCurrent());
641 
642   // Verify each candidate before passing down to the transport layer.
643   if (!VerifyCandidates(candidates, err)) {
644     return false;
645   }
646 
647   JsepTransport* transport = GetJsepTransport(transport_name);
648   if (!transport) {
649     // If we didn't find a transport, that's not an error;
650     // it could have been deleted as a result of bundling.
651     return true;
652   }
653 
654   for (const Candidate& candidate : candidates) {
655     RefCountedChannel* channel =
656         GetChannel_n(transport_name, candidate.component());
657     if (!channel) {
658       *err = "Candidate has an unknown component: " + candidate.ToString() +
659              " for content: " + transport_name;
660       return false;
661     }
662     channel->dtls()->AddRemoteCandidate(candidate);
663   }
664   return true;
665 }
666 
RemoveRemoteCandidates_n(const Candidates & candidates,std::string * err)667 bool TransportController::RemoveRemoteCandidates_n(const Candidates& candidates,
668                                                    std::string* err) {
669   RTC_DCHECK(network_thread_->IsCurrent());
670 
671   // Verify each candidate before passing down to the transport layer.
672   if (!VerifyCandidates(candidates, err)) {
673     return false;
674   }
675 
676   std::map<std::string, Candidates> candidates_by_transport_name;
677   for (const Candidate& cand : candidates) {
678     RTC_DCHECK(!cand.transport_name().empty());
679     candidates_by_transport_name[cand.transport_name()].push_back(cand);
680   }
681 
682   bool result = true;
683   for (const auto& kv : candidates_by_transport_name) {
684     const std::string& transport_name = kv.first;
685     const Candidates& candidates = kv.second;
686     JsepTransport* transport = GetJsepTransport(transport_name);
687     if (!transport) {
688       // If we didn't find a transport, that's not an error;
689       // it could have been deleted as a result of bundling.
690       continue;
691     }
692     for (const Candidate& candidate : candidates) {
693       RefCountedChannel* channel =
694           GetChannel_n(transport_name, candidate.component());
695       if (channel) {
696         channel->dtls()->RemoveRemoteCandidate(candidate);
697       }
698     }
699   }
700   return result;
701 }
702 
ReadyForRemoteCandidates_n(const std::string & transport_name) const703 bool TransportController::ReadyForRemoteCandidates_n(
704     const std::string& transport_name) const {
705   RTC_DCHECK(network_thread_->IsCurrent());
706 
707   const JsepTransport* transport = GetJsepTransport(transport_name);
708   if (!transport) {
709     return false;
710   }
711   return transport->ready_for_remote_candidates();
712 }
713 
GetStats_n(const std::string & transport_name,TransportStats * stats)714 bool TransportController::GetStats_n(const std::string& transport_name,
715                                      TransportStats* stats) {
716   RTC_DCHECK(network_thread_->IsCurrent());
717 
718   JsepTransport* transport = GetJsepTransport(transport_name);
719   if (!transport) {
720     return false;
721   }
722   return transport->GetStats(stats);
723 }
724 
SetMetricsObserver_n(webrtc::MetricsObserverInterface * metrics_observer)725 void TransportController::SetMetricsObserver_n(
726     webrtc::MetricsObserverInterface* metrics_observer) {
727   RTC_DCHECK(network_thread_->IsCurrent());
728   metrics_observer_ = metrics_observer;
729   for (auto& channel : channels_) {
730     channel->dtls()->SetMetricsObserver(metrics_observer);
731   }
732 }
733 
OnChannelWritableState_n(rtc::PacketTransportInterface * transport)734 void TransportController::OnChannelWritableState_n(
735     rtc::PacketTransportInterface* transport) {
736   RTC_DCHECK(network_thread_->IsCurrent());
737   LOG(LS_INFO) << " TransportChannel " << transport->debug_name()
738                << " writability changed to " << transport->writable() << ".";
739   UpdateAggregateStates_n();
740 }
741 
OnChannelReceivingState_n(rtc::PacketTransportInterface * transport)742 void TransportController::OnChannelReceivingState_n(
743     rtc::PacketTransportInterface* transport) {
744   RTC_DCHECK(network_thread_->IsCurrent());
745   UpdateAggregateStates_n();
746 }
747 
OnChannelGatheringState_n(TransportChannelImpl * channel)748 void TransportController::OnChannelGatheringState_n(
749     TransportChannelImpl* channel) {
750   RTC_DCHECK(network_thread_->IsCurrent());
751   UpdateAggregateStates_n();
752 }
753 
OnChannelCandidateGathered_n(TransportChannelImpl * channel,const Candidate & candidate)754 void TransportController::OnChannelCandidateGathered_n(
755     TransportChannelImpl* channel,
756     const Candidate& candidate) {
757   RTC_DCHECK(network_thread_->IsCurrent());
758 
759   // We should never signal peer-reflexive candidates.
760   if (candidate.type() == PRFLX_PORT_TYPE) {
761     RTC_NOTREACHED();
762     return;
763   }
764   std::vector<Candidate> candidates;
765   candidates.push_back(candidate);
766   CandidatesData* data =
767       new CandidatesData(channel->transport_name(), candidates);
768   signaling_thread_->Post(RTC_FROM_HERE, this, MSG_CANDIDATESGATHERED, data);
769 }
770 
OnChannelCandidatesRemoved_n(TransportChannelImpl * channel,const Candidates & candidates)771 void TransportController::OnChannelCandidatesRemoved_n(
772     TransportChannelImpl* channel,
773     const Candidates& candidates) {
774   invoker_.AsyncInvoke<void>(
775       RTC_FROM_HERE, signaling_thread_,
776       rtc::Bind(&TransportController::OnChannelCandidatesRemoved, this,
777                 candidates));
778 }
779 
OnChannelCandidatesRemoved(const Candidates & candidates)780 void TransportController::OnChannelCandidatesRemoved(
781     const Candidates& candidates) {
782   RTC_DCHECK(signaling_thread_->IsCurrent());
783   SignalCandidatesRemoved(candidates);
784 }
785 
OnChannelRoleConflict_n(TransportChannelImpl * channel)786 void TransportController::OnChannelRoleConflict_n(
787     TransportChannelImpl* channel) {
788   RTC_DCHECK(network_thread_->IsCurrent());
789   // Note: since the role conflict is handled entirely on the network thread,
790   // we don't need to worry about role conflicts occurring on two ports at once.
791   // The first one encountered should immediately reverse the role.
792   IceRole reversed_role = (ice_role_ == ICEROLE_CONTROLLING)
793                               ? ICEROLE_CONTROLLED
794                               : ICEROLE_CONTROLLING;
795   LOG(LS_INFO) << "Got role conflict; switching to "
796                << (reversed_role == ICEROLE_CONTROLLING ? "controlling"
797                                                         : "controlled")
798                << " role.";
799   SetIceRole_n(reversed_role);
800 }
801 
OnChannelStateChanged_n(TransportChannelImpl * channel)802 void TransportController::OnChannelStateChanged_n(
803     TransportChannelImpl* channel) {
804   RTC_DCHECK(network_thread_->IsCurrent());
805   LOG(LS_INFO) << channel->transport_name() << " TransportChannel "
806                << channel->component()
807                << " state changed. Check if state is complete.";
808   UpdateAggregateStates_n();
809 }
810 
UpdateAggregateStates_n()811 void TransportController::UpdateAggregateStates_n() {
812   RTC_DCHECK(network_thread_->IsCurrent());
813 
814   IceConnectionState new_connection_state = kIceConnectionConnecting;
815   IceGatheringState new_gathering_state = kIceGatheringNew;
816   bool any_receiving = false;
817   bool any_failed = false;
818   bool all_connected = !channels_.empty();
819   bool all_completed = !channels_.empty();
820   bool any_gathering = false;
821   bool all_done_gathering = !channels_.empty();
822   for (const auto& channel : channels_) {
823     any_receiving = any_receiving || channel->dtls()->receiving();
824     any_failed = any_failed ||
825                  channel->dtls()->GetState() == IceTransportState::STATE_FAILED;
826     all_connected = all_connected && channel->dtls()->writable();
827     all_completed =
828         all_completed && channel->dtls()->writable() &&
829         channel->dtls()->GetState() == IceTransportState::STATE_COMPLETED &&
830         channel->dtls()->GetIceRole() == ICEROLE_CONTROLLING &&
831         channel->dtls()->gathering_state() == kIceGatheringComplete;
832     any_gathering =
833         any_gathering || channel->dtls()->gathering_state() != kIceGatheringNew;
834     all_done_gathering =
835         all_done_gathering &&
836         channel->dtls()->gathering_state() == kIceGatheringComplete;
837   }
838 
839   if (any_failed) {
840     new_connection_state = kIceConnectionFailed;
841   } else if (all_completed) {
842     new_connection_state = kIceConnectionCompleted;
843   } else if (all_connected) {
844     new_connection_state = kIceConnectionConnected;
845   }
846   if (connection_state_ != new_connection_state) {
847     connection_state_ = new_connection_state;
848     signaling_thread_->Post(
849         RTC_FROM_HERE, this, MSG_ICECONNECTIONSTATE,
850         new rtc::TypedMessageData<IceConnectionState>(new_connection_state));
851   }
852 
853   if (receiving_ != any_receiving) {
854     receiving_ = any_receiving;
855     signaling_thread_->Post(RTC_FROM_HERE, this, MSG_RECEIVING,
856                             new rtc::TypedMessageData<bool>(any_receiving));
857   }
858 
859   if (all_done_gathering) {
860     new_gathering_state = kIceGatheringComplete;
861   } else if (any_gathering) {
862     new_gathering_state = kIceGatheringGathering;
863   }
864   if (gathering_state_ != new_gathering_state) {
865     gathering_state_ = new_gathering_state;
866     signaling_thread_->Post(
867         RTC_FROM_HERE, this, MSG_ICEGATHERINGSTATE,
868         new rtc::TypedMessageData<IceGatheringState>(new_gathering_state));
869   }
870 }
871 
OnDtlsHandshakeError(rtc::SSLHandshakeError error)872 void TransportController::OnDtlsHandshakeError(rtc::SSLHandshakeError error) {
873   SignalDtlsHandshakeError(error);
874 }
875 
876 }  // namespace cricket
877