blob: 573d571102f06d2cf331deefaf9cfe17c905e406 [file] [log] [blame]
deadbeefcbecd352015-09-23 11:50:27 -07001/*
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>
jbauch555604a2016-04-26 03:13:22 -070015#include <memory>
deadbeefcbecd352015-09-23 11:50:27 -070016#include <string>
17#include <vector>
18
Honghai Zhangcc411c02016-03-29 17:27:21 -070019#include "webrtc/p2p/base/candidatepairinterface.h"
deadbeefcbecd352015-09-23 11:50:27 -070020#include "webrtc/p2p/base/transport.h"
21#include "webrtc/p2p/base/transportchannel.h"
22#include "webrtc/p2p/base/transportcontroller.h"
23#include "webrtc/p2p/base/transportchannelimpl.h"
24#include "webrtc/base/bind.h"
25#include "webrtc/base/buffer.h"
26#include "webrtc/base/fakesslidentity.h"
27#include "webrtc/base/messagequeue.h"
28#include "webrtc/base/sigslot.h"
29#include "webrtc/base/sslfingerprint.h"
30#include "webrtc/base/thread.h"
31
zhihuang9763d562016-08-05 11:14:50 -070032#ifdef HAVE_QUIC
33#include "webrtc/p2p/quic/quictransport.h"
34#endif
35
deadbeefcbecd352015-09-23 11:50:27 -070036namespace cricket {
37
38class FakeTransport;
39
stefanc1aeaf02015-10-15 07:26:07 -070040namespace {
deadbeefcbecd352015-09-23 11:50:27 -070041struct PacketMessageData : public rtc::MessageData {
42 PacketMessageData(const char* data, size_t len) : packet(data, len) {}
43 rtc::Buffer packet;
44};
stefanc1aeaf02015-10-15 07:26:07 -070045} // namespace
deadbeefcbecd352015-09-23 11:50:27 -070046
47// Fake transport channel class, which can be passed to anything that needs a
48// transport channel. Can be informed of another FakeTransportChannel via
49// SetDestination.
50// TODO(hbos): Move implementation to .cc file, this and other classes in file.
51class FakeTransportChannel : public TransportChannelImpl,
52 public rtc::MessageHandler {
53 public:
mikescarlettb9dd7c52016-02-19 20:43:45 -080054 explicit FakeTransportChannel(const std::string& name, int component)
deadbeefcbecd352015-09-23 11:50:27 -070055 : TransportChannelImpl(name, component),
deadbeefcbecd352015-09-23 11:50:27 -070056 dtls_fingerprint_("", nullptr, 0) {}
57 ~FakeTransportChannel() { Reset(); }
58
Peter Boström0c4e06b2015-10-07 12:23:21 +020059 uint64_t IceTiebreaker() const { return tiebreaker_; }
deadbeefcbecd352015-09-23 11:50:27 -070060 IceMode remote_ice_mode() const { return remote_ice_mode_; }
61 const std::string& ice_ufrag() const { return ice_ufrag_; }
62 const std::string& ice_pwd() const { return ice_pwd_; }
63 const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; }
64 const std::string& remote_ice_pwd() const { return remote_ice_pwd_; }
65 const rtc::SSLFingerprint& dtls_fingerprint() const {
66 return dtls_fingerprint_;
67 }
68
69 // If async, will send packets by "Post"-ing to message queue instead of
70 // synchronously "Send"-ing.
71 void SetAsync(bool async) { async_ = async; }
deadbeef89824f62016-09-30 11:55:43 -070072 void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; }
deadbeefcbecd352015-09-23 11:50:27 -070073
deadbeefcbecd352015-09-23 11:50:27 -070074 TransportChannelState GetState() const override {
75 if (connection_count_ == 0) {
76 return had_connection_ ? TransportChannelState::STATE_FAILED
77 : TransportChannelState::STATE_INIT;
78 }
79
80 if (connection_count_ == 1) {
81 return TransportChannelState::STATE_COMPLETED;
82 }
83
84 return TransportChannelState::STATE_CONNECTING;
85 }
86
87 void SetIceRole(IceRole role) override { role_ = role; }
88 IceRole GetIceRole() const override { return role_; }
Peter Boström0c4e06b2015-10-07 12:23:21 +020089 void SetIceTiebreaker(uint64_t tiebreaker) override {
deadbeefcbecd352015-09-23 11:50:27 -070090 tiebreaker_ = tiebreaker;
91 }
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070092 void SetIceParameters(const IceParameters& ice_params) override {
93 ice_ufrag_ = ice_params.ufrag;
94 ice_pwd_ = ice_params.pwd;
deadbeefcbecd352015-09-23 11:50:27 -070095 }
Honghai Zhang4cedf2b2016-08-31 08:18:11 -070096 void SetRemoteIceParameters(const IceParameters& params) override {
97 remote_ice_ufrag_ = params.ufrag;
98 remote_ice_pwd_ = params.pwd;
deadbeefcbecd352015-09-23 11:50:27 -070099 }
100
101 void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; }
102 bool SetRemoteFingerprint(const std::string& alg,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200103 const uint8_t* digest,
deadbeefcbecd352015-09-23 11:50:27 -0700104 size_t digest_len) override {
105 dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
106 return true;
107 }
108 bool SetSslRole(rtc::SSLRole role) override {
109 ssl_role_ = role;
110 return true;
111 }
112 bool GetSslRole(rtc::SSLRole* role) const override {
113 *role = ssl_role_;
114 return true;
115 }
116
deadbeefcbecd352015-09-23 11:50:27 -0700117 void MaybeStartGathering() override {
118 if (gathering_state_ == kIceGatheringNew) {
119 gathering_state_ = kIceGatheringGathering;
120 SignalGatheringState(this);
121 }
122 }
123
124 IceGatheringState gathering_state() const override {
125 return gathering_state_;
126 }
127
128 void Reset() {
129 if (state_ != STATE_INIT) {
130 state_ = STATE_INIT;
131 if (dest_) {
132 dest_->state_ = STATE_INIT;
133 dest_->dest_ = nullptr;
134 dest_ = nullptr;
135 }
136 }
137 }
138
139 void SetWritable(bool writable) { set_writable(writable); }
140
deadbeefe84cd2e2016-05-04 17:16:34 -0700141 // Simulates the two transport channels connecting to each other.
142 // If |asymmetric| is true this method only affects this FakeTransportChannel.
143 // If false, it affects |dest| as well.
144 void SetDestination(FakeTransportChannel* dest, bool asymmetric = false) {
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700145 if (state_ == STATE_INIT && dest) {
deadbeefcbecd352015-09-23 11:50:27 -0700146 // This simulates the delivery of candidates.
147 dest_ = dest;
deadbeefcbecd352015-09-23 11:50:27 -0700148 if (local_cert_ && dest_->local_cert_) {
149 do_dtls_ = true;
deadbeefcbecd352015-09-23 11:50:27 -0700150 NegotiateSrtpCiphers();
151 }
152 state_ = STATE_CONNECTED;
deadbeefcbecd352015-09-23 11:50:27 -0700153 set_writable(true);
deadbeefe84cd2e2016-05-04 17:16:34 -0700154 if (!asymmetric) {
155 dest->SetDestination(this, true);
156 }
deadbeefcbecd352015-09-23 11:50:27 -0700157 } else if (state_ == STATE_CONNECTED && !dest) {
158 // Simulates loss of connectivity, by asymmetrically forgetting dest_.
159 dest_ = nullptr;
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700160 state_ = STATE_INIT;
deadbeefcbecd352015-09-23 11:50:27 -0700161 set_writable(false);
162 }
163 }
164
165 void SetConnectionCount(size_t connection_count) {
166 size_t old_connection_count = connection_count_;
167 connection_count_ = connection_count;
168 if (connection_count)
169 had_connection_ = true;
Honghai Zhang1590c392016-05-24 13:15:02 -0700170 // In this fake transport channel, |connection_count_| determines the
171 // transport channel state.
deadbeefcbecd352015-09-23 11:50:27 -0700172 if (connection_count_ < old_connection_count)
Honghai Zhang1590c392016-05-24 13:15:02 -0700173 SignalStateChanged(this);
deadbeefcbecd352015-09-23 11:50:27 -0700174 }
175
176 void SetCandidatesGatheringComplete() {
177 if (gathering_state_ != kIceGatheringComplete) {
178 gathering_state_ = kIceGatheringComplete;
179 SignalGatheringState(this);
180 }
181 }
182
183 void SetReceiving(bool receiving) { set_receiving(receiving); }
184
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700185 void SetIceConfig(const IceConfig& config) override { ice_config_ = config; }
deadbeefcbecd352015-09-23 11:50:27 -0700186
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700187 int receiving_timeout() const { return ice_config_.receiving_timeout; }
188 bool gather_continually() const { return ice_config_.gather_continually(); }
deadbeefcbecd352015-09-23 11:50:27 -0700189
190 int SendPacket(const char* data,
191 size_t len,
192 const rtc::PacketOptions& options,
193 int flags) override {
194 if (state_ != STATE_CONNECTED) {
195 return -1;
196 }
197
198 if (flags != PF_SRTP_BYPASS && flags != 0) {
199 return -1;
200 }
201
202 PacketMessageData* packet = new PacketMessageData(data, len);
203 if (async_) {
deadbeef89824f62016-09-30 11:55:43 -0700204 if (async_delay_ms_) {
205 rtc::Thread::Current()->PostDelayed(RTC_FROM_HERE, async_delay_ms_,
206 this, 0, packet);
207 } else {
208 rtc::Thread::Current()->Post(RTC_FROM_HERE, this, 0, packet);
209 }
deadbeefcbecd352015-09-23 11:50:27 -0700210 } else {
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700211 rtc::Thread::Current()->Send(RTC_FROM_HERE, this, 0, packet);
deadbeefcbecd352015-09-23 11:50:27 -0700212 }
nisse1bffc1d2016-05-02 08:18:55 -0700213 rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis());
stefanc1aeaf02015-10-15 07:26:07 -0700214 SignalSentPacket(this, sent_packet);
deadbeefcbecd352015-09-23 11:50:27 -0700215 return static_cast<int>(len);
216 }
217 int SetOption(rtc::Socket::Option opt, int value) override { return true; }
218 bool GetOption(rtc::Socket::Option opt, int* value) override { return true; }
219 int GetError() override { return 0; }
220
221 void AddRemoteCandidate(const Candidate& candidate) override {
222 remote_candidates_.push_back(candidate);
223 }
Honghai Zhang7fb69db2016-03-14 11:59:18 -0700224
225 void RemoveRemoteCandidate(const Candidate& candidate) override {}
226
deadbeefcbecd352015-09-23 11:50:27 -0700227 const Candidates& remote_candidates() const { return remote_candidates_; }
228
229 void OnMessage(rtc::Message* msg) override {
230 PacketMessageData* data = static_cast<PacketMessageData*>(msg->pdata);
231 dest_->SignalReadPacket(dest_, data->packet.data<char>(),
232 data->packet.size(), rtc::CreatePacketTime(0), 0);
233 delete data;
234 }
235
236 bool SetLocalCertificate(
nisseef8b61e2016-04-29 06:09:15 -0700237 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
deadbeefcbecd352015-09-23 11:50:27 -0700238 local_cert_ = certificate;
239 return true;
240 }
241
242 void SetRemoteSSLCertificate(rtc::FakeSSLCertificate* cert) {
243 remote_cert_ = cert;
244 }
245
246 bool IsDtlsActive() const override { return do_dtls_; }
247
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800248 bool SetSrtpCryptoSuites(const std::vector<int>& ciphers) override {
deadbeefcbecd352015-09-23 11:50:27 -0700249 srtp_ciphers_ = ciphers;
250 return true;
251 }
252
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800253 bool GetSrtpCryptoSuite(int* crypto_suite) override {
254 if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) {
255 *crypto_suite = chosen_crypto_suite_;
deadbeefcbecd352015-09-23 11:50:27 -0700256 return true;
257 }
258 return false;
259 }
260
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800261 bool GetSslCipherSuite(int* cipher_suite) override { return false; }
deadbeefcbecd352015-09-23 11:50:27 -0700262
nisseef8b61e2016-04-29 06:09:15 -0700263 rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override {
deadbeefcbecd352015-09-23 11:50:27 -0700264 return local_cert_;
265 }
266
jbauch555604a2016-04-26 03:13:22 -0700267 std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
kwibergb4d01c42016-04-06 05:15:06 -0700268 const override {
jbauch555604a2016-04-26 03:13:22 -0700269 return remote_cert_ ? std::unique_ptr<rtc::SSLCertificate>(
kwibergb4d01c42016-04-06 05:15:06 -0700270 remote_cert_->GetReference())
271 : nullptr;
deadbeefcbecd352015-09-23 11:50:27 -0700272 }
273
274 bool ExportKeyingMaterial(const std::string& label,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200275 const uint8_t* context,
deadbeefcbecd352015-09-23 11:50:27 -0700276 size_t context_len,
277 bool use_context,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200278 uint8_t* result,
deadbeefcbecd352015-09-23 11:50:27 -0700279 size_t result_len) override {
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800280 if (chosen_crypto_suite_ != rtc::SRTP_INVALID_CRYPTO_SUITE) {
deadbeefcbecd352015-09-23 11:50:27 -0700281 memset(result, 0xff, result_len);
282 return true;
283 }
284
285 return false;
286 }
287
deadbeefcbecd352015-09-23 11:50:27 -0700288 bool GetStats(ConnectionInfos* infos) override {
289 ConnectionInfo info;
290 infos->clear();
291 infos->push_back(info);
292 return true;
293 }
294
295 void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) {
296 ssl_max_version_ = version;
297 }
298 rtc::SSLProtocolVersion ssl_max_protocol_version() const {
299 return ssl_max_version_;
300 }
301
Honghai Zhangd93f50c2016-10-05 11:47:22 -0700302 void SetMetricsObserver(webrtc::MetricsObserverInterface* observer) override {
303 }
304
deadbeefcbecd352015-09-23 11:50:27 -0700305 private:
deadbeefe84cd2e2016-05-04 17:16:34 -0700306 void NegotiateSrtpCiphers() {
307 for (std::vector<int>::const_iterator it1 = srtp_ciphers_.begin();
308 it1 != srtp_ciphers_.end(); ++it1) {
309 for (std::vector<int>::const_iterator it2 = dest_->srtp_ciphers_.begin();
310 it2 != dest_->srtp_ciphers_.end(); ++it2) {
311 if (*it1 == *it2) {
312 chosen_crypto_suite_ = *it1;
313 return;
314 }
315 }
316 }
317 }
318
Taylor Brandstetterb825aee2016-06-29 13:07:16 -0700319 enum State { STATE_INIT, STATE_CONNECTED };
deadbeefcbecd352015-09-23 11:50:27 -0700320 FakeTransportChannel* dest_ = nullptr;
321 State state_ = STATE_INIT;
322 bool async_ = false;
deadbeef89824f62016-09-30 11:55:43 -0700323 int async_delay_ms_ = 0;
deadbeefcbecd352015-09-23 11:50:27 -0700324 Candidates remote_candidates_;
325 rtc::scoped_refptr<rtc::RTCCertificate> local_cert_;
326 rtc::FakeSSLCertificate* remote_cert_ = nullptr;
327 bool do_dtls_ = false;
Guo-wei Shieh521ed7b2015-11-18 19:41:53 -0800328 std::vector<int> srtp_ciphers_;
329 int chosen_crypto_suite_ = rtc::SRTP_INVALID_CRYPTO_SUITE;
Honghai Zhang5622c5e2016-07-01 13:59:29 -0700330 IceConfig ice_config_;
deadbeefcbecd352015-09-23 11:50:27 -0700331 IceRole role_ = ICEROLE_UNKNOWN;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200332 uint64_t tiebreaker_ = 0;
deadbeefcbecd352015-09-23 11:50:27 -0700333 std::string ice_ufrag_;
334 std::string ice_pwd_;
335 std::string remote_ice_ufrag_;
336 std::string remote_ice_pwd_;
337 IceMode remote_ice_mode_ = ICEMODE_FULL;
Guo-wei Shieha7446d22016-01-11 15:27:03 -0800338 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
deadbeefcbecd352015-09-23 11:50:27 -0700339 rtc::SSLFingerprint dtls_fingerprint_;
340 rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT;
341 size_t connection_count_ = 0;
342 IceGatheringState gathering_state_ = kIceGatheringNew;
343 bool had_connection_ = false;
344};
345
346// Fake transport class, which can be passed to anything that needs a Transport.
347// Can be informed of another FakeTransport via SetDestination (low-tech way
348// of doing candidates)
349class FakeTransport : public Transport {
350 public:
351 typedef std::map<int, FakeTransportChannel*> ChannelMap;
352
353 explicit FakeTransport(const std::string& name) : Transport(name, nullptr) {}
354
355 // Note that we only have a constructor with the allocator parameter so it can
356 // be wrapped by a DtlsTransport.
357 FakeTransport(const std::string& name, PortAllocator* allocator)
358 : Transport(name, nullptr) {}
359
360 ~FakeTransport() { DestroyAllChannels(); }
361
362 const ChannelMap& channels() const { return channels_; }
363
364 // If async, will send packets by "Post"-ing to message queue instead of
365 // synchronously "Send"-ing.
366 void SetAsync(bool async) { async_ = async; }
deadbeef89824f62016-09-30 11:55:43 -0700367 void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; }
deadbeefe84cd2e2016-05-04 17:16:34 -0700368
369 // If |asymmetric| is true, only set the destination for this transport, and
370 // not |dest|.
371 void SetDestination(FakeTransport* dest, bool asymmetric = false) {
deadbeefcbecd352015-09-23 11:50:27 -0700372 dest_ = dest;
373 for (const auto& kv : channels_) {
374 kv.second->SetLocalCertificate(certificate_);
deadbeefe84cd2e2016-05-04 17:16:34 -0700375 SetChannelDestination(kv.first, kv.second, asymmetric);
deadbeefcbecd352015-09-23 11:50:27 -0700376 }
377 }
378
379 void SetWritable(bool writable) {
380 for (const auto& kv : channels_) {
381 kv.second->SetWritable(writable);
382 }
383 }
384
385 void SetLocalCertificate(
386 const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override {
387 certificate_ = certificate;
388 }
389 bool GetLocalCertificate(
390 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) override {
391 if (!certificate_)
392 return false;
393
394 *certificate = certificate_;
395 return true;
396 }
397
398 bool GetSslRole(rtc::SSLRole* role) const override {
399 if (channels_.empty()) {
400 return false;
401 }
402 return channels_.begin()->second->GetSslRole(role);
403 }
404
405 bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) override {
406 ssl_max_version_ = version;
407 for (const auto& kv : channels_) {
408 kv.second->set_ssl_max_protocol_version(ssl_max_version_);
409 }
410 return true;
411 }
412 rtc::SSLProtocolVersion ssl_max_protocol_version() const {
413 return ssl_max_version_;
414 }
415
416 using Transport::local_description;
417 using Transport::remote_description;
mikescarlette7748672016-04-29 20:20:54 -0700418 using Transport::VerifyCertificateFingerprint;
419 using Transport::NegotiateRole;
deadbeefcbecd352015-09-23 11:50:27 -0700420
421 protected:
422 TransportChannelImpl* CreateTransportChannel(int component) override {
423 if (channels_.find(component) != channels_.end()) {
424 return nullptr;
425 }
mikescarlettb9dd7c52016-02-19 20:43:45 -0800426 FakeTransportChannel* channel = new FakeTransportChannel(name(), component);
deadbeefcbecd352015-09-23 11:50:27 -0700427 channel->set_ssl_max_protocol_version(ssl_max_version_);
428 channel->SetAsync(async_);
deadbeef89824f62016-09-30 11:55:43 -0700429 channel->SetAsyncDelay(async_delay_ms_);
deadbeefe84cd2e2016-05-04 17:16:34 -0700430 SetChannelDestination(component, channel, false);
deadbeefcbecd352015-09-23 11:50:27 -0700431 channels_[component] = channel;
432 return channel;
433 }
434
435 void DestroyTransportChannel(TransportChannelImpl* channel) override {
436 channels_.erase(channel->component());
437 delete channel;
438 }
439
440 private:
441 FakeTransportChannel* GetFakeChannel(int component) {
442 auto it = channels_.find(component);
443 return (it != channels_.end()) ? it->second : nullptr;
444 }
445
deadbeefe84cd2e2016-05-04 17:16:34 -0700446 void SetChannelDestination(int component,
447 FakeTransportChannel* channel,
448 bool asymmetric) {
deadbeefcbecd352015-09-23 11:50:27 -0700449 FakeTransportChannel* dest_channel = nullptr;
450 if (dest_) {
451 dest_channel = dest_->GetFakeChannel(component);
deadbeefe84cd2e2016-05-04 17:16:34 -0700452 if (dest_channel && !asymmetric) {
deadbeefcbecd352015-09-23 11:50:27 -0700453 dest_channel->SetLocalCertificate(dest_->certificate_);
454 }
455 }
deadbeefe84cd2e2016-05-04 17:16:34 -0700456 channel->SetDestination(dest_channel, asymmetric);
deadbeefcbecd352015-09-23 11:50:27 -0700457 }
458
459 // Note, this is distinct from the Channel map owned by Transport.
460 // This map just tracks the FakeTransportChannels created by this class.
461 // It's mainly needed so that we can access a FakeTransportChannel directly,
462 // even if wrapped by a DtlsTransportChannelWrapper.
463 ChannelMap channels_;
464 FakeTransport* dest_ = nullptr;
465 bool async_ = false;
deadbeef89824f62016-09-30 11:55:43 -0700466 int async_delay_ms_ = 0;
deadbeefcbecd352015-09-23 11:50:27 -0700467 rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
Guo-wei Shieha7446d22016-01-11 15:27:03 -0800468 rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
deadbeefcbecd352015-09-23 11:50:27 -0700469};
470
zhihuang9763d562016-08-05 11:14:50 -0700471#ifdef HAVE_QUIC
472class FakeQuicTransport : public QuicTransport {
473 public:
474 FakeQuicTransport(const std::string& transport_name)
475 : QuicTransport(transport_name, nullptr, nullptr) {}
476
477 protected:
478 QuicTransportChannel* CreateTransportChannel(int component) override {
479 FakeTransportChannel* fake_ice_transport_channel =
480 new FakeTransportChannel(name(), component);
481 return new QuicTransportChannel(fake_ice_transport_channel);
482 }
483};
484#endif
485
Honghai Zhangcc411c02016-03-29 17:27:21 -0700486// Fake candidate pair class, which can be passed to BaseChannel for testing
487// purposes.
488class FakeCandidatePair : public CandidatePairInterface {
489 public:
490 FakeCandidatePair(const Candidate& local_candidate,
491 const Candidate& remote_candidate)
492 : local_candidate_(local_candidate),
493 remote_candidate_(remote_candidate) {}
494 const Candidate& local_candidate() const override { return local_candidate_; }
495 const Candidate& remote_candidate() const override {
496 return remote_candidate_;
497 }
498
499 private:
500 Candidate local_candidate_;
501 Candidate remote_candidate_;
502};
503
deadbeefcbecd352015-09-23 11:50:27 -0700504// Fake TransportController class, which can be passed into a BaseChannel object
505// for test purposes. Can be connected to other FakeTransportControllers via
506// Connect().
507//
508// This fake is unusual in that for the most part, it's implemented with the
509// real TransportController code, but with fake TransportChannels underneath.
510class FakeTransportController : public TransportController {
511 public:
512 FakeTransportController()
513 : TransportController(rtc::Thread::Current(),
514 rtc::Thread::Current(),
515 nullptr),
516 fail_create_channel_(false) {}
517
Taylor Brandstetterf0bb3602016-08-26 20:59:24 -0700518 explicit FakeTransportController(bool redetermine_role_on_ice_restart)
519 : TransportController(rtc::Thread::Current(),
520 rtc::Thread::Current(),
521 nullptr,
522 redetermine_role_on_ice_restart),
523 fail_create_channel_(false) {}
524
deadbeefcbecd352015-09-23 11:50:27 -0700525 explicit FakeTransportController(IceRole role)
526 : TransportController(rtc::Thread::Current(),
527 rtc::Thread::Current(),
528 nullptr),
529 fail_create_channel_(false) {
530 SetIceRole(role);
531 }
532
533 explicit FakeTransportController(rtc::Thread* worker_thread)
534 : TransportController(rtc::Thread::Current(), worker_thread, nullptr),
535 fail_create_channel_(false) {}
536
537 FakeTransportController(rtc::Thread* worker_thread, IceRole role)
538 : TransportController(rtc::Thread::Current(), worker_thread, nullptr),
539 fail_create_channel_(false) {
540 SetIceRole(role);
541 }
542
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200543 FakeTransport* GetTransport_n(const std::string& transport_name) {
deadbeefcbecd352015-09-23 11:50:27 -0700544 return static_cast<FakeTransport*>(
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200545 TransportController::GetTransport_n(transport_name));
deadbeefcbecd352015-09-23 11:50:27 -0700546 }
547
548 void Connect(FakeTransportController* dest) {
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200549 network_thread()->Invoke<void>(
Taylor Brandstetter5d97a9a2016-06-10 14:17:27 -0700550 RTC_FROM_HERE,
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200551 rtc::Bind(&FakeTransportController::Connect_n, this, dest));
deadbeefcbecd352015-09-23 11:50:27 -0700552 }
553
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200554 TransportChannel* CreateTransportChannel_n(const std::string& transport_name,
deadbeefcbecd352015-09-23 11:50:27 -0700555 int component) override {
556 if (fail_create_channel_) {
557 return nullptr;
558 }
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200559 return TransportController::CreateTransportChannel_n(transport_name,
deadbeefcbecd352015-09-23 11:50:27 -0700560 component);
561 }
562
Honghai Zhangcc411c02016-03-29 17:27:21 -0700563 FakeCandidatePair* CreateFakeCandidatePair(
564 const rtc::SocketAddress& local_address,
565 int16_t local_network_id,
566 const rtc::SocketAddress& remote_address,
567 int16_t remote_network_id) {
568 Candidate local_candidate(0, "udp", local_address, 0u, "", "", "local", 0,
569 "foundation", local_network_id, 0);
570 Candidate remote_candidate(0, "udp", remote_address, 0u, "", "", "local", 0,
571 "foundation", remote_network_id, 0);
572 return new FakeCandidatePair(local_candidate, remote_candidate);
573 }
574
deadbeefcbecd352015-09-23 11:50:27 -0700575 void set_fail_channel_creation(bool fail_channel_creation) {
576 fail_create_channel_ = fail_channel_creation;
577 }
578
579 protected:
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200580 Transport* CreateTransport_n(const std::string& transport_name) override {
zhihuang9763d562016-08-05 11:14:50 -0700581#ifdef HAVE_QUIC
582 if (quic()) {
583 return new FakeQuicTransport(transport_name);
584 }
585#endif
deadbeefcbecd352015-09-23 11:50:27 -0700586 return new FakeTransport(transport_name);
587 }
588
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200589 void Connect_n(FakeTransportController* dest) {
deadbeefcbecd352015-09-23 11:50:27 -0700590 // Simulate the exchange of candidates.
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200591 ConnectChannels_n();
592 dest->ConnectChannels_n();
deadbeefcbecd352015-09-23 11:50:27 -0700593 for (auto& kv : transports()) {
594 FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200595 transport->SetDestination(dest->GetTransport_n(kv.first));
deadbeefcbecd352015-09-23 11:50:27 -0700596 }
597 }
598
Danil Chapovalov7f216b72016-05-12 09:20:31 +0200599 void ConnectChannels_n() {
zhihuang3ba4d532016-04-11 15:10:52 -0700600 TransportDescription faketransport_desc(
601 std::vector<std::string>(),
602 rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH),
603 rtc::CreateRandomString(cricket::ICE_PWD_LENGTH), cricket::ICEMODE_FULL,
604 cricket::CONNECTIONROLE_NONE, nullptr);
deadbeefcbecd352015-09-23 11:50:27 -0700605 for (auto& kv : transports()) {
606 FakeTransport* transport = static_cast<FakeTransport*>(kv.second);
zhihuang3ba4d532016-04-11 15:10:52 -0700607 // Set local transport description for FakeTransport before connecting.
608 // Otherwise, the RTC_CHECK in Transport.ConnectChannel will fail.
609 if (!transport->local_description()) {
610 transport->SetLocalTransportDescription(faketransport_desc,
611 cricket::CA_OFFER, nullptr);
612 }
deadbeefcbecd352015-09-23 11:50:27 -0700613 transport->MaybeStartGathering();
614 }
615 }
616
617 private:
618 bool fail_create_channel_;
619};
620
621} // namespace cricket
622
623#endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_