Create the SrtpTransportInterface.
Create the SrtpTransportInterface, a subclass of RtpTransportInterface, which allows the user to set the send and receive keys. The functionalities are implemented inside the RtpTransportAdapters on top of BaseChannel. BUG=webrtc:7013 Review-Url: https://codereview.webrtc.org/2714813004 Cr-Commit-Position: refs/heads/master@{#17023}
This commit is contained in:
parent
716e726ef0
commit
d3501adf17
@ -94,6 +94,7 @@ rtc_source_set("ortc_api") {
|
||||
"ortc/packettransportinterface.h",
|
||||
"ortc/rtptransportcontrollerinterface.h",
|
||||
"ortc/rtptransportinterface.h",
|
||||
"ortc/srtptransportinterface.h",
|
||||
"ortc/udptransportinterface.h",
|
||||
]
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include "webrtc/api/ortc/packettransportinterface.h"
|
||||
#include "webrtc/api/ortc/rtptransportcontrollerinterface.h"
|
||||
#include "webrtc/api/ortc/rtptransportinterface.h"
|
||||
#include "webrtc/api/ortc/srtptransportinterface.h"
|
||||
#include "webrtc/api/ortc/udptransportinterface.h"
|
||||
#include "webrtc/api/rtcerror.h"
|
||||
#include "webrtc/api/rtpparameters.h"
|
||||
@ -126,6 +127,14 @@ class OrtcFactoryInterface {
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerInterface* transport_controller) = 0;
|
||||
|
||||
// Creates an SrtpTransport which is an RTP transport that uses SRTP.
|
||||
virtual RTCErrorOr<std::unique_ptr<SrtpTransportInterface>>
|
||||
CreateSrtpTransport(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerInterface* transport_controller) = 0;
|
||||
|
||||
// Returns the capabilities of an RTP sender of type |kind|. These
|
||||
// capabilities can be used to determine what RtpParameters to use to create
|
||||
// an RtpSender.
|
||||
|
||||
@ -18,8 +18,8 @@
|
||||
#ifndef WEBRTC_API_ORTC_ORTCRTPSENDERINTERFACE_H_
|
||||
#define WEBRTC_API_ORTC_ORTCRTPSENDERINTERFACE_H_
|
||||
|
||||
#include "webrtc/api/mediatypes.h"
|
||||
#include "webrtc/api/mediastreaminterface.h"
|
||||
#include "webrtc/api/mediatypes.h"
|
||||
#include "webrtc/api/ortc/rtptransportinterface.h"
|
||||
#include "webrtc/api/rtcerror.h"
|
||||
#include "webrtc/api/rtpparameters.h"
|
||||
|
||||
48
webrtc/api/ortc/srtptransportinterface.h
Normal file
48
webrtc/api/ortc/srtptransportinterface.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2017 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_API_ORTC_SRTPTRANSPORTINTERFACE_H_
|
||||
#define WEBRTC_API_ORTC_SRTPTRANSPORTINTERFACE_H_
|
||||
|
||||
#include "webrtc/api/ortc/rtptransportinterface.h"
|
||||
#include "webrtc/api/rtcerror.h"
|
||||
#include "webrtc/media/base/cryptoparams.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// The subclass of the RtpTransport which uses SRTP. The keying information
|
||||
// is explicitly passed in from the application.
|
||||
//
|
||||
// If using SDP and SDES (RFC4568) for signaling, then after applying the
|
||||
// answer, the negotiated keying information from the offer and answer would be
|
||||
// set and the SRTP would be active.
|
||||
//
|
||||
// Note that Edge's implementation of ORTC provides a similar API point, called
|
||||
// RTCSrtpSdesTransport:
|
||||
// https://msdn.microsoft.com/en-us/library/mt502527(v=vs.85).aspx
|
||||
class SrtpTransportInterface : public RtpTransportInterface {
|
||||
public:
|
||||
virtual ~SrtpTransportInterface() {}
|
||||
|
||||
// There are some limitations of the current implementation:
|
||||
// 1. Send and receive keys must use the same crypto suite.
|
||||
// 2. The keys can't be changed after initially set.
|
||||
// 3. The keys must be set before creating a sender/receiver using the SRTP
|
||||
// transport.
|
||||
// Set the SRTP keying material for sending RTP and RTCP.
|
||||
virtual RTCError SetSrtpSendKey(const cricket::CryptoParams& params) = 0;
|
||||
|
||||
// Set the SRTP keying material for receiving RTP and RTCP.
|
||||
virtual RTCError SetSrtpReceiveKey(const cricket::CryptoParams& params) = 0;
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // WEBRTC_API_ORTC_SRTPTRANSPORTINTERFACE_H_
|
||||
@ -16,8 +16,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/api/mediatypes.h"
|
||||
#include "webrtc/config.h"
|
||||
#include "webrtc/base/optional.h"
|
||||
#include "webrtc/config.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
|
||||
@ -58,6 +58,7 @@ if (rtc_include_tests) {
|
||||
"rtpparametersconversion_unittest.cc",
|
||||
"rtptransport_unittest.cc",
|
||||
"rtptransportcontroller_unittest.cc",
|
||||
"srtptransport_unittest.cc",
|
||||
"testrtpparameters.cc",
|
||||
"testrtpparameters.h",
|
||||
]
|
||||
|
||||
@ -11,11 +11,11 @@
|
||||
#include "webrtc/ortc/ortcfactory.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <utility> // For std::move.
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/api/proxy.h"
|
||||
#include "webrtc/api/mediastreamtrackproxy.h"
|
||||
#include "webrtc/api/proxy.h"
|
||||
#include "webrtc/api/rtcerror.h"
|
||||
#include "webrtc/api/videosourceproxy.h"
|
||||
#include "webrtc/base/asyncpacketsocket.h"
|
||||
@ -33,9 +33,9 @@
|
||||
#include "webrtc/ortc/rtptransportcontrolleradapter.h"
|
||||
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
|
||||
#include "webrtc/p2p/base/udptransport.h"
|
||||
#include "webrtc/pc/audiotrack.h"
|
||||
#include "webrtc/pc/channelmanager.h"
|
||||
#include "webrtc/pc/localaudiosource.h"
|
||||
#include "webrtc/pc/audiotrack.h"
|
||||
#include "webrtc/pc/videocapturertracksource.h"
|
||||
#include "webrtc/pc/videotrack.h"
|
||||
|
||||
@ -78,6 +78,14 @@ PROXY_METHOD4(RTCErrorOr<std::unique_ptr<RtpTransportInterface>>,
|
||||
PacketTransportInterface*,
|
||||
PacketTransportInterface*,
|
||||
RtpTransportControllerInterface*)
|
||||
|
||||
PROXY_METHOD4(RTCErrorOr<std::unique_ptr<SrtpTransportInterface>>,
|
||||
CreateSrtpTransport,
|
||||
const RtcpParameters&,
|
||||
PacketTransportInterface*,
|
||||
PacketTransportInterface*,
|
||||
RtpTransportControllerInterface*)
|
||||
|
||||
PROXY_CONSTMETHOD1(RtpCapabilities,
|
||||
GetRtpSenderCapabilities,
|
||||
cricket::MediaType)
|
||||
@ -250,6 +258,43 @@ OrtcFactory::CreateRtpTransport(
|
||||
}
|
||||
}
|
||||
|
||||
RTCErrorOr<std::unique_ptr<SrtpTransportInterface>>
|
||||
OrtcFactory::CreateSrtpTransport(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerInterface* transport_controller) {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread_);
|
||||
RtcpParameters copied_parameters = rtcp_parameters;
|
||||
if (copied_parameters.cname.empty()) {
|
||||
copied_parameters.cname = default_cname_;
|
||||
}
|
||||
if (transport_controller) {
|
||||
return transport_controller->GetInternal()->CreateProxiedSrtpTransport(
|
||||
copied_parameters, rtp, rtcp);
|
||||
} else {
|
||||
// If |transport_controller| is null, create one automatically, which the
|
||||
// returned SrtpTransport will own.
|
||||
auto controller_result = CreateRtpTransportController();
|
||||
if (!controller_result.ok()) {
|
||||
return controller_result.MoveError();
|
||||
}
|
||||
auto controller = controller_result.MoveValue();
|
||||
auto transport_result =
|
||||
controller->GetInternal()->CreateProxiedSrtpTransport(copied_parameters,
|
||||
rtp, rtcp);
|
||||
// If SrtpTransport was successfully created, transfer ownership of
|
||||
// |rtp_transport_controller|. Otherwise it will go out of scope and be
|
||||
// deleted automatically.
|
||||
if (transport_result.ok()) {
|
||||
transport_result.value()
|
||||
->GetInternal()
|
||||
->TakeOwnershipOfRtpTransportController(std::move(controller));
|
||||
}
|
||||
return transport_result;
|
||||
}
|
||||
}
|
||||
|
||||
RtpCapabilities OrtcFactory::GetRtpSenderCapabilities(
|
||||
cricket::MediaType kind) const {
|
||||
RTC_DCHECK_RUN_ON(signaling_thread_);
|
||||
|
||||
@ -49,6 +49,12 @@ class OrtcFactory : public OrtcFactoryInterface {
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerInterface* transport_controller) override;
|
||||
|
||||
RTCErrorOr<std::unique_ptr<SrtpTransportInterface>> CreateSrtpTransport(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerInterface* transport_controller) override;
|
||||
|
||||
RtpCapabilities GetRtpSenderCapabilities(
|
||||
cricket::MediaType kind) const override;
|
||||
|
||||
|
||||
@ -25,13 +25,38 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const int kDefaultTimeout = 10000; // 10 seconds.
|
||||
const int kDefaultTimeout = 10000; // 10 seconds.
|
||||
const int kReceivingDuration = 1000; // 1 second.
|
||||
// Default number of audio/video frames to wait for before considering a test a
|
||||
// success.
|
||||
const int kDefaultNumFrames = 3;
|
||||
const rtc::IPAddress kIPv4LocalHostAddress =
|
||||
rtc::IPAddress(0x7F000001); // 127.0.0.1
|
||||
|
||||
static const char kTestKeyParams1[] =
|
||||
"inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVz";
|
||||
static const char kTestKeyParams2[] =
|
||||
"inline:PS1uQCVeeCFCanVmcjkpaywjNWhcYD0mXXtxaVBR";
|
||||
static const char kTestKeyParams3[] =
|
||||
"inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVa";
|
||||
static const char kTestKeyParams4[] =
|
||||
"inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVb";
|
||||
static const cricket::CryptoParams kTestCryptoParams1(1,
|
||||
"AES_CM_128_HMAC_SHA1_80",
|
||||
kTestKeyParams1,
|
||||
"");
|
||||
static const cricket::CryptoParams kTestCryptoParams2(1,
|
||||
"AES_CM_128_HMAC_SHA1_80",
|
||||
kTestKeyParams2,
|
||||
"");
|
||||
static const cricket::CryptoParams kTestCryptoParams3(1,
|
||||
"AES_CM_128_HMAC_SHA1_80",
|
||||
kTestKeyParams3,
|
||||
"");
|
||||
static const cricket::CryptoParams kTestCryptoParams4(1,
|
||||
"AES_CM_128_HMAC_SHA1_80",
|
||||
kTestKeyParams4,
|
||||
"");
|
||||
} // namespace
|
||||
|
||||
namespace webrtc {
|
||||
@ -71,6 +96,9 @@ class OrtcFactoryIntegrationTest : public testing::Test {
|
||||
typedef std::pair<std::unique_ptr<RtpTransportInterface>,
|
||||
std::unique_ptr<RtpTransportInterface>>
|
||||
RtpTransportPair;
|
||||
typedef std::pair<std::unique_ptr<SrtpTransportInterface>,
|
||||
std::unique_ptr<SrtpTransportInterface>>
|
||||
SrtpTransportPair;
|
||||
typedef std::pair<std::unique_ptr<RtpTransportControllerInterface>,
|
||||
std::unique_ptr<RtpTransportControllerInterface>>
|
||||
RtpTransportControllerPair;
|
||||
@ -115,6 +143,20 @@ class OrtcFactoryIntegrationTest : public testing::Test {
|
||||
return {transport_result1.MoveValue(), transport_result2.MoveValue()};
|
||||
}
|
||||
|
||||
SrtpTransportPair CreateSrtpTransportPair(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
const UdpTransportPair& rtp_udp_transports,
|
||||
const UdpTransportPair& rtcp_udp_transports,
|
||||
const RtpTransportControllerPair& transport_controllers) {
|
||||
auto transport_result1 = ortc_factory1_->CreateSrtpTransport(
|
||||
rtcp_parameters, rtp_udp_transports.first.get(),
|
||||
rtcp_udp_transports.first.get(), transport_controllers.first.get());
|
||||
auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
|
||||
rtcp_parameters, rtp_udp_transports.second.get(),
|
||||
rtcp_udp_transports.second.get(), transport_controllers.second.get());
|
||||
return {transport_result1.MoveValue(), transport_result2.MoveValue()};
|
||||
}
|
||||
|
||||
// For convenience when |rtcp_udp_transports| and |transport_controllers|
|
||||
// aren't needed.
|
||||
RtpTransportPair CreateRtpTransportPair(
|
||||
@ -125,6 +167,38 @@ class OrtcFactoryIntegrationTest : public testing::Test {
|
||||
RtpTransportControllerPair());
|
||||
}
|
||||
|
||||
SrtpTransportPair CreateSrtpTransportPairAndSetKeys(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
const UdpTransportPair& rtp_udp_transports) {
|
||||
SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
|
||||
rtcp_parameters, rtp_udp_transports, UdpTransportPair(),
|
||||
RtpTransportControllerPair());
|
||||
EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
|
||||
EXPECT_TRUE(
|
||||
srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
|
||||
EXPECT_TRUE(
|
||||
srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2).ok());
|
||||
EXPECT_TRUE(
|
||||
srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1).ok());
|
||||
return srtp_transports;
|
||||
}
|
||||
|
||||
SrtpTransportPair CreateSrtpTransportPairAndSetMismatchingKeys(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
const UdpTransportPair& rtp_udp_transports) {
|
||||
SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
|
||||
rtcp_parameters, rtp_udp_transports, UdpTransportPair(),
|
||||
RtpTransportControllerPair());
|
||||
EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
|
||||
EXPECT_TRUE(
|
||||
srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
|
||||
EXPECT_TRUE(
|
||||
srtp_transports.second->SetSrtpSendKey(kTestCryptoParams1).ok());
|
||||
EXPECT_TRUE(
|
||||
srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams2).ok());
|
||||
return srtp_transports;
|
||||
}
|
||||
|
||||
// Ends up using fake audio capture module, which was passed into OrtcFactory
|
||||
// on creation.
|
||||
rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack(
|
||||
@ -152,6 +226,110 @@ class OrtcFactoryIntegrationTest : public testing::Test {
|
||||
ortc_factory->CreateVideoTrack(id, source));
|
||||
}
|
||||
|
||||
// Helper function used to test two way RTP senders and receivers with basic
|
||||
// configurations.
|
||||
// If |expect_success| is true, waits for kDefaultTimeout for
|
||||
// kDefaultNumFrames frames to be received by all RtpReceivers.
|
||||
// If |expect_success| is false, simply waits for |kReceivingDuration|, and
|
||||
// stores the number of received frames in |received_audio_frame1_| etc.
|
||||
void BasicTwoWayRtpSendersAndReceiversTest(RtpTransportPair srtp_transports,
|
||||
bool expect_success) {
|
||||
received_audio_frames1_ = 0;
|
||||
received_audio_frames2_ = 0;
|
||||
rendered_video_frames1_ = 0;
|
||||
rendered_video_frames2_ = 0;
|
||||
// Create all the senders and receivers (four per endpoint).
|
||||
auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
|
||||
auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
|
||||
auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
|
||||
auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
|
||||
ASSERT_TRUE(audio_sender_result1.ok());
|
||||
ASSERT_TRUE(video_sender_result1.ok());
|
||||
ASSERT_TRUE(audio_receiver_result1.ok());
|
||||
ASSERT_TRUE(video_receiver_result1.ok());
|
||||
auto audio_sender1 = audio_sender_result1.MoveValue();
|
||||
auto video_sender1 = video_sender_result1.MoveValue();
|
||||
auto audio_receiver1 = audio_receiver_result1.MoveValue();
|
||||
auto video_receiver1 = video_receiver_result1.MoveValue();
|
||||
|
||||
auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
|
||||
auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
|
||||
auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
|
||||
auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
|
||||
ASSERT_TRUE(audio_sender_result2.ok());
|
||||
ASSERT_TRUE(video_sender_result2.ok());
|
||||
ASSERT_TRUE(audio_receiver_result2.ok());
|
||||
ASSERT_TRUE(video_receiver_result2.ok());
|
||||
auto audio_sender2 = audio_sender_result2.MoveValue();
|
||||
auto video_sender2 = video_sender_result2.MoveValue();
|
||||
auto audio_receiver2 = audio_receiver_result2.MoveValue();
|
||||
auto video_receiver2 = video_receiver_result2.MoveValue();
|
||||
|
||||
// Add fake tracks.
|
||||
RTCError error = audio_sender1->SetTrack(
|
||||
CreateLocalAudioTrack("audio", ortc_factory1_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
error = video_sender1->SetTrack(
|
||||
CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
error = audio_sender2->SetTrack(
|
||||
CreateLocalAudioTrack("audio", ortc_factory2_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
error = video_sender2->SetTrack(
|
||||
CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory2_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
|
||||
// "sent_X_parameters1" are the parameters that endpoint 1 sends with and
|
||||
// endpoint 2 receives with.
|
||||
RtpParameters sent_opus_parameters1 =
|
||||
MakeMinimalOpusParametersWithSsrc(0xdeadbeef);
|
||||
RtpParameters sent_vp8_parameters1 =
|
||||
MakeMinimalVp8ParametersWithSsrc(0xbaadfeed);
|
||||
RtpParameters sent_opus_parameters2 =
|
||||
MakeMinimalOpusParametersWithSsrc(0x13333337);
|
||||
RtpParameters sent_vp8_parameters2 =
|
||||
MakeMinimalVp8ParametersWithSsrc(0x12345678);
|
||||
|
||||
// Configure the senders' and receivers' parameters.
|
||||
EXPECT_TRUE(audio_receiver1->Receive(sent_opus_parameters2).ok());
|
||||
EXPECT_TRUE(video_receiver1->Receive(sent_vp8_parameters2).ok());
|
||||
EXPECT_TRUE(audio_receiver2->Receive(sent_opus_parameters1).ok());
|
||||
EXPECT_TRUE(video_receiver2->Receive(sent_vp8_parameters1).ok());
|
||||
EXPECT_TRUE(audio_sender1->Send(sent_opus_parameters1).ok());
|
||||
EXPECT_TRUE(video_sender1->Send(sent_vp8_parameters1).ok());
|
||||
EXPECT_TRUE(audio_sender2->Send(sent_opus_parameters2).ok());
|
||||
EXPECT_TRUE(video_sender2->Send(sent_vp8_parameters2).ok());
|
||||
|
||||
FakeVideoTrackRenderer fake_video_renderer1(
|
||||
static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
|
||||
FakeVideoTrackRenderer fake_video_renderer2(
|
||||
static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
|
||||
|
||||
if (expect_success) {
|
||||
EXPECT_TRUE_WAIT(
|
||||
fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
|
||||
fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
|
||||
fake_audio_capture_module2_->frames_received() >
|
||||
kDefaultNumFrames &&
|
||||
fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames,
|
||||
kDefaultTimeout);
|
||||
} else {
|
||||
WAIT(false, kReceivingDuration);
|
||||
rendered_video_frames1_ = fake_video_renderer1.num_rendered_frames();
|
||||
rendered_video_frames2_ = fake_video_renderer2.num_rendered_frames();
|
||||
received_audio_frames1_ = fake_audio_capture_module1_->frames_received();
|
||||
received_audio_frames2_ = fake_audio_capture_module2_->frames_received();
|
||||
}
|
||||
}
|
||||
|
||||
rtc::PhysicalSocketServer physical_socket_server_;
|
||||
rtc::VirtualSocketServer virtual_socket_server_;
|
||||
rtc::Thread network_thread_;
|
||||
@ -162,6 +340,10 @@ class OrtcFactoryIntegrationTest : public testing::Test {
|
||||
std::unique_ptr<OrtcFactoryInterface> ortc_factory2_;
|
||||
// Actually owned by video tracks.
|
||||
std::vector<cricket::FakeVideoCapturer*> fake_video_capturers_;
|
||||
int received_audio_frames1_ = 0;
|
||||
int received_audio_frames2_ = 0;
|
||||
int rendered_video_frames1_ = 0;
|
||||
int rendered_video_frames2_ = 0;
|
||||
};
|
||||
|
||||
// Very basic end-to-end test with a single pair of audio RTP sender and
|
||||
@ -285,102 +467,75 @@ TEST_F(OrtcFactoryIntegrationTest,
|
||||
auto udp_transports = CreateAndConnectUdpTransportPair();
|
||||
auto rtp_transports =
|
||||
CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
|
||||
bool expect_success = true;
|
||||
BasicTwoWayRtpSendersAndReceiversTest(std::move(rtp_transports),
|
||||
expect_success);
|
||||
}
|
||||
|
||||
// Create all the senders and receivers (four per endpoint).
|
||||
auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
|
||||
auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
|
||||
auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
|
||||
auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
|
||||
ASSERT_TRUE(audio_sender_result1.ok());
|
||||
ASSERT_TRUE(video_sender_result1.ok());
|
||||
ASSERT_TRUE(audio_receiver_result1.ok());
|
||||
ASSERT_TRUE(video_receiver_result1.ok());
|
||||
auto audio_sender1 = audio_sender_result1.MoveValue();
|
||||
auto video_sender1 = video_sender_result1.MoveValue();
|
||||
auto audio_receiver1 = audio_receiver_result1.MoveValue();
|
||||
auto video_receiver1 = video_receiver_result1.MoveValue();
|
||||
TEST_F(OrtcFactoryIntegrationTest,
|
||||
BasicTwoWayAudioVideoSrtpSendersAndReceivers) {
|
||||
auto udp_transports = CreateAndConnectUdpTransportPair();
|
||||
auto srtp_transports = CreateSrtpTransportPairAndSetKeys(
|
||||
MakeRtcpMuxParameters(), udp_transports);
|
||||
bool expect_success = true;
|
||||
BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
|
||||
expect_success);
|
||||
}
|
||||
|
||||
auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
|
||||
auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
|
||||
auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
|
||||
auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
|
||||
ASSERT_TRUE(audio_sender_result2.ok());
|
||||
ASSERT_TRUE(video_sender_result2.ok());
|
||||
ASSERT_TRUE(audio_receiver_result2.ok());
|
||||
ASSERT_TRUE(video_receiver_result2.ok());
|
||||
auto audio_sender2 = audio_sender_result2.MoveValue();
|
||||
auto video_sender2 = video_sender_result2.MoveValue();
|
||||
auto audio_receiver2 = audio_receiver_result2.MoveValue();
|
||||
auto video_receiver2 = video_receiver_result2.MoveValue();
|
||||
// Tests that the packets cannot be decoded if the keys are mismatched.
|
||||
TEST_F(OrtcFactoryIntegrationTest, SrtpSendersAndReceiversWithMismatchingKeys) {
|
||||
auto udp_transports = CreateAndConnectUdpTransportPair();
|
||||
auto srtp_transports = CreateSrtpTransportPairAndSetMismatchingKeys(
|
||||
MakeRtcpMuxParameters(), udp_transports);
|
||||
bool expect_success = false;
|
||||
BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
|
||||
expect_success);
|
||||
// No frames are expected to be decoded.
|
||||
EXPECT_TRUE(received_audio_frames1_ == 0 && received_audio_frames2_ == 0 &&
|
||||
rendered_video_frames1_ == 0 && rendered_video_frames2_ == 0);
|
||||
}
|
||||
|
||||
// Add fake tracks.
|
||||
RTCError error = audio_sender1->SetTrack(
|
||||
CreateLocalAudioTrack("audio", ortc_factory1_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
error = video_sender1->SetTrack(
|
||||
CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory1_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
error = audio_sender2->SetTrack(
|
||||
CreateLocalAudioTrack("audio", ortc_factory2_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
error = video_sender2->SetTrack(
|
||||
CreateLocalVideoTrackAndFakeCapturer("video", ortc_factory2_.get()));
|
||||
EXPECT_TRUE(error.ok());
|
||||
// Tests that the frames cannot be decoded if only one side uses SRTP.
|
||||
TEST_F(OrtcFactoryIntegrationTest, OneSideSrtpSenderAndReceiver) {
|
||||
auto rtcp_parameters = MakeRtcpMuxParameters();
|
||||
auto udp_transports = CreateAndConnectUdpTransportPair();
|
||||
auto rtcp_udp_transports = UdpTransportPair();
|
||||
auto transport_controllers = RtpTransportControllerPair();
|
||||
auto transport_result1 = ortc_factory1_->CreateRtpTransport(
|
||||
rtcp_parameters, udp_transports.first.get(),
|
||||
rtcp_udp_transports.first.get(), transport_controllers.first.get());
|
||||
auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
|
||||
rtcp_parameters, udp_transports.second.get(),
|
||||
rtcp_udp_transports.second.get(), transport_controllers.second.get());
|
||||
|
||||
// "sent_X_parameters1" are the parameters that endpoint 1 sends with and
|
||||
// endpoint 2 receives with.
|
||||
RtpParameters sent_opus_parameters1 =
|
||||
MakeMinimalOpusParametersWithSsrc(0xdeadbeef);
|
||||
RtpParameters sent_vp8_parameters1 =
|
||||
MakeMinimalVp8ParametersWithSsrc(0xbaadfeed);
|
||||
RtpParameters sent_opus_parameters2 =
|
||||
MakeMinimalOpusParametersWithSsrc(0x13333337);
|
||||
RtpParameters sent_vp8_parameters2 =
|
||||
MakeMinimalVp8ParametersWithSsrc(0x12345678);
|
||||
auto rtp_transport = transport_result1.MoveValue();
|
||||
auto srtp_transport = transport_result2.MoveValue();
|
||||
EXPECT_TRUE(srtp_transport->SetSrtpSendKey(kTestCryptoParams1).ok());
|
||||
EXPECT_TRUE(srtp_transport->SetSrtpReceiveKey(kTestCryptoParams2).ok());
|
||||
bool expect_success = false;
|
||||
BasicTwoWayRtpSendersAndReceiversTest(
|
||||
{std::move(rtp_transport), std::move(srtp_transport)}, expect_success);
|
||||
|
||||
// Configure the senders' and receivers' parameters.
|
||||
EXPECT_TRUE(audio_receiver1->Receive(sent_opus_parameters2).ok());
|
||||
EXPECT_TRUE(video_receiver1->Receive(sent_vp8_parameters2).ok());
|
||||
EXPECT_TRUE(audio_receiver2->Receive(sent_opus_parameters1).ok());
|
||||
EXPECT_TRUE(video_receiver2->Receive(sent_vp8_parameters1).ok());
|
||||
EXPECT_TRUE(audio_sender1->Send(sent_opus_parameters1).ok());
|
||||
EXPECT_TRUE(video_sender1->Send(sent_vp8_parameters1).ok());
|
||||
EXPECT_TRUE(audio_sender2->Send(sent_opus_parameters2).ok());
|
||||
EXPECT_TRUE(video_sender2->Send(sent_vp8_parameters2).ok());
|
||||
|
||||
FakeVideoTrackRenderer fake_video_renderer1(
|
||||
static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
|
||||
FakeVideoTrackRenderer fake_video_renderer2(
|
||||
static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));
|
||||
|
||||
// Senders and receivers are connected and configured; audio and video frames
|
||||
// should be able to flow at this point.
|
||||
EXPECT_TRUE_WAIT(
|
||||
fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
|
||||
fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
|
||||
fake_audio_capture_module2_->frames_received() > kDefaultNumFrames &&
|
||||
fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
|
||||
kDefaultTimeout);
|
||||
// The SRTP side is not expected to decode any audio or video frames.
|
||||
// The RTP side is not expected to decode any video frames while it is
|
||||
// possible that the encrypted audio frames can be accidentally decoded which
|
||||
// is why received_audio_frames1_ is not validated.
|
||||
EXPECT_TRUE(received_audio_frames2_ == 0 && rendered_video_frames1_ == 0 &&
|
||||
rendered_video_frames2_ == 0);
|
||||
}
|
||||
|
||||
// End-to-end test with two pairs of RTP senders and receivers, for audio and
|
||||
// video. Unlike the test above, this attempts to make the parameters as
|
||||
// complex as possible.
|
||||
// complex as possible. The senders and receivers use the SRTP transport with
|
||||
// different keys.
|
||||
//
|
||||
// Uses non-muxed RTCP, with separate audio/video transports, and a full set of
|
||||
// parameters, as would normally be used in a PeerConnection.
|
||||
//
|
||||
// TODO(deadbeef): Update this test as more audio/video features become
|
||||
// supported.
|
||||
TEST_F(OrtcFactoryIntegrationTest, FullTwoWayAudioVideoRtpSendersAndReceivers) {
|
||||
TEST_F(OrtcFactoryIntegrationTest,
|
||||
FullTwoWayAudioVideoSrtpSendersAndReceivers) {
|
||||
// We want four pairs of UDP transports for this test, for audio/video and
|
||||
// RTP/RTCP.
|
||||
auto audio_rtp_udp_transports = CreateAndConnectUdpTransportPair();
|
||||
@ -394,26 +549,37 @@ TEST_F(OrtcFactoryIntegrationTest, FullTwoWayAudioVideoRtpSendersAndReceivers) {
|
||||
|
||||
RtcpParameters audio_rtcp_parameters;
|
||||
audio_rtcp_parameters.mux = false;
|
||||
auto audio_rtp_transports =
|
||||
CreateRtpTransportPair(audio_rtcp_parameters, audio_rtp_udp_transports,
|
||||
audio_rtcp_udp_transports, transport_controllers);
|
||||
auto audio_srtp_transports =
|
||||
CreateSrtpTransportPair(audio_rtcp_parameters, audio_rtp_udp_transports,
|
||||
audio_rtcp_udp_transports, transport_controllers);
|
||||
|
||||
RtcpParameters video_rtcp_parameters;
|
||||
video_rtcp_parameters.mux = false;
|
||||
video_rtcp_parameters.reduced_size = true;
|
||||
auto video_rtp_transports =
|
||||
CreateRtpTransportPair(video_rtcp_parameters, video_rtp_udp_transports,
|
||||
video_rtcp_udp_transports, transport_controllers);
|
||||
auto video_srtp_transports =
|
||||
CreateSrtpTransportPair(video_rtcp_parameters, video_rtp_udp_transports,
|
||||
video_rtcp_udp_transports, transport_controllers);
|
||||
|
||||
// Set keys for SRTP transports.
|
||||
audio_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1);
|
||||
audio_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2);
|
||||
video_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams3);
|
||||
video_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams4);
|
||||
|
||||
audio_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2);
|
||||
audio_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1);
|
||||
video_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams4);
|
||||
video_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams3);
|
||||
|
||||
// Create all the senders and receivers (four per endpoint).
|
||||
auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.first.get());
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
|
||||
auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.first.get());
|
||||
cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
|
||||
auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.first.get());
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
|
||||
auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.first.get());
|
||||
cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
|
||||
ASSERT_TRUE(audio_sender_result1.ok());
|
||||
ASSERT_TRUE(video_sender_result1.ok());
|
||||
ASSERT_TRUE(audio_receiver_result1.ok());
|
||||
@ -424,13 +590,13 @@ TEST_F(OrtcFactoryIntegrationTest, FullTwoWayAudioVideoRtpSendersAndReceivers) {
|
||||
auto video_receiver1 = video_receiver_result1.MoveValue();
|
||||
|
||||
auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.second.get());
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
|
||||
auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
|
||||
cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.second.get());
|
||||
cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
|
||||
auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_rtp_transports.second.get());
|
||||
cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
|
||||
auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_VIDEO, video_rtp_transports.second.get());
|
||||
cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
|
||||
ASSERT_TRUE(audio_sender_result2.ok());
|
||||
ASSERT_TRUE(video_sender_result2.ok());
|
||||
ASSERT_TRUE(audio_receiver_result2.ok());
|
||||
|
||||
@ -82,6 +82,24 @@ TEST_F(OrtcFactoryTest, CreateRtpTransportWithAndWithoutMux) {
|
||||
EXPECT_TRUE(result.ok());
|
||||
}
|
||||
|
||||
// Simple test for the successful cases of CreateSrtpTransport.
|
||||
TEST_F(OrtcFactoryTest, CreateSrtpTransport) {
|
||||
rtc::FakePacketTransport rtp("rtp");
|
||||
rtc::FakePacketTransport rtcp("rtcp");
|
||||
// With muxed RTCP.
|
||||
RtcpParameters rtcp_parameters;
|
||||
rtcp_parameters.mux = true;
|
||||
auto result = ortc_factory_->CreateSrtpTransport(rtcp_parameters, &rtp,
|
||||
nullptr, nullptr);
|
||||
EXPECT_TRUE(result.ok());
|
||||
result.MoveValue().reset();
|
||||
// With non-muxed RTCP.
|
||||
rtcp_parameters.mux = false;
|
||||
result =
|
||||
ortc_factory_->CreateSrtpTransport(rtcp_parameters, &rtp, &rtcp, nullptr);
|
||||
EXPECT_TRUE(result.ok());
|
||||
}
|
||||
|
||||
// If no CNAME is provided, one should be generated and returned by
|
||||
// GetRtpParameters.
|
||||
TEST_F(OrtcFactoryTest, CreateRtpTransportGeneratesCname) {
|
||||
|
||||
@ -12,9 +12,9 @@
|
||||
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/media/base/fakemediaengine.h"
|
||||
#include "webrtc/p2p/base/fakepackettransport.h"
|
||||
#include "webrtc/ortc/ortcfactory.h"
|
||||
#include "webrtc/ortc/testrtpparameters.h"
|
||||
#include "webrtc/p2p/base/fakepackettransport.h"
|
||||
#include "webrtc/pc/test/fakevideotracksource.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -12,9 +12,9 @@
|
||||
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/media/base/fakemediaengine.h"
|
||||
#include "webrtc/p2p/base/fakepackettransport.h"
|
||||
#include "webrtc/ortc/ortcfactory.h"
|
||||
#include "webrtc/ortc/testrtpparameters.h"
|
||||
#include "webrtc/p2p/base/fakepackettransport.h"
|
||||
#include "webrtc/pc/test/fakevideotracksource.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
#include "webrtc/api/rtcerror.h"
|
||||
#include "webrtc/api/rtpparameters.h"
|
||||
#include "webrtc/base/optional.h"
|
||||
#include "webrtc/pc/mediasession.h"
|
||||
#include "webrtc/media/base/codec.h"
|
||||
#include "webrtc/pc/mediasession.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
|
||||
@ -32,6 +32,20 @@ RtpTransportAdapter* GetInternal() override {
|
||||
}
|
||||
END_PROXY_MAP()
|
||||
|
||||
BEGIN_OWNED_PROXY_MAP(SrtpTransport)
|
||||
PROXY_SIGNALING_THREAD_DESTRUCTOR()
|
||||
PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtpPacketTransport)
|
||||
PROXY_CONSTMETHOD0(PacketTransportInterface*, GetRtcpPacketTransport)
|
||||
PROXY_METHOD1(RTCError, SetRtcpParameters, const RtcpParameters&)
|
||||
PROXY_CONSTMETHOD0(RtcpParameters, GetRtcpParameters)
|
||||
PROXY_METHOD1(RTCError, SetSrtpSendKey, const cricket::CryptoParams&)
|
||||
PROXY_METHOD1(RTCError, SetSrtpReceiveKey, const cricket::CryptoParams&)
|
||||
protected:
|
||||
RtpTransportAdapter* GetInternal() override {
|
||||
return internal();
|
||||
}
|
||||
END_PROXY_MAP()
|
||||
|
||||
// static
|
||||
RTCErrorOr<std::unique_ptr<RtpTransportInterface>>
|
||||
RtpTransportAdapter::CreateProxied(
|
||||
@ -64,7 +78,43 @@ RtpTransportAdapter::CreateProxied(
|
||||
rtp_transport_controller->signaling_thread(),
|
||||
rtp_transport_controller->worker_thread(),
|
||||
std::unique_ptr<RtpTransportAdapter>(new RtpTransportAdapter(
|
||||
rtcp_parameters, rtp, rtcp, rtp_transport_controller)));
|
||||
rtcp_parameters, rtp, rtcp, rtp_transport_controller,
|
||||
/*is_srtp_transport*/ false)));
|
||||
}
|
||||
|
||||
RTCErrorOr<std::unique_ptr<SrtpTransportInterface>>
|
||||
RtpTransportAdapter::CreateSrtpProxied(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerAdapter* rtp_transport_controller) {
|
||||
if (!rtp) {
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
|
||||
"Must provide an RTP packet transport.");
|
||||
}
|
||||
if (!rtcp_parameters.mux && !rtcp) {
|
||||
LOG_AND_RETURN_ERROR(
|
||||
RTCErrorType::INVALID_PARAMETER,
|
||||
"Must provide an RTCP packet transport when RTCP muxing is not used.");
|
||||
}
|
||||
if (rtcp_parameters.mux && rtcp) {
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
|
||||
"Creating an RtpTransport with RTCP muxing enabled, "
|
||||
"with a separate RTCP packet transport?");
|
||||
}
|
||||
if (!rtp_transport_controller) {
|
||||
// Since OrtcFactory::CreateRtpTransport creates an RtpTransportController
|
||||
// automatically when one isn't passed in, this should never be reached.
|
||||
RTC_NOTREACHED();
|
||||
LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
|
||||
"Must provide an RTP transport controller.");
|
||||
}
|
||||
return SrtpTransportProxyWithInternal<RtpTransportAdapter>::Create(
|
||||
rtp_transport_controller->signaling_thread(),
|
||||
rtp_transport_controller->worker_thread(),
|
||||
std::unique_ptr<RtpTransportAdapter>(new RtpTransportAdapter(
|
||||
rtcp_parameters, rtp, rtcp, rtp_transport_controller,
|
||||
/*is_srtp_transport*/ true)));
|
||||
}
|
||||
|
||||
void RtpTransportAdapter::TakeOwnershipOfRtpTransportController(
|
||||
@ -78,11 +128,13 @@ RtpTransportAdapter::RtpTransportAdapter(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerAdapter* rtp_transport_controller)
|
||||
RtpTransportControllerAdapter* rtp_transport_controller,
|
||||
bool is_srtp_transport)
|
||||
: rtp_packet_transport_(rtp),
|
||||
rtcp_packet_transport_(rtcp),
|
||||
rtp_transport_controller_(rtp_transport_controller),
|
||||
rtcp_parameters_(rtcp_parameters) {
|
||||
rtcp_parameters_(rtcp_parameters),
|
||||
is_srtp_transport_(is_srtp_transport) {
|
||||
RTC_DCHECK(rtp_transport_controller);
|
||||
// CNAME should have been filled by OrtcFactory if empty.
|
||||
RTC_DCHECK(!rtcp_parameters_.cname.empty());
|
||||
@ -126,4 +178,36 @@ RTCError RtpTransportAdapter::SetRtcpParameters(
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
RTCError RtpTransportAdapter::SetSrtpSendKey(
|
||||
const cricket::CryptoParams& params) {
|
||||
if (send_key_) {
|
||||
LOG_AND_RETURN_ERROR(
|
||||
webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
"Setting the SRTP send key twice is currently unsupported.");
|
||||
}
|
||||
if (receive_key_ && receive_key_->cipher_suite != params.cipher_suite) {
|
||||
LOG_AND_RETURN_ERROR(
|
||||
webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
"The send key and receive key must have the same cipher suite.");
|
||||
}
|
||||
send_key_ = rtc::Optional<cricket::CryptoParams>(params);
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
RTCError RtpTransportAdapter::SetSrtpReceiveKey(
|
||||
const cricket::CryptoParams& params) {
|
||||
if (receive_key_) {
|
||||
LOG_AND_RETURN_ERROR(
|
||||
webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
"Setting the SRTP receive key twice is currently unsupported.");
|
||||
}
|
||||
if (send_key_ && send_key_->cipher_suite != params.cipher_suite) {
|
||||
LOG_AND_RETURN_ERROR(
|
||||
webrtc::RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
"The send key and receive key must have the same cipher suite.");
|
||||
}
|
||||
receive_key_ = rtc::Optional<cricket::CryptoParams>(params);
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/api/ortc/rtptransportinterface.h"
|
||||
#include "webrtc/api/ortc/srtptransportinterface.h"
|
||||
#include "webrtc/api/rtcerror.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
@ -24,13 +24,14 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// Implementation of RtpTransportInterface to be used with RtpSenderAdapter,
|
||||
// RtpReceiverAdapter, and RtpTransportControllerAdapter classes.
|
||||
// Implementation of SrtpTransportInterface to be used with RtpSenderAdapter,
|
||||
// RtpReceiverAdapter, and RtpTransportControllerAdapter classes. This class
|
||||
// is used to implement both a secure and insecure RTP transport.
|
||||
//
|
||||
// TODO(deadbeef): When BaseChannel is split apart into separate
|
||||
// "RtpTransport"/"RtpTransceiver"/"RtpSender"/"RtpReceiver" objects, this
|
||||
// adapter object can be removed.
|
||||
class RtpTransportAdapter : public RtpTransportInterface {
|
||||
class RtpTransportAdapter : public SrtpTransportInterface {
|
||||
public:
|
||||
// |rtp| can't be null. |rtcp| can if RTCP muxing is used immediately (meaning
|
||||
// |rtcp_parameters.mux| is also true).
|
||||
@ -39,6 +40,13 @@ class RtpTransportAdapter : public RtpTransportInterface {
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerAdapter* rtp_transport_controller);
|
||||
|
||||
static RTCErrorOr<std::unique_ptr<SrtpTransportInterface>> CreateSrtpProxied(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerAdapter* rtp_transport_controller);
|
||||
|
||||
~RtpTransportAdapter() override;
|
||||
|
||||
// RtpTransportInterface implementation.
|
||||
@ -47,6 +55,10 @@ class RtpTransportAdapter : public RtpTransportInterface {
|
||||
RTCError SetRtcpParameters(const RtcpParameters& parameters) override;
|
||||
RtcpParameters GetRtcpParameters() const override { return rtcp_parameters_; }
|
||||
|
||||
// SRTP specific implementation.
|
||||
RTCError SetSrtpSendKey(const cricket::CryptoParams& params) override;
|
||||
RTCError SetSrtpReceiveKey(const cricket::CryptoParams& params) override;
|
||||
|
||||
// Methods used internally by OrtcFactory.
|
||||
RtpTransportControllerAdapter* rtp_transport_controller() {
|
||||
return rtp_transport_controller_;
|
||||
@ -58,6 +70,14 @@ class RtpTransportAdapter : public RtpTransportInterface {
|
||||
// returning this transport from GetTransports().
|
||||
sigslot::signal1<RtpTransportAdapter*> SignalDestroyed;
|
||||
|
||||
// Used by the RtpTransportControllerAdapter to tell if an rtp sender or
|
||||
// receiver can be created.
|
||||
bool is_srtp_transport() { return is_srtp_transport_; }
|
||||
// Used by the RtpTransportControllerAdapter to set keys for senders and
|
||||
// receivers.
|
||||
rtc::Optional<cricket::CryptoParams> send_key() { return send_key_; }
|
||||
rtc::Optional<cricket::CryptoParams> receive_key() { return receive_key_; }
|
||||
|
||||
protected:
|
||||
RtpTransportAdapter* GetInternal() override { return this; }
|
||||
|
||||
@ -65,7 +85,8 @@ class RtpTransportAdapter : public RtpTransportInterface {
|
||||
RtpTransportAdapter(const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp,
|
||||
RtpTransportControllerAdapter* rtp_transport_controller);
|
||||
RtpTransportControllerAdapter* rtp_transport_controller,
|
||||
bool is_srtp_transport);
|
||||
|
||||
PacketTransportInterface* rtp_packet_transport_;
|
||||
PacketTransportInterface* rtcp_packet_transport_;
|
||||
@ -75,6 +96,11 @@ class RtpTransportAdapter : public RtpTransportInterface {
|
||||
owned_rtp_transport_controller_;
|
||||
RtcpParameters rtcp_parameters_;
|
||||
|
||||
// SRTP specific members.
|
||||
rtc::Optional<cricket::CryptoParams> send_key_;
|
||||
rtc::Optional<cricket::CryptoParams> receive_key_;
|
||||
bool is_srtp_transport_;
|
||||
|
||||
RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(RtpTransportAdapter);
|
||||
};
|
||||
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
#include "webrtc/ortc/rtptransportcontrolleradapter.h"
|
||||
|
||||
#include <algorithm> // For "remove", "find".
|
||||
#include <sstream>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <unordered_map>
|
||||
#include <utility> // For std::move.
|
||||
|
||||
@ -138,6 +138,21 @@ RtpTransportControllerAdapter::CreateProxiedRtpTransport(
|
||||
return result;
|
||||
}
|
||||
|
||||
RTCErrorOr<std::unique_ptr<SrtpTransportInterface>>
|
||||
RtpTransportControllerAdapter::CreateProxiedSrtpTransport(
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp) {
|
||||
auto result =
|
||||
RtpTransportAdapter::CreateSrtpProxied(rtcp_parameters, rtp, rtcp, this);
|
||||
if (result.ok()) {
|
||||
transport_proxies_.push_back(result.value().get());
|
||||
transport_proxies_.back()->GetInternal()->SignalDestroyed.connect(
|
||||
this, &RtpTransportControllerAdapter::OnRtpTransportDestroyed);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
RTCErrorOr<std::unique_ptr<OrtcRtpSenderInterface>>
|
||||
RtpTransportControllerAdapter::CreateProxiedRtpSender(
|
||||
cricket::MediaType kind,
|
||||
@ -605,6 +620,11 @@ RTCError RtpTransportControllerAdapter::AttachAudioSender(
|
||||
"RtpSender and RtpReceiver is not currently "
|
||||
"supported.");
|
||||
}
|
||||
RTCError err = MaybeSetCryptos(inner_transport, &local_audio_description_,
|
||||
&remote_audio_description_);
|
||||
if (!err.ok()) {
|
||||
return err;
|
||||
}
|
||||
// If setting new transport, extract its RTCP parameters and create voice
|
||||
// channel.
|
||||
if (!inner_audio_transport_) {
|
||||
@ -635,6 +655,11 @@ RTCError RtpTransportControllerAdapter::AttachVideoSender(
|
||||
"RtpSender and RtpReceiver is not currently "
|
||||
"supported.");
|
||||
}
|
||||
RTCError err = MaybeSetCryptos(inner_transport, &local_video_description_,
|
||||
&remote_video_description_);
|
||||
if (!err.ok()) {
|
||||
return err;
|
||||
}
|
||||
// If setting new transport, extract its RTCP parameters and create video
|
||||
// channel.
|
||||
if (!inner_video_transport_) {
|
||||
@ -665,6 +690,11 @@ RTCError RtpTransportControllerAdapter::AttachAudioReceiver(
|
||||
"RtpReceiver and RtpReceiver is not currently "
|
||||
"supported.");
|
||||
}
|
||||
RTCError err = MaybeSetCryptos(inner_transport, &local_audio_description_,
|
||||
&remote_audio_description_);
|
||||
if (!err.ok()) {
|
||||
return err;
|
||||
}
|
||||
// If setting new transport, extract its RTCP parameters and create voice
|
||||
// channel.
|
||||
if (!inner_audio_transport_) {
|
||||
@ -695,6 +725,11 @@ RTCError RtpTransportControllerAdapter::AttachVideoReceiver(
|
||||
"RtpReceiver and RtpReceiver is not currently "
|
||||
"supported.");
|
||||
}
|
||||
RTCError err = MaybeSetCryptos(inner_transport, &local_video_description_,
|
||||
&remote_video_description_);
|
||||
if (!err.ok()) {
|
||||
return err;
|
||||
}
|
||||
// If setting new transport, extract its RTCP parameters and create video
|
||||
// channel.
|
||||
if (!inner_video_transport_) {
|
||||
@ -896,4 +931,25 @@ RtpTransportControllerAdapter::MakeSendStreamParamsVec(
|
||||
return result;
|
||||
}
|
||||
|
||||
RTCError RtpTransportControllerAdapter::MaybeSetCryptos(
|
||||
RtpTransportInterface* rtp_transport,
|
||||
cricket::MediaContentDescription* local_description,
|
||||
cricket::MediaContentDescription* remote_description) {
|
||||
if (rtp_transport->GetInternal()->is_srtp_transport()) {
|
||||
if (!rtp_transport->GetInternal()->send_key() ||
|
||||
!rtp_transport->GetInternal()->receive_key()) {
|
||||
LOG_AND_RETURN_ERROR(webrtc::RTCErrorType::UNSUPPORTED_PARAMETER,
|
||||
"The SRTP send key or receive key is not set.")
|
||||
}
|
||||
std::vector<cricket::CryptoParams> cryptos;
|
||||
cryptos.push_back(*(rtp_transport->GetInternal()->receive_key()));
|
||||
local_description->set_cryptos(cryptos);
|
||||
|
||||
cryptos.clear();
|
||||
cryptos.push_back(*(rtp_transport->GetInternal()->send_key()));
|
||||
remote_description->set_cryptos(cryptos);
|
||||
}
|
||||
return RTCError::OK();
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -16,18 +16,18 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/api/ortc/ortcrtpreceiverinterface.h"
|
||||
#include "webrtc/api/ortc/ortcrtpsenderinterface.h"
|
||||
#include "webrtc/api/ortc/rtptransportcontrollerinterface.h"
|
||||
#include "webrtc/api/ortc/srtptransportinterface.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/call/call.h"
|
||||
#include "webrtc/logging/rtc_event_log/rtc_event_log.h"
|
||||
#include "webrtc/api/ortc/ortcrtpreceiverinterface.h"
|
||||
#include "webrtc/api/ortc/ortcrtpsenderinterface.h"
|
||||
#include "webrtc/api/ortc/rtptransportcontrollerinterface.h"
|
||||
#include "webrtc/api/ortc/rtptransportinterface.h"
|
||||
#include "webrtc/media/base/mediachannel.h" // For MediaConfig.
|
||||
#include "webrtc/pc/channelmanager.h"
|
||||
#include "webrtc/pc/mediacontroller.h"
|
||||
#include "webrtc/media/base/mediachannel.h" // For MediaConfig.
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -81,6 +81,12 @@ class RtpTransportControllerAdapter : public RtpTransportControllerInterface,
|
||||
const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp);
|
||||
|
||||
RTCErrorOr<std::unique_ptr<SrtpTransportInterface>>
|
||||
CreateProxiedSrtpTransport(const RtcpParameters& rtcp_parameters,
|
||||
PacketTransportInterface* rtp,
|
||||
PacketTransportInterface* rtcp);
|
||||
|
||||
// |transport_proxy| needs to be a proxy to a transport because the
|
||||
// application may call GetTransport() on the returned sender or receiver,
|
||||
// and expects it to return a thread-safe transport proxy.
|
||||
@ -170,6 +176,13 @@ class RtpTransportControllerAdapter : public RtpTransportControllerInterface,
|
||||
const std::string& cname,
|
||||
const cricket::MediaContentDescription& description) const;
|
||||
|
||||
// If the |rtp_transport| is a SrtpTransport, set the cryptos of the
|
||||
// audio/video content descriptions.
|
||||
RTCError MaybeSetCryptos(
|
||||
RtpTransportInterface* rtp_transport,
|
||||
cricket::MediaContentDescription* local_description,
|
||||
cricket::MediaContentDescription* remote_description);
|
||||
|
||||
rtc::Thread* signaling_thread_;
|
||||
rtc::Thread* worker_thread_;
|
||||
// |transport_proxies_| and |inner_audio_transport_|/|inner_audio_transport_|
|
||||
|
||||
167
webrtc/ortc/srtptransport_unittest.cc
Normal file
167
webrtc/ortc/srtptransport_unittest.cc
Normal file
@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "webrtc/base/gunit.h"
|
||||
#include "webrtc/media/base/fakemediaengine.h"
|
||||
#include "webrtc/ortc/ortcfactory.h"
|
||||
#include "webrtc/ortc/testrtpparameters.h"
|
||||
#include "webrtc/p2p/base/fakepackettransport.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
static const char kTestSha1KeyParams1[] =
|
||||
"inline:WVNfX19zZW1jdGwgKCkgewkyMjA7fQp9CnVubGVz";
|
||||
static const char kTestSha1KeyParams2[] =
|
||||
"inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR";
|
||||
static const char kTestGcmKeyParams3[] =
|
||||
"inline:e166KFlKzJsGW0d5apX+rrI05vxbrvMJEzFI14aTDCa63IRTlLK4iH66uOI=";
|
||||
|
||||
static const cricket::CryptoParams kTestSha1CryptoParams1(
|
||||
1,
|
||||
"AES_CM_128_HMAC_SHA1_80",
|
||||
kTestSha1KeyParams1,
|
||||
"");
|
||||
static const cricket::CryptoParams kTestSha1CryptoParams2(
|
||||
1,
|
||||
"AES_CM_128_HMAC_SHA1_80",
|
||||
kTestSha1KeyParams2,
|
||||
"");
|
||||
static const cricket::CryptoParams kTestGcmCryptoParams3(1,
|
||||
"AEAD_AES_256_GCM",
|
||||
kTestGcmKeyParams3,
|
||||
"");
|
||||
|
||||
// This test uses fake packet transports and a fake media engine, in order to
|
||||
// test the SrtpTransport at only an API level. Any end-to-end test should go in
|
||||
// ortcfactory_integrationtest.cc instead.
|
||||
class SrtpTransportTest : public testing::Test {
|
||||
public:
|
||||
SrtpTransportTest() {
|
||||
fake_media_engine_ = new cricket::FakeMediaEngine();
|
||||
// Note: This doesn't need to use fake network classes, since it uses
|
||||
// FakePacketTransports.
|
||||
auto result = OrtcFactory::Create(
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr,
|
||||
std::unique_ptr<cricket::MediaEngineInterface>(fake_media_engine_));
|
||||
ortc_factory_ = result.MoveValue();
|
||||
rtp_transport_controller_ =
|
||||
ortc_factory_->CreateRtpTransportController().MoveValue();
|
||||
|
||||
fake_packet_transport_.reset(new rtc::FakePacketTransport("fake"));
|
||||
auto srtp_transport_result = ortc_factory_->CreateSrtpTransport(
|
||||
rtcp_parameters_, fake_packet_transport_.get(), nullptr,
|
||||
rtp_transport_controller_.get());
|
||||
srtp_transport_ = srtp_transport_result.MoveValue();
|
||||
}
|
||||
|
||||
protected:
|
||||
// Owned by |ortc_factory_|.
|
||||
cricket::FakeMediaEngine* fake_media_engine_;
|
||||
std::unique_ptr<OrtcFactoryInterface> ortc_factory_;
|
||||
std::unique_ptr<RtpTransportControllerInterface> rtp_transport_controller_;
|
||||
std::unique_ptr<SrtpTransportInterface> srtp_transport_;
|
||||
RtcpParameters rtcp_parameters_;
|
||||
std::unique_ptr<rtc::FakePacketTransport> fake_packet_transport_;
|
||||
};
|
||||
|
||||
// Tests that setting the SRTP send/receive key succeeds.
|
||||
TEST_F(SrtpTransportTest, SetSrtpSendAndReceiveKey) {
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpSendKey(kTestSha1CryptoParams1).ok());
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpReceiveKey(kTestSha1CryptoParams2).ok());
|
||||
auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_AUDIO,
|
||||
srtp_transport_.get());
|
||||
EXPECT_TRUE(sender_result.ok());
|
||||
auto receiver_result = ortc_factory_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, srtp_transport_.get());
|
||||
EXPECT_TRUE(receiver_result.ok());
|
||||
}
|
||||
|
||||
// Tests that setting the SRTP send/receive key twice is not supported.
|
||||
TEST_F(SrtpTransportTest, SetSrtpSendAndReceiveKeyTwice) {
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpSendKey(kTestSha1CryptoParams1).ok());
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpReceiveKey(kTestSha1CryptoParams2).ok());
|
||||
EXPECT_EQ(RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
srtp_transport_->SetSrtpSendKey(kTestSha1CryptoParams2).type());
|
||||
EXPECT_EQ(RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
srtp_transport_->SetSrtpReceiveKey(kTestSha1CryptoParams1).type());
|
||||
// Ensure that the senders and receivers can be created despite the previous
|
||||
// errors.
|
||||
auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_AUDIO,
|
||||
srtp_transport_.get());
|
||||
EXPECT_TRUE(sender_result.ok());
|
||||
auto receiver_result = ortc_factory_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, srtp_transport_.get());
|
||||
EXPECT_TRUE(receiver_result.ok());
|
||||
}
|
||||
|
||||
// Test that the SRTP send key and receive key must have the same cipher suite.
|
||||
TEST_F(SrtpTransportTest, SetSrtpSendAndReceiveKeyDifferentCipherSuite) {
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpSendKey(kTestSha1CryptoParams1).ok());
|
||||
EXPECT_EQ(RTCErrorType::UNSUPPORTED_OPERATION,
|
||||
srtp_transport_->SetSrtpReceiveKey(kTestGcmCryptoParams3).type());
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpReceiveKey(kTestSha1CryptoParams2).ok());
|
||||
// Ensure that the senders and receivers can be created despite the previous
|
||||
// error.
|
||||
auto sender_result = ortc_factory_->CreateRtpSender(cricket::MEDIA_TYPE_AUDIO,
|
||||
srtp_transport_.get());
|
||||
EXPECT_TRUE(sender_result.ok());
|
||||
auto receiver_result = ortc_factory_->CreateRtpReceiver(
|
||||
cricket::MEDIA_TYPE_AUDIO, srtp_transport_.get());
|
||||
EXPECT_TRUE(receiver_result.ok());
|
||||
}
|
||||
|
||||
class SrtpTransportTestWithMediaType
|
||||
: public SrtpTransportTest,
|
||||
public ::testing::WithParamInterface<cricket::MediaType> {};
|
||||
|
||||
// Tests that the senders cannot be created before setting the keys.
|
||||
TEST_P(SrtpTransportTestWithMediaType, CreateSenderBeforeSettingKeys) {
|
||||
auto sender_result =
|
||||
ortc_factory_->CreateRtpSender(GetParam(), srtp_transport_.get());
|
||||
EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, sender_result.error().type());
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpSendKey(kTestSha1CryptoParams1).ok());
|
||||
sender_result =
|
||||
ortc_factory_->CreateRtpSender(GetParam(), srtp_transport_.get());
|
||||
EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, sender_result.error().type());
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpReceiveKey(kTestSha1CryptoParams2).ok());
|
||||
// Ensure that after the keys are set, a sender can be created, despite the
|
||||
// previous errors.
|
||||
sender_result =
|
||||
ortc_factory_->CreateRtpSender(GetParam(), srtp_transport_.get());
|
||||
EXPECT_TRUE(sender_result.ok());
|
||||
}
|
||||
|
||||
// Tests that the receivers cannot be created before setting the keys.
|
||||
TEST_P(SrtpTransportTestWithMediaType, CreateReceiverBeforeSettingKeys) {
|
||||
auto receiver_result =
|
||||
ortc_factory_->CreateRtpReceiver(GetParam(), srtp_transport_.get());
|
||||
EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
|
||||
receiver_result.error().type());
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpSendKey(kTestSha1CryptoParams1).ok());
|
||||
receiver_result =
|
||||
ortc_factory_->CreateRtpReceiver(GetParam(), srtp_transport_.get());
|
||||
EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
|
||||
receiver_result.error().type());
|
||||
EXPECT_TRUE(srtp_transport_->SetSrtpReceiveKey(kTestSha1CryptoParams2).ok());
|
||||
// Ensure that after the keys are set, a receiver can be created, despite the
|
||||
// previous errors.
|
||||
receiver_result =
|
||||
ortc_factory_->CreateRtpReceiver(GetParam(), srtp_transport_.get());
|
||||
EXPECT_TRUE(receiver_result.ok());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(SenderCreatationTest,
|
||||
SrtpTransportTestWithMediaType,
|
||||
::testing::Values(cricket::MEDIA_TYPE_AUDIO,
|
||||
cricket::MEDIA_TYPE_VIDEO));
|
||||
|
||||
} // namespace webrtc
|
||||
Loading…
x
Reference in New Issue
Block a user