• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2009 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 #ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
12 #define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
13 
14 #include <map>
15 #include <string>
16 #include <vector>
17 
18 #include "webrtc/p2p/base/transport.h"
19 #include "webrtc/p2p/base/transportchannel.h"
20 #include "webrtc/p2p/base/transportcontroller.h"
21 #include "webrtc/p2p/base/transportchannelimpl.h"
22 #include "webrtc/base/bind.h"
23 #include "webrtc/base/buffer.h"
24 #include "webrtc/base/fakesslidentity.h"
25 #include "webrtc/base/messagequeue.h"
26 #include "webrtc/base/sigslot.h"
27 #include "webrtc/base/sslfingerprint.h"
28 #include "webrtc/base/thread.h"
29 
30 namespace cricket {
31 
32 class FakeTransport;
33 
34 namespace {
35 struct PacketMessageData : public rtc::MessageData {
PacketMessageDataPacketMessageData36   PacketMessageData(const char* data, size_t len) : packet(data, len) {}
37   rtc::Buffer packet;
38 };
39 }  // namespace
40 
41 // Fake transport channel class, which can be passed to anything that needs a
42 // transport channel. Can be informed of another FakeTransportChannel via
43 // SetDestination.
44 // TODO(hbos): Move implementation to .cc file, this and other classes in file.
45 class FakeTransportChannel : public TransportChannelImpl,
46                              public rtc::MessageHandler {
47  public:
FakeTransportChannel(Transport * transport,const std::string & name,int component)48   explicit FakeTransportChannel(Transport* transport,
49                                 const std::string& name,
50                                 int component)
51       : TransportChannelImpl(name, component),
52         transport_(transport),
53         dtls_fingerprint_("", nullptr, 0) {}
~FakeTransportChannel()54   ~FakeTransportChannel() { Reset(); }
55 
IceTiebreaker()56   uint64_t IceTiebreaker() const { return tiebreaker_; }
remote_ice_mode()57   IceMode remote_ice_mode() const { return remote_ice_mode_; }
ice_ufrag()58   const std::string& ice_ufrag() const { return ice_ufrag_; }
ice_pwd()59   const std::string& ice_pwd() const { return ice_pwd_; }
remote_ice_ufrag()60   const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; }
remote_ice_pwd()61   const std::string& remote_ice_pwd() const { return remote_ice_pwd_; }
dtls_fingerprint()62   const rtc::SSLFingerprint& dtls_fingerprint() const {
63     return dtls_fingerprint_;
64   }
65 
66   // If async, will send packets by "Post"-ing to message queue instead of
67   // synchronously "Send"-ing.
SetAsync(bool async)68   void SetAsync(bool async) { async_ = async; }
69 
GetTransport()70   Transport* GetTransport() override { return transport_; }
71 
GetState()72   TransportChannelState GetState() const override {
73     if (connection_count_ == 0) {
74       return had_connection_ ? TransportChannelState::STATE_FAILED
75                              : TransportChannelState::STATE_INIT;
76     }
77 
78     if (connection_count_ == 1) {
79       return TransportChannelState::STATE_COMPLETED;
80     }
81 
82     return TransportChannelState::STATE_CONNECTING;
83   }
84 
SetIceRole(IceRole role)85   void SetIceRole(IceRole role) override { role_ = role; }
GetIceRole()86   IceRole GetIceRole() const override { return role_; }
SetIceTiebreaker(uint64_t tiebreaker)87   void SetIceTiebreaker(uint64_t tiebreaker) override {
88     tiebreaker_ = tiebreaker;
89   }
SetIceCredentials(const std::string & ice_ufrag,const std::string & ice_pwd)90   void SetIceCredentials(const std::string& ice_ufrag,
91                          const std::string& ice_pwd) override {
92     ice_ufrag_ = ice_ufrag;
93     ice_pwd_ = ice_pwd;
94   }
SetRemoteIceCredentials(const std::string & ice_ufrag,const std::string & ice_pwd)95   void SetRemoteIceCredentials(const std::string& ice_ufrag,
96                                const std::string& ice_pwd) override {
97     remote_ice_ufrag_ = ice_ufrag;
98     remote_ice_pwd_ = ice_pwd;
99   }
100 
SetRemoteIceMode(IceMode mode)101   void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; }
SetRemoteFingerprint(const std::string & alg,const uint8_t * digest,size_t digest_len)102   bool SetRemoteFingerprint(const std::string& alg,
103                             const uint8_t* digest,
104                             size_t digest_len) override {
105     dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
106     return true;
107   }
SetSslRole(rtc::SSLRole role)108   bool SetSslRole(rtc::SSLRole role) override {
109     ssl_role_ = role;
110     return true;
111   }
GetSslRole(rtc::SSLRole * role)112   bool GetSslRole(rtc::SSLRole* role) const override {
113     *role = ssl_role_;
114     return true;
115   }
116 
Connect()117   void Connect() override {
118     if (state_ == STATE_INIT) {
119       state_ = STATE_CONNECTING;
120     }
121   }
122 
MaybeStartGathering()123   void MaybeStartGathering() override {
124     if (gathering_state_ == kIceGatheringNew) {
125       gathering_state_ = kIceGatheringGathering;
126       SignalGatheringState(this);
127     }
128   }
129 
gathering_state()130   IceGatheringState gathering_state() const override {
131     return gathering_state_;
132   }
133 
Reset()134   void Reset() {
135     if (state_ != STATE_INIT) {
136       state_ = STATE_INIT;
137       if (dest_) {
138         dest_->state_ = STATE_INIT;
139         dest_->dest_ = nullptr;
140         dest_ = nullptr;
141       }
142     }
143   }
144 
SetWritable(bool writable)145   void SetWritable(bool writable) { set_writable(writable); }
146 
SetDestination(FakeTransportChannel * dest)147   void SetDestination(FakeTransportChannel* dest) {
148     if (state_ == STATE_CONNECTING && dest) {
149       // This simulates the delivery of candidates.
150       dest_ = dest;
151       dest_->dest_ = this;
152       if (local_cert_ && dest_->local_cert_) {
153         do_dtls_ = true;
154         dest_->do_dtls_ = true;
155         NegotiateSrtpCiphers();
156       }
157       state_ = STATE_CONNECTED;
158       dest_->state_ = STATE_CONNECTED;
159       set_writable(true);
160       dest_->set_writable(true);
161     } else if (state_ == STATE_CONNECTED && !dest) {
162       // Simulates loss of connectivity, by asymmetrically forgetting dest_.
163       dest_ = nullptr;
164       state_ = STATE_CONNECTING;
165       set_writable(false);
166     }
167   }
168 
SetConnectionCount(size_t connection_count)169   void SetConnectionCount(size_t connection_count) {
170     size_t old_connection_count = connection_count_;
171     connection_count_ = connection_count;
172     if (connection_count)
173       had_connection_ = true;
174     if (connection_count_ < old_connection_count)
175       SignalConnectionRemoved(this);
176   }
177 
SetCandidatesGatheringComplete()178   void SetCandidatesGatheringComplete() {
179     if (gathering_state_ != kIceGatheringComplete) {
180       gathering_state_ = kIceGatheringComplete;
181       SignalGatheringState(this);
182     }
183   }
184 
SetReceiving(bool receiving)185   void SetReceiving(bool receiving) { set_receiving(receiving); }
186 
SetIceConfig(const IceConfig & config)187   void SetIceConfig(const IceConfig& config) override {
188     receiving_timeout_ = config.receiving_timeout_ms;
189     gather_continually_ = config.gather_continually;
190   }
191 
receiving_timeout()192   int receiving_timeout() const { return receiving_timeout_; }
gather_continually()193   bool gather_continually() const { return gather_continually_; }
194 
SendPacket(const char * data,size_t len,const rtc::PacketOptions & options,int flags)195   int SendPacket(const char* data,
196                  size_t len,
197                  const rtc::PacketOptions& options,
198                  int flags) override {
199     if (state_ != STATE_CONNECTED) {
200       return -1;
201     }
202 
203     if (flags != PF_SRTP_BYPASS && flags != 0) {
204       return -1;
205     }
206 
207     PacketMessageData* packet = new PacketMessageData(data, len);
208     if (async_) {
209       rtc::Thread::Current()->Post(this, 0, packet);
210     } else {
211       rtc::Thread::Current()->Send(this, 0, packet);
212     }
213     rtc::SentPacket sent_packet(options.packet_id, rtc::Time());
214     SignalSentPacket(this, sent_packet);
215     return static_cast<int>(len);
216   }
SetOption(rtc::Socket::Option opt,int value)217   int SetOption(rtc::Socket::Option opt, int value) override { return true; }
GetOption(rtc::Socket::Option opt,int * value)218   bool GetOption(rtc::Socket::Option opt, int* value) override { return true; }
GetError()219   int GetError() override { return 0; }
220 
AddRemoteCandidate(const Candidate & candidate)221   void AddRemoteCandidate(const Candidate& candidate) override {
222     remote_candidates_.push_back(candidate);
223   }
remote_candidates()224   const Candidates& remote_candidates() const { return remote_candidates_; }
225 
OnMessage(rtc::Message * msg)226   void OnMessage(rtc::Message* msg) override {
227     PacketMessageData* data = static_cast<PacketMessageData*>(msg->pdata);
228     dest_->SignalReadPacket(dest_, data->packet.data<char>(),
229                             data->packet.size(), rtc::CreatePacketTime(0), 0);
230     delete data;
231   }
232 
SetLocalCertificate(const rtc::scoped_refptr<rtc::RTCCertificate> & certificate)233   bool SetLocalCertificate(
234       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
235     local_cert_ = certificate;
236     return true;
237   }
238 
SetRemoteSSLCertificate(rtc::FakeSSLCertificate * cert)239   void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) {
240     remote_cert_ = cert;
241   }
242 
IsDtlsActive()243   bool IsDtlsActive() const override { return do_dtls_; }
244 
SetSrtpCryptoSuites(const std::vector<int> & ciphers)245   bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override {
246     srtp_ciphers_ = ciphers;
247     return true;
248   }
249 
GetSrtpCryptoSuite(int * crypto_suite)250   bool GetSrtpCryptoSuite(int* crypto_suite) override {
251     if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) {
252       *crypto_suite = chosen_crypto_suite_;
253       return true;
254     }
255     return false;
256   }
257 
GetSslCipherSuite(int * cipher_suite)258   bool GetSslCipherSuite(int* cipher_suite) override { return false; }
259 
GetLocalCertificate()260   rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const {
261     return local_cert_;
262   }
263 
GetRemoteSSLCertificate(rtc::SSLCertificate ** cert)264   bool GetRemoteSSLCertificate(rtc::SSLCertificate** cert) const override {
265     if (!remote_cert_)
266       return false;
267 
268     *cert = remote_cert_->GetReference();
269     return true;
270   }
271 
ExportKeyingMaterial(const std::string & label,const uint8_t * context,size_t context_len,bool use_context,uint8_t * result,size_t result_len)272   bool ExportKeyingMaterial(const std::string& label,
273                             const uint8_t* context,
274                             size_t context_len,
275                             bool use_context,
276                             uint8_t* result,
277                             size_t result_len) override {
278     if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) {
279       memset(result, 0xff, result_len);
280       return true;
281     }
282 
283     return false;
284   }
285 
NegotiateSrtpCiphers()286   void NegotiateSrtpCiphers() {
287     for (std::vector<int>::const_iterator it1 = srtp_ciphers_.begin();
288          it1 != srtp_ciphers_.end(); ++it1) {
289       for (std::vector<int>::const_iterator it2 = dest_->srtp_ciphers_.begin();
290            it2 != dest_->srtp_ciphers_.end(); ++it2) {
291         if (*it1 == *it2) {
292           chosen_crypto_suite_ = *it1;
293           dest_->chosen_crypto_suite_ = *it2;
294           return;
295         }
296       }
297     }
298   }
299 
GetStats(ConnectionInfos * infos)300   bool GetStats(ConnectionInfos* infos) override {
301     ConnectionInfo info;
302     infos->clear();
303     infos->push_back(info);
304     return true;
305   }
306 
set_ssl_max_protocol_version(rtc::SSLProtocolVersion version)307   void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) {
308     ssl_max_version_ = version;
309   }
ssl_max_protocol_version()310   rtc::SSLProtocolVersion ssl_max_protocol_version() const {
311     return ssl_max_version_;
312   }
313 
314  private:
315   enum State { STATE_INIT, STATE_CONNECTING, STATE_CONNECTED };
316   Transport* transport_;
317   FakeTransportChannel* dest_ = nullptr;
318   State state_ = STATE_INIT;
319   bool async_ = false;
320   Candidates remote_candidates_;
321   rtc::scoped_refptr<rtc::RTCCertificate> local_cert_;
322   rtc::FakeSSLCertificate* remote_cert_ = nullptr;
323   bool do_dtls_ = false;
324   std::vector<int> srtp_ciphers_;
325   int chosen_crypto_suite_ = rtc::SRTP_INVALID_CRYPTO_SUITE;
326   int receiving_timeout_ = -1;
327   bool gather_continually_ = false;
328   IceRole role_ = ICEROLE_UNKNOWN;
329   uint64_t tiebreaker_ = 0;
330   std::string ice_ufrag_;
331   std::string ice_pwd_;
332   std::string remote_ice_ufrag_;
333   std::string remote_ice_pwd_;
334   IceMode remote_ice_mode_ = ICEMODE_FULL;
335   rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
336   rtc::SSLFingerprint dtls_fingerprint_;
337   rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT;
338   size_t connection_count_ = 0;
339   IceGatheringState gathering_state_ = kIceGatheringNew;
340   bool had_connection_ = false;
341 };
342 
343 // Fake transport class, which can be passed to anything that needs a Transport.
344 // Can be informed of another FakeTransport via SetDestination (low-tech way
345 // of doing candidates)
346 class FakeTransport : public Transport {
347  public:
348   typedef std::map<int, FakeTransportChannel*> ChannelMap;
349 
FakeTransport(const std::string & name)350   explicit FakeTransport(const std::string& name) : Transport(name, nullptr) {}
351 
352   // Note that we only have a constructor with the allocator parameter so it can
353   // be wrapped by a DtlsTransport.
FakeTransport(const std::string & name,PortAllocator * allocator)354   FakeTransport(const std::string& name, PortAllocator* allocator)
355       : Transport(name, nullptr) {}
356 
~FakeTransport()357   ~FakeTransport() { DestroyAllChannels(); }
358 
channels()359   const ChannelMap& channels() const { return channels_; }
360 
361   // If async, will send packets by "Post"-ing to message queue instead of
362   // synchronously "Send"-ing.
SetAsync(bool async)363   void SetAsync(bool async) { async_ = async; }
SetDestination(FakeTransport * dest)364   void SetDestination(FakeTransport* dest) {
365     dest_ = dest;
366     for (const auto& kv : channels_) {
367       kv.second->SetLocalCertificate(certificate_);
368       SetChannelDestination(kv.first, kv.second);
369     }
370   }
371 
SetWritable(bool writable)372   void SetWritable(bool writable) {
373     for (const auto& kv : channels_) {
374       kv.second->SetWritable(writable);
375     }
376   }
377 
SetLocalCertificate(const rtc::scoped_refptr<rtc::RTCCertificate> & certificate)378   void SetLocalCertificate(
379       const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
380     certificate_ = certificate;
381   }
GetLocalCertificate(rtc::scoped_refptr<rtc::RTCCertificate> * certificate)382   bool GetLocalCertificate(
383       rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
384     if (!certificate_)
385       return false;
386 
387     *certificate = certificate_;
388     return true;
389   }
390 
GetSslRole(rtc::SSLRole * role)391   bool GetSslRole(rtc::SSLRole* role) const override {
392     if (channels_.empty()) {
393       return false;
394     }
395     return channels_.begin()->second->GetSslRole(role);
396   }
397 
SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version)398   bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override {
399     ssl_max_version_ = version;
400     for (const auto& kv : channels_) {
401       kv.second->set_ssl_max_protocol_version(ssl_max_version_);
402     }
403     return true;
404   }
ssl_max_protocol_version()405   rtc::SSLProtocolVersion ssl_max_protocol_version() const {
406     return ssl_max_version_;
407   }
408 
409   using Transport::local_description;
410   using Transport::remote_description;
411 
412  protected:
CreateTransportChannel(int component)413   TransportChannelImpl* CreateTransportChannel(int component) override {
414     if (channels_.find(component) != channels_.end()) {
415       return nullptr;
416     }
417     FakeTransportChannel* channel =
418         new FakeTransportChannel(this, name(), component);
419     channel->set_ssl_max_protocol_version(ssl_max_version_);
420     channel->SetAsync(async_);
421     SetChannelDestination(component, channel);
422     channels_[component] = channel;
423     return channel;
424   }
425 
DestroyTransportChannel(TransportChannelImpl * channel)426   void DestroyTransportChannel(TransportChannelImpl* channel) override {
427     channels_.erase(channel->component());
428     delete channel;
429   }
430 
431  private:
GetFakeChannel(int component)432   FakeTransportChannel* GetFakeChannel(int component) {
433     auto it = channels_.find(component);
434     return (it != channels_.end()) ? it->second : nullptr;
435   }
436 
SetChannelDestination(int component,FakeTransportChannel * channel)437   void SetChannelDestination(int component, FakeTransportChannel* channel) {
438     FakeTransportChannel* dest_channel = nullptr;
439     if (dest_) {
440       dest_channel = dest_->GetFakeChannel(component);
441       if (dest_channel) {
442         dest_channel->SetLocalCertificate(dest_->certificate_);
443       }
444     }
445     channel->SetDestination(dest_channel);
446   }
447 
448   // Note, this is distinct from the Channel map owned by Transport.
449   // This map just tracks the FakeTransportChannels created by this class.
450   // It's mainly needed so that we can access a FakeTransportChannel directly,
451   // even if wrapped by a DtlsTransportChannelWrapper.
452   ChannelMap channels_;
453   FakeTransport* dest_ = nullptr;
454   bool async_ = false;
455   rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
456   rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
457 };
458 
459 // Fake TransportController class, which can be passed into a BaseChannel object
460 // for test purposes. Can be connected to other FakeTransportControllers via
461 // Connect().
462 //
463 // This fake is unusual in that for the most part, it's implemented with the
464 // real TransportController code, but with fake TransportChannels underneath.
465 class FakeTransportController : public TransportController {
466  public:
FakeTransportController()467   FakeTransportController()
468       : TransportController(rtc::Thread::Current(),
469                             rtc::Thread::Current(),
470                             nullptr),
471         fail_create_channel_(false) {}
472 
FakeTransportController(IceRole role)473   explicit FakeTransportController(IceRole role)
474       : TransportController(rtc::Thread::Current(),
475                             rtc::Thread::Current(),
476                             nullptr),
477         fail_create_channel_(false) {
478     SetIceRole(role);
479   }
480 
FakeTransportController(rtc::Thread * worker_thread)481   explicit FakeTransportController(rtc::Thread* worker_thread)
482       : TransportController(rtc::Thread::Current(), worker_thread, nullptr),
483         fail_create_channel_(false) {}
484 
FakeTransportController(rtc::Thread * worker_thread,IceRole role)485   FakeTransportController(rtc::Thread* worker_thread, IceRole role)
486       : TransportController(rtc::Thread::Current(), worker_thread, nullptr),
487         fail_create_channel_(false) {
488     SetIceRole(role);
489   }
490 
GetTransport_w(const std::string & transport_name)491   FakeTransport* GetTransport_w(const std::string& transport_name) {
492     return static_cast<FakeTransport*>(
493         TransportController::GetTransport_w(transport_name));
494   }
495 
Connect(FakeTransportController * dest)496   void Connect(FakeTransportController* dest) {
497     worker_thread()->Invoke<void>(
498         rtc::Bind(&FakeTransportController::Connect_w, this, dest));
499   }
500 
CreateTransportChannel_w(const std::string & transport_name,int component)501   TransportChannel* CreateTransportChannel_w(const std::string& transport_name,
502                                              int component) override {
503     if (fail_create_channel_) {
504       return nullptr;
505     }
506     return TransportController::CreateTransportChannel_w(transport_name,
507                                                          component);
508   }
509 
set_fail_channel_creation(bool fail_channel_creation)510   void set_fail_channel_creation(bool fail_channel_creation) {
511     fail_create_channel_ = fail_channel_creation;
512   }
513 
514  protected:
CreateTransport_w(const std::string & transport_name)515   Transport* CreateTransport_w(const std::string& transport_name) override {
516     return new FakeTransport(transport_name);
517   }
518 
Connect_w(FakeTransportController * dest)519   void Connect_w(FakeTransportController* dest) {
520     // Simulate the exchange of candidates.
521     ConnectChannels_w();
522     dest->ConnectChannels_w();
523     for (auto& kv : transports()) {
524       FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
525       transport->SetDestination(dest->GetTransport_w(kv.first));
526     }
527   }
528 
ConnectChannels_w()529   void ConnectChannels_w() {
530     for (auto& kv : transports()) {
531       FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
532       transport->ConnectChannels();
533       transport->MaybeStartGathering();
534     }
535   }
536 
537  private:
538   bool fail_create_channel_;
539 };
540 
541 }  // namespace cricket
542 
543 #endif  // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
544