Before this CL, we would negotiate: - No crypto suites for data m= sections. - A full set for audio m= sections. - The full set, minus SRTP_AES128_CM_SHA1_32 for video m= sections. However, this doesn't make sense with BUNDLE, since any DTLS association could end up being used for any type of media. If video is "bundled on" the audio transport (which is typical), it will actually end up using SRTP_AES128_CM_SHA1_32. So, this CL moves the responsibility of deciding SRTP crypto suites out of BaseChannel and into DtlsTransport. The only two possibilities are now "normal set" or "normal set + GCM", if enabled by the PC factory options. This fixes an issue (see linked bug) that was occurring when audio/video were "bundled onto" the data transport. Since the data transport wasn't negotiating any SRTP crypto suites, none were available to use for audio/video, so the application would get black video/no audio. This CL doesn't affect the SDES SRTP crypto suite negotiation; it only affects the negotiation in the DLTS handshake, through the use_srtp extension. BUG=chromium:711243 Review-Url: https://codereview.webrtc.org/2815513012 Cr-Commit-Position: refs/heads/master@{#17810}
160 lines
6.2 KiB
C++
160 lines
6.2 KiB
C++
/*
|
|
* 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/base/bind.h"
|
|
#include "webrtc/base/sslfingerprint.h"
|
|
#include "webrtc/base/thread.h"
|
|
#include "webrtc/p2p/base/fakedtlstransport.h"
|
|
#include "webrtc/p2p/base/fakeicetransport.h"
|
|
#include "webrtc/p2p/base/transportcontroller.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_
|