blob: 0c784754a6aea085c1ca5087505f3786613846fd [file] [log] [blame]
/*
* Copyright 2009 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
#define WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_
#include <memory>
#include <string>
#include <vector>
#include "webrtc/p2p/base/fakedtlstransport.h"
#include "webrtc/p2p/base/fakeicetransport.h"
#include "webrtc/p2p/base/transportcontroller.h"
#include "webrtc/rtc_base/bind.h"
#include "webrtc/rtc_base/sslfingerprint.h"
#include "webrtc/rtc_base/thread.h"
namespace cricket {
// Fake TransportController class, which can be passed into a WebRtcSession
// object for test purposes. Can be connected to other FakeTransportControllers
// via Connect().
//
// This fake is unusual in that for the most part, it's implemented with the
// real TransportController code, but with fake TransportChannels underneath.
class FakeTransportController : public TransportController {
public:
FakeTransportController()
: TransportController(rtc::Thread::Current(),
rtc::Thread::Current(),
nullptr,
/*redetermine_role_on_ice_restart=*/true,
rtc::CryptoOptions()) {}
explicit FakeTransportController(bool redetermine_role_on_ice_restart)
: TransportController(rtc::Thread::Current(),
rtc::Thread::Current(),
nullptr,
redetermine_role_on_ice_restart,
rtc::CryptoOptions()) {}
explicit FakeTransportController(IceRole role)
: TransportController(rtc::Thread::Current(),
rtc::Thread::Current(),
nullptr,
/*redetermine_role_on_ice_restart=*/true,
rtc::CryptoOptions()) {
SetIceRole(role);
}
explicit FakeTransportController(rtc::Thread* network_thread)
: TransportController(rtc::Thread::Current(),
network_thread,
nullptr,
/*redetermine_role_on_ice_restart=*/true,
rtc::CryptoOptions()) {}
FakeTransportController(rtc::Thread* network_thread, IceRole role)
: TransportController(rtc::Thread::Current(),
network_thread,
nullptr,
/*redetermine_role_on_ice_restart=*/true,
rtc::CryptoOptions()) {
SetIceRole(role);
}
FakeDtlsTransport* GetFakeDtlsTransport_n(const std::string& transport_name,
int component) {
return static_cast<FakeDtlsTransport*>(
get_channel_for_testing(transport_name, component));
}
// Simulate the exchange of transport descriptions, and the gathering and
// exchange of ICE candidates.
void Connect(FakeTransportController* dest) {
for (const std::string& transport_name : transport_names_for_testing()) {
std::unique_ptr<rtc::SSLFingerprint> local_fingerprint;
std::unique_ptr<rtc::SSLFingerprint> remote_fingerprint;
if (certificate_for_testing()) {
local_fingerprint.reset(rtc::SSLFingerprint::CreateFromCertificate(
certificate_for_testing()));
}
if (dest->certificate_for_testing()) {
remote_fingerprint.reset(rtc::SSLFingerprint::CreateFromCertificate(
dest->certificate_for_testing()));
}
TransportDescription local_desc(
std::vector<std::string>(),
rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH),
rtc::CreateRandomString(cricket::ICE_PWD_LENGTH),
cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE,
local_fingerprint.get());
TransportDescription remote_desc(
std::vector<std::string>(),
rtc::CreateRandomString(cricket::ICE_UFRAG_LENGTH),
rtc::CreateRandomString(cricket::ICE_PWD_LENGTH),
cricket::ICEMODE_FULL, cricket::CONNECTIONROLE_NONE,
remote_fingerprint.get());
std::string err;
SetLocalTransportDescription(transport_name, local_desc,
cricket::CA_OFFER, &err);
dest->SetRemoteTransportDescription(transport_name, local_desc,
cricket::CA_OFFER, &err);
dest->SetLocalTransportDescription(transport_name, remote_desc,
cricket::CA_ANSWER, &err);
SetRemoteTransportDescription(transport_name, remote_desc,
cricket::CA_ANSWER, &err);
}
MaybeStartGathering();
dest->MaybeStartGathering();
network_thread()->Invoke<void>(
RTC_FROM_HERE,
rtc::Bind(&FakeTransportController::SetChannelDestinations_n, this,
dest));
}
void DestroyRtcpTransport(const std::string& transport_name) {
DestroyDtlsTransport_n(transport_name,
cricket::ICE_CANDIDATE_COMPONENT_RTCP);
}
protected:
IceTransportInternal* CreateIceTransportChannel_n(
const std::string& transport_name,
int component) override {
return new FakeIceTransport(transport_name, component);
}
DtlsTransportInternal* CreateDtlsTransportChannel_n(
const std::string& transport_name,
int component,
IceTransportInternal* ice) override {
return new FakeDtlsTransport(static_cast<FakeIceTransport*>(ice));
}
private:
void SetChannelDestinations_n(FakeTransportController* dest) {
for (DtlsTransportInternal* tc : channels_for_testing()) {
FakeDtlsTransport* local = static_cast<FakeDtlsTransport*>(tc);
FakeDtlsTransport* remote = dest->GetFakeDtlsTransport_n(
local->transport_name(), local->component());
if (remote) {
bool asymmetric = false;
local->SetDestination(remote, asymmetric);
}
}
}
};
} // namespace cricket
#endif // WEBRTC_P2P_BASE_FAKETRANSPORTCONTROLLER_H_