Revert of make the DtlsTransportWrapper inherit form DtlsTransportInternal (patchset #11 id:320001 of https://codereview.webrtc.org/2606123002/ )
Reason for revert:
Failed the memory check.
May need to fix the memory leak.
Original issue's description:
> make the DtlsTransportWrapper inherit form DtlsTransportInternal
>
> BUG=none
>
> Review-Url: https://codereview.webrtc.org/2606123002
> Cr-Commit-Position: refs/heads/master@{#16160}
> Committed: 5aed06c8d3
TBR=deadbeef@webrtc.org,pthatcher@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=none
Review-Url: https://codereview.webrtc.org/2639203004
Cr-Commit-Position: refs/heads/master@{#16162}
This commit is contained in:
parent
daeffb299b
commit
6ce9259cb0
@ -64,8 +64,8 @@ class RtpSenderReceiverTest : public testing::Test {
|
||||
channel_manager_.Init();
|
||||
bool rtcp_mux_required = true;
|
||||
bool srtp_required = true;
|
||||
cricket::DtlsTransportInternal* rtp_transport =
|
||||
fake_transport_controller_.CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
fake_transport_controller_.CreateTransportChannel(
|
||||
cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
voice_channel_ = channel_manager_.CreateVoiceChannel(
|
||||
&fake_media_controller_, rtp_transport, nullptr, rtc::Thread::Current(),
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include "webrtc/media/base/videocapturer.h"
|
||||
#include "webrtc/media/sctp/sctptransportinternal.h"
|
||||
#include "webrtc/p2p/base/portallocator.h"
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
#include "webrtc/pc/channel.h"
|
||||
#include "webrtc/pc/channelmanager.h"
|
||||
#include "webrtc/pc/mediasession.h"
|
||||
@ -1081,25 +1082,25 @@ bool WebRtcSession::EnableBundle(const cricket::ContentGroup& bundle) {
|
||||
return true;
|
||||
}
|
||||
|
||||
cricket::DtlsTransportInternal* rtp_dtls_transport =
|
||||
transport_controller_->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller_->CreateTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
bool need_rtcp = (ch->rtcp_dtls_transport() != nullptr);
|
||||
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
|
||||
bool need_rtcp = (ch->rtcp_transport() != nullptr);
|
||||
cricket::TransportChannel* rtcp_transport = nullptr;
|
||||
if (need_rtcp) {
|
||||
rtcp_dtls_transport = transport_controller_->CreateDtlsTransport_n(
|
||||
rtcp_transport = transport_controller_->CreateTransportChannel_n(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
|
||||
ch->SetTransports(rtp_dtls_transport, rtcp_dtls_transport);
|
||||
ch->SetTransports(rtp_transport, rtcp_transport);
|
||||
LOG(LS_INFO) << "Enabled BUNDLE for " << ch->content_name() << " on "
|
||||
<< transport_name << ".";
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
old_transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
// If the channel needs rtcp, it means that the channel used to have a
|
||||
// rtcp transport which needs to be deleted now.
|
||||
if (need_rtcp) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
old_transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
return true;
|
||||
@ -1788,24 +1789,24 @@ bool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content,
|
||||
std::string transport_name =
|
||||
bundle_transport ? *bundle_transport : content->name;
|
||||
|
||||
cricket::DtlsTransportInternal* rtp_dtls_transport =
|
||||
transport_controller_->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller_->CreateTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
|
||||
cricket::TransportChannel* rtcp_transport = nullptr;
|
||||
if (!require_rtcp_mux) {
|
||||
rtcp_dtls_transport = transport_controller_->CreateDtlsTransport(
|
||||
rtcp_transport = transport_controller_->CreateTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
|
||||
voice_channel_.reset(channel_manager_->CreateVoiceChannel(
|
||||
media_controller_, rtp_dtls_transport, rtcp_dtls_transport,
|
||||
media_controller_, rtp_transport, rtcp_transport,
|
||||
transport_controller_->signaling_thread(), content->name,
|
||||
bundle_transport, require_rtcp_mux, SrtpRequired(), audio_options_));
|
||||
if (!voice_channel_) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
if (rtcp_dtls_transport) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
if (rtcp_transport) {
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
}
|
||||
return false;
|
||||
@ -1830,25 +1831,25 @@ bool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content,
|
||||
std::string transport_name =
|
||||
bundle_transport ? *bundle_transport : content->name;
|
||||
|
||||
cricket::DtlsTransportInternal* rtp_dtls_transport =
|
||||
transport_controller_->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller_->CreateTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
|
||||
cricket::TransportChannel* rtcp_transport = nullptr;
|
||||
if (!require_rtcp_mux) {
|
||||
rtcp_dtls_transport = transport_controller_->CreateDtlsTransport(
|
||||
rtcp_transport = transport_controller_->CreateTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
|
||||
video_channel_.reset(channel_manager_->CreateVideoChannel(
|
||||
media_controller_, rtp_dtls_transport, rtcp_dtls_transport,
|
||||
media_controller_, rtp_transport, rtcp_transport,
|
||||
transport_controller_->signaling_thread(), content->name,
|
||||
bundle_transport, require_rtcp_mux, SrtpRequired(), video_options_));
|
||||
|
||||
if (!video_channel_) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
if (rtcp_dtls_transport) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
if (rtcp_transport) {
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
}
|
||||
return false;
|
||||
@ -1872,7 +1873,7 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content,
|
||||
#ifdef HAVE_QUIC
|
||||
if (data_channel_type_ == cricket::DCT_QUIC) {
|
||||
RTC_DCHECK(transport_controller_->quic());
|
||||
quic_data_transport_->SetTransports(transport_name);
|
||||
quic_data_transport_->SetTransport(transport_name);
|
||||
return true;
|
||||
}
|
||||
#endif // HAVE_QUIC
|
||||
@ -1895,25 +1896,25 @@ bool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content,
|
||||
|
||||
std::string transport_name =
|
||||
bundle_transport ? *bundle_transport : content->name;
|
||||
cricket::DtlsTransportInternal* rtp_dtls_transport =
|
||||
transport_controller_->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller_->CreateTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
|
||||
cricket::TransportChannel* rtcp_transport = nullptr;
|
||||
if (!require_rtcp_mux) {
|
||||
rtcp_dtls_transport = transport_controller_->CreateDtlsTransport(
|
||||
rtcp_transport = transport_controller_->CreateTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
|
||||
rtp_data_channel_.reset(channel_manager_->CreateRtpDataChannel(
|
||||
media_controller_, rtp_dtls_transport, rtcp_dtls_transport,
|
||||
media_controller_, rtp_transport, rtcp_transport,
|
||||
transport_controller_->signaling_thread(), content->name,
|
||||
bundle_transport, require_rtcp_mux, SrtpRequired()));
|
||||
|
||||
if (!rtp_data_channel_) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
if (rtcp_dtls_transport) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
if (rtcp_transport) {
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
}
|
||||
return false;
|
||||
@ -1958,8 +1959,8 @@ bool WebRtcSession::CreateSctpTransport_n(const std::string& content_name,
|
||||
const std::string& transport_name) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
RTC_DCHECK(sctp_factory_);
|
||||
cricket::DtlsTransportInternal* tc =
|
||||
transport_controller_->CreateDtlsTransport_n(
|
||||
cricket::TransportChannel* tc =
|
||||
transport_controller_->CreateTransportChannel_n(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
sctp_transport_ = sctp_factory_->CreateSctpTransport(tc);
|
||||
RTC_DCHECK(sctp_transport_);
|
||||
@ -1981,11 +1982,11 @@ void WebRtcSession::ChangeSctpTransport_n(const std::string& transport_name) {
|
||||
RTC_DCHECK(sctp_transport_name_);
|
||||
std::string old_sctp_transport_name = *sctp_transport_name_;
|
||||
sctp_transport_name_ = rtc::Optional<std::string>(transport_name);
|
||||
cricket::DtlsTransportInternal* tc =
|
||||
transport_controller_->CreateDtlsTransport_n(
|
||||
cricket::TransportChannel* tc =
|
||||
transport_controller_->CreateTransportChannel_n(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
sctp_transport_->SetTransportChannel(tc);
|
||||
transport_controller_->DestroyDtlsTransport_n(
|
||||
transport_controller_->DestroyTransportChannel_n(
|
||||
old_sctp_transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
}
|
||||
|
||||
@ -2382,52 +2383,51 @@ const std::string WebRtcSession::GetTransportName(
|
||||
|
||||
void WebRtcSession::DestroyRtcpTransport_n(const std::string& transport_name) {
|
||||
RTC_DCHECK(network_thread()->IsCurrent());
|
||||
transport_controller_->DestroyDtlsTransport_n(
|
||||
transport_controller_->DestroyTransportChannel_n(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
|
||||
void WebRtcSession::DestroyVideoChannel() {
|
||||
SignalVideoChannelDestroyed();
|
||||
RTC_DCHECK(video_channel_->rtp_dtls_transport());
|
||||
RTC_DCHECK(video_channel_->rtp_transport());
|
||||
std::string transport_name;
|
||||
transport_name = video_channel_->rtp_dtls_transport()->transport_name();
|
||||
bool need_to_delete_rtcp = (video_channel_->rtcp_dtls_transport() != nullptr);
|
||||
transport_name = video_channel_->rtp_transport()->transport_name();
|
||||
bool need_to_delete_rtcp = (video_channel_->rtcp_transport() != nullptr);
|
||||
channel_manager_->DestroyVideoChannel(video_channel_.release());
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
if (need_to_delete_rtcp) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSession::DestroyVoiceChannel() {
|
||||
SignalVoiceChannelDestroyed();
|
||||
RTC_DCHECK(voice_channel_->rtp_dtls_transport());
|
||||
RTC_DCHECK(voice_channel_->rtp_transport());
|
||||
std::string transport_name;
|
||||
transport_name = voice_channel_->rtp_dtls_transport()->transport_name();
|
||||
bool need_to_delete_rtcp = (voice_channel_->rtcp_dtls_transport() != nullptr);
|
||||
transport_name = voice_channel_->rtp_transport()->transport_name();
|
||||
bool need_to_delete_rtcp = (voice_channel_->rtcp_transport() != nullptr);
|
||||
channel_manager_->DestroyVoiceChannel(voice_channel_.release());
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
if (need_to_delete_rtcp) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
}
|
||||
|
||||
void WebRtcSession::DestroyDataChannel() {
|
||||
SignalDataChannelDestroyed();
|
||||
RTC_DCHECK(rtp_data_channel_->rtp_dtls_transport());
|
||||
RTC_DCHECK(rtp_data_channel_->rtp_transport());
|
||||
std::string transport_name;
|
||||
transport_name = rtp_data_channel_->rtp_dtls_transport()->transport_name();
|
||||
bool need_to_delete_rtcp =
|
||||
(rtp_data_channel_->rtcp_dtls_transport() != nullptr);
|
||||
transport_name = rtp_data_channel_->rtp_transport()->transport_name();
|
||||
bool need_to_delete_rtcp = (rtp_data_channel_->rtcp_transport() != nullptr);
|
||||
channel_manager_->DestroyRtpDataChannel(rtp_data_channel_.release());
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
if (need_to_delete_rtcp) {
|
||||
transport_controller_->DestroyDtlsTransport(
|
||||
transport_controller_->DestroyTransportChannel(
|
||||
transport_name, cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "webrtc/p2p/base/stunserver.h"
|
||||
#include "webrtc/p2p/base/teststunserver.h"
|
||||
#include "webrtc/p2p/base/testturnserver.h"
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
#include "webrtc/p2p/client/basicportallocator.h"
|
||||
#include "webrtc/pc/channelmanager.h"
|
||||
#include "webrtc/pc/mediasession.h"
|
||||
@ -218,7 +219,7 @@ class MockIceObserver : public webrtc::IceObserver {
|
||||
// local/remote ports.
|
||||
class FakeSctpTransport : public cricket::SctpTransportInternal {
|
||||
public:
|
||||
void SetTransportChannel(rtc::PacketTransportInterface* channel) override {}
|
||||
void SetTransportChannel(cricket::TransportChannel* channel) override {}
|
||||
bool Start(int local_port, int remote_port) override {
|
||||
local_port_ = local_port;
|
||||
remote_port_ = remote_port;
|
||||
@ -245,7 +246,7 @@ class FakeSctpTransport : public cricket::SctpTransportInternal {
|
||||
class FakeSctpTransportFactory : public cricket::SctpTransportInternalFactory {
|
||||
public:
|
||||
std::unique_ptr<cricket::SctpTransportInternal> CreateSctpTransport(
|
||||
rtc::PacketTransportInterface*) override {
|
||||
cricket::TransportChannel*) override {
|
||||
last_fake_sctp_transport_ = new FakeSctpTransport();
|
||||
return std::unique_ptr<cricket::SctpTransportInternal>(
|
||||
last_fake_sctp_transport_);
|
||||
@ -305,7 +306,7 @@ class WebRtcSessionForTest : public webrtc::WebRtcSession {
|
||||
if (!ch) {
|
||||
return nullptr;
|
||||
}
|
||||
return ch->rtp_dtls_transport();
|
||||
return ch->rtp_transport();
|
||||
}
|
||||
|
||||
rtc::PacketTransportInterface* rtcp_transport_channel(
|
||||
@ -313,7 +314,7 @@ class WebRtcSessionForTest : public webrtc::WebRtcSession {
|
||||
if (!ch) {
|
||||
return nullptr;
|
||||
}
|
||||
return ch->rtcp_dtls_transport();
|
||||
return ch->rtcp_transport();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -39,7 +39,6 @@ enum PreservedErrno {
|
||||
#include "webrtc/media/base/mediaconstants.h"
|
||||
#include "webrtc/media/base/rtputils.h" // For IsRtpPacket
|
||||
#include "webrtc/media/base/streamparams.h"
|
||||
#include "webrtc/p2p/base/dtlstransportinternal.h" // For PF_NORMAL
|
||||
|
||||
namespace {
|
||||
|
||||
@ -385,7 +384,7 @@ class SctpTransport::UsrSctpWrapper {
|
||||
};
|
||||
|
||||
SctpTransport::SctpTransport(rtc::Thread* network_thread,
|
||||
rtc::PacketTransportInterface* channel)
|
||||
TransportChannel* channel)
|
||||
: network_thread_(network_thread),
|
||||
transport_channel_(channel),
|
||||
was_ever_writable_(channel->writable()) {
|
||||
@ -400,8 +399,7 @@ SctpTransport::~SctpTransport() {
|
||||
CloseSctpSocket();
|
||||
}
|
||||
|
||||
void SctpTransport::SetTransportChannel(
|
||||
rtc::PacketTransportInterface* channel) {
|
||||
void SctpTransport::SetTransportChannel(cricket::TransportChannel* channel) {
|
||||
RTC_DCHECK_RUN_ON(network_thread_);
|
||||
RTC_DCHECK(channel);
|
||||
DisconnectTransportChannelSignals();
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
// For SendDataParams/ReceiveDataParams.
|
||||
#include "webrtc/media/base/mediachannel.h"
|
||||
#include "webrtc/media/sctp/sctptransportinternal.h"
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
|
||||
// Defined by "usrsctplib/usrsctp.h"
|
||||
struct sockaddr_conn;
|
||||
@ -58,7 +59,6 @@ struct SctpInboundPacket;
|
||||
// 12. SctpTransport::SignalDataReceived(data)
|
||||
// [from the same thread, methods registered/connected to
|
||||
// SctpTransport are called with the recieved data]
|
||||
// TODO(zhihuang): Rename "channel" to "transport" on network-level.
|
||||
class SctpTransport : public SctpTransportInternal,
|
||||
public sigslot::has_slots<> {
|
||||
public:
|
||||
@ -67,11 +67,11 @@ class SctpTransport : public SctpTransportInternal,
|
||||
// methods can be called.
|
||||
// |channel| is required (must not be null).
|
||||
SctpTransport(rtc::Thread* network_thread,
|
||||
rtc::PacketTransportInterface* channel);
|
||||
cricket::TransportChannel* channel);
|
||||
~SctpTransport() override;
|
||||
|
||||
// SctpTransportInternal overrides (see sctptransportinternal.h for comments).
|
||||
void SetTransportChannel(rtc::PacketTransportInterface* channel) override;
|
||||
void SetTransportChannel(cricket::TransportChannel* channel) override;
|
||||
bool Start(int local_port, int remote_port) override;
|
||||
bool OpenStream(int sid) override;
|
||||
bool ResetStream(int sid) override;
|
||||
@ -140,7 +140,7 @@ class SctpTransport : public SctpTransportInternal,
|
||||
// Helps pass inbound/outbound packets asynchronously to the network thread.
|
||||
rtc::AsyncInvoker invoker_;
|
||||
// Underlying DTLS channel.
|
||||
rtc::PacketTransportInterface* transport_channel_;
|
||||
TransportChannel* transport_channel_;
|
||||
bool was_ever_writable_ = false;
|
||||
int local_port_ = kSctpDefaultPort;
|
||||
int remote_port_ = kSctpDefaultPort;
|
||||
@ -179,7 +179,7 @@ class SctpTransportFactory : public SctpTransportInternalFactory {
|
||||
: network_thread_(network_thread) {}
|
||||
|
||||
std::unique_ptr<SctpTransportInternal> CreateSctpTransport(
|
||||
rtc::PacketTransportInterface* channel) override {
|
||||
TransportChannel* channel) override {
|
||||
return std::unique_ptr<SctpTransportInternal>(
|
||||
new SctpTransport(network_thread_, channel));
|
||||
}
|
||||
|
||||
@ -130,8 +130,8 @@ class SctpTransportTest : public testing::Test, public sigslot::has_slots<> {
|
||||
static void SetUpTestCase() {}
|
||||
|
||||
void SetupConnectedTransportsWithTwoStreams() {
|
||||
fake_dtls1_.reset(new FakeDtlsTransport("fake dtls 1", 0));
|
||||
fake_dtls2_.reset(new FakeDtlsTransport("fake dtls 2", 0));
|
||||
fake_dtls1_.reset(new FakeTransportChannel("fake dtls 1", 0));
|
||||
fake_dtls2_.reset(new FakeTransportChannel("fake dtls 2", 0));
|
||||
recv1_.reset(new SctpFakeDataReceiver());
|
||||
recv2_.reset(new SctpFakeDataReceiver());
|
||||
transport1_.reset(CreateTransport(fake_dtls1_.get(), recv1_.get()));
|
||||
@ -164,7 +164,7 @@ class SctpTransportTest : public testing::Test, public sigslot::has_slots<> {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SctpTransport* CreateTransport(FakeDtlsTransport* fake_dtls,
|
||||
SctpTransport* CreateTransport(FakeTransportChannel* fake_dtls,
|
||||
SctpFakeDataReceiver* recv) {
|
||||
SctpTransport* transport =
|
||||
new SctpTransport(rtc::Thread::Current(), fake_dtls);
|
||||
@ -207,8 +207,8 @@ class SctpTransportTest : public testing::Test, public sigslot::has_slots<> {
|
||||
SctpTransport* transport2() { return transport2_.get(); }
|
||||
SctpFakeDataReceiver* receiver1() { return recv1_.get(); }
|
||||
SctpFakeDataReceiver* receiver2() { return recv2_.get(); }
|
||||
FakeDtlsTransport* fake_dtls1() { return fake_dtls1_.get(); }
|
||||
FakeDtlsTransport* fake_dtls2() { return fake_dtls2_.get(); }
|
||||
FakeTransportChannel* fake_dtls1() { return fake_dtls1_.get(); }
|
||||
FakeTransportChannel* fake_dtls2() { return fake_dtls2_.get(); }
|
||||
|
||||
int transport1_ready_to_send_count() {
|
||||
return transport1_ready_to_send_count_;
|
||||
@ -218,8 +218,8 @@ class SctpTransportTest : public testing::Test, public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<FakeDtlsTransport> fake_dtls1_;
|
||||
std::unique_ptr<FakeDtlsTransport> fake_dtls2_;
|
||||
std::unique_ptr<FakeTransportChannel> fake_dtls1_;
|
||||
std::unique_ptr<FakeTransportChannel> fake_dtls2_;
|
||||
std::unique_ptr<SctpFakeDataReceiver> recv1_;
|
||||
std::unique_ptr<SctpFakeDataReceiver> recv2_;
|
||||
std::unique_ptr<SctpTransport> transport1_;
|
||||
@ -236,9 +236,9 @@ class SctpTransportTest : public testing::Test, public sigslot::has_slots<> {
|
||||
// transport channel (which is unwritable), and then switches to another
|
||||
// channel. A common scenario due to how BUNDLE works.
|
||||
TEST_F(SctpTransportTest, SwitchTransportChannel) {
|
||||
FakeDtlsTransport black_hole("black hole", 0);
|
||||
FakeDtlsTransport fake_dtls1("fake dtls 1", 0);
|
||||
FakeDtlsTransport fake_dtls2("fake dtls 2", 0);
|
||||
FakeTransportChannel black_hole("black hole", 0);
|
||||
FakeTransportChannel fake_dtls1("fake dtls 1", 0);
|
||||
FakeTransportChannel fake_dtls2("fake dtls 2", 0);
|
||||
SctpFakeDataReceiver recv1;
|
||||
SctpFakeDataReceiver recv2;
|
||||
|
||||
@ -294,8 +294,8 @@ TEST_F(SctpTransportTest, CallingStartWithDifferentPortFails) {
|
||||
// A value of -1 for the local/remote port should be treated as the default
|
||||
// (5000).
|
||||
TEST_F(SctpTransportTest, NegativeOnePortTreatedAsDefault) {
|
||||
FakeDtlsTransport fake_dtls1("fake dtls 1", 0);
|
||||
FakeDtlsTransport fake_dtls2("fake dtls 2", 0);
|
||||
FakeTransportChannel fake_dtls1("fake dtls 1", 0);
|
||||
FakeTransportChannel fake_dtls2("fake dtls 2", 0);
|
||||
SctpFakeDataReceiver recv1;
|
||||
SctpFakeDataReceiver recv2;
|
||||
std::unique_ptr<SctpTransport> transport1(
|
||||
@ -325,7 +325,7 @@ TEST_F(SctpTransportTest, NegativeOnePortTreatedAsDefault) {
|
||||
}
|
||||
|
||||
TEST_F(SctpTransportTest, OpenStreamWithAlreadyOpenedStreamFails) {
|
||||
FakeDtlsTransport fake_dtls("fake dtls", 0);
|
||||
FakeTransportChannel fake_dtls("fake dtls", 0);
|
||||
SctpFakeDataReceiver recv;
|
||||
std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
|
||||
EXPECT_TRUE(transport->OpenStream(1));
|
||||
@ -333,7 +333,7 @@ TEST_F(SctpTransportTest, OpenStreamWithAlreadyOpenedStreamFails) {
|
||||
}
|
||||
|
||||
TEST_F(SctpTransportTest, ResetStreamWithAlreadyResetStreamFails) {
|
||||
FakeDtlsTransport fake_dtls("fake dtls", 0);
|
||||
FakeTransportChannel fake_dtls("fake dtls", 0);
|
||||
SctpFakeDataReceiver recv;
|
||||
std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
|
||||
EXPECT_TRUE(transport->OpenStream(1));
|
||||
@ -344,7 +344,7 @@ TEST_F(SctpTransportTest, ResetStreamWithAlreadyResetStreamFails) {
|
||||
// Test that SignalReadyToSendData is fired after Start has been called and the
|
||||
// DTLS channel is writable.
|
||||
TEST_F(SctpTransportTest, SignalReadyToSendDataAfterDtlsWritable) {
|
||||
FakeDtlsTransport fake_dtls("fake dtls", 0);
|
||||
FakeTransportChannel fake_dtls("fake dtls", 0);
|
||||
SctpFakeDataReceiver recv;
|
||||
std::unique_ptr<SctpTransport> transport(CreateTransport(&fake_dtls, &recv));
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
// TODO(deadbeef): Use something else for SCTP. It's confusing that we use an
|
||||
// SSRC field for SID.
|
||||
#include "webrtc/media/base/mediachannel.h"
|
||||
#include "webrtc/p2p/base/packettransportinterface.h"
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
@ -58,7 +58,7 @@ class SctpTransportInternal {
|
||||
// Changes what underlying DTLS channel is uses. Used when switching which
|
||||
// bundled transport the SctpTransport uses.
|
||||
// Assumes |channel| is non-null.
|
||||
virtual void SetTransportChannel(rtc::PacketTransportInterface* channel) = 0;
|
||||
virtual void SetTransportChannel(TransportChannel* channel) = 0;
|
||||
|
||||
// When Start is called, connects as soon as possible; this can be called
|
||||
// before DTLS completes, in which case the connection will begin when DTLS
|
||||
@ -129,7 +129,7 @@ class SctpTransportInternalFactory {
|
||||
|
||||
// Create an SCTP transport using |channel| for the underlying transport.
|
||||
virtual std::unique_ptr<SctpTransportInternal> CreateSctpTransport(
|
||||
rtc::PacketTransportInterface* channel) = 0;
|
||||
TransportChannel* channel) = 0;
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -61,6 +61,9 @@ rtc_static_library("rtc_p2p") {
|
||||
"base/tcpport.cc",
|
||||
"base/tcpport.h",
|
||||
"base/transport.h",
|
||||
"base/transportchannel.cc",
|
||||
"base/transportchannel.h",
|
||||
"base/transportchannelimpl.h",
|
||||
"base/transportcontroller.cc",
|
||||
"base/transportcontroller.h",
|
||||
"base/transportdescription.cc",
|
||||
|
||||
@ -50,9 +50,8 @@ static bool IsRtpPacket(const char* data, size_t len) {
|
||||
return (len >= kMinRtpPacketLen && (u[0] & 0xC0) == 0x80);
|
||||
}
|
||||
|
||||
StreamInterfaceChannel::StreamInterfaceChannel(
|
||||
IceTransportInternal* ice_transport)
|
||||
: ice_transport_(ice_transport),
|
||||
StreamInterfaceChannel::StreamInterfaceChannel(IceTransportInternal* channel)
|
||||
: channel_(channel),
|
||||
state_(rtc::SS_OPEN),
|
||||
packets_(kMaxPendingPackets, kMaxDtlsPacketLen) {}
|
||||
|
||||
@ -77,11 +76,10 @@ rtc::StreamResult StreamInterfaceChannel::Write(const void* data,
|
||||
size_t* written,
|
||||
int* error) {
|
||||
// Always succeeds, since this is an unreliable transport anyway.
|
||||
// TODO(zhihuang): Should this block if ice_transport_'s temporarily
|
||||
// unwritable?
|
||||
// TODO: Should this block if channel_'s temporarily unwritable?
|
||||
rtc::PacketOptions packet_options;
|
||||
ice_transport_->SendPacket(static_cast<const char*>(data), data_len,
|
||||
packet_options);
|
||||
channel_->SendPacket(static_cast<const char*>(data), data_len,
|
||||
packet_options);
|
||||
if (written) {
|
||||
*written = data_len;
|
||||
}
|
||||
@ -103,27 +101,44 @@ void StreamInterfaceChannel::Close() {
|
||||
state_ = rtc::SS_CLOSED;
|
||||
}
|
||||
|
||||
DtlsTransport::DtlsTransport(IceTransportInternal* ice_transport)
|
||||
: transport_name_(ice_transport->transport_name()),
|
||||
component_(ice_transport->component()),
|
||||
DtlsTransportChannelWrapper::DtlsTransportChannelWrapper(
|
||||
IceTransportInternal* channel)
|
||||
: TransportChannelImpl(channel->transport_name(), channel->component()),
|
||||
network_thread_(rtc::Thread::Current()),
|
||||
ice_transport_(ice_transport),
|
||||
channel_(channel),
|
||||
downward_(NULL),
|
||||
ssl_role_(rtc::SSL_CLIENT),
|
||||
ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_12) {
|
||||
ice_transport_->SignalWritableState.connect(this,
|
||||
&DtlsTransport::OnWritableState);
|
||||
ice_transport_->SignalReadPacket.connect(this, &DtlsTransport::OnReadPacket);
|
||||
ice_transport_->SignalSentPacket.connect(this, &DtlsTransport::OnSentPacket);
|
||||
ice_transport_->SignalReadyToSend.connect(this,
|
||||
&DtlsTransport::OnReadyToSend);
|
||||
ice_transport_->SignalReceivingState.connect(
|
||||
this, &DtlsTransport::OnReceivingState);
|
||||
channel_->SignalWritableState.connect(this,
|
||||
&DtlsTransportChannelWrapper::OnWritableState);
|
||||
channel_->SignalReadPacket.connect(this,
|
||||
&DtlsTransportChannelWrapper::OnReadPacket);
|
||||
channel_->SignalSentPacket.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnSentPacket);
|
||||
channel_->SignalReadyToSend.connect(this,
|
||||
&DtlsTransportChannelWrapper::OnReadyToSend);
|
||||
channel_->SignalGatheringState.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnGatheringState);
|
||||
channel_->SignalCandidateGathered.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnCandidateGathered);
|
||||
channel_->SignalCandidatesRemoved.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnCandidatesRemoved);
|
||||
channel_->SignalRoleConflict.connect(this,
|
||||
&DtlsTransportChannelWrapper::OnRoleConflict);
|
||||
channel_->SignalRouteChange.connect(this,
|
||||
&DtlsTransportChannelWrapper::OnRouteChange);
|
||||
channel_->SignalSelectedCandidatePairChanged.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnSelectedCandidatePairChanged);
|
||||
channel_->SignalStateChanged.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnChannelStateChanged);
|
||||
channel_->SignalReceivingState.connect(this,
|
||||
&DtlsTransportChannelWrapper::OnReceivingState);
|
||||
}
|
||||
|
||||
DtlsTransport::~DtlsTransport() {}
|
||||
DtlsTransportChannelWrapper::~DtlsTransportChannelWrapper() {
|
||||
}
|
||||
|
||||
bool DtlsTransport::SetLocalCertificate(
|
||||
bool DtlsTransportChannelWrapper::SetLocalCertificate(
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) {
|
||||
if (dtls_active_) {
|
||||
if (certificate == local_certificate_) {
|
||||
@ -146,12 +161,13 @@ bool DtlsTransport::SetLocalCertificate(
|
||||
return true;
|
||||
}
|
||||
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> DtlsTransport::GetLocalCertificate()
|
||||
const {
|
||||
rtc::scoped_refptr<rtc::RTCCertificate>
|
||||
DtlsTransportChannelWrapper::GetLocalCertificate() const {
|
||||
return local_certificate_;
|
||||
}
|
||||
|
||||
bool DtlsTransport::SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) {
|
||||
bool DtlsTransportChannelWrapper::SetSslMaxProtocolVersion(
|
||||
rtc::SSLProtocolVersion version) {
|
||||
if (dtls_active_) {
|
||||
LOG(LS_ERROR) << "Not changing max. protocol version "
|
||||
<< "while DTLS is negotiating";
|
||||
@ -162,7 +178,7 @@ bool DtlsTransport::SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransport::SetSslRole(rtc::SSLRole role) {
|
||||
bool DtlsTransportChannelWrapper::SetSslRole(rtc::SSLRole role) {
|
||||
if (dtls_) {
|
||||
if (ssl_role_ != role) {
|
||||
LOG(LS_ERROR) << "SSL Role can't be reversed after the session is setup.";
|
||||
@ -175,12 +191,12 @@ bool DtlsTransport::SetSslRole(rtc::SSLRole role) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransport::GetSslRole(rtc::SSLRole* role) const {
|
||||
bool DtlsTransportChannelWrapper::GetSslRole(rtc::SSLRole* role) const {
|
||||
*role = ssl_role_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransport::GetSslCipherSuite(int* cipher) {
|
||||
bool DtlsTransportChannelWrapper::GetSslCipherSuite(int* cipher) {
|
||||
if (dtls_state() != DTLS_TRANSPORT_CONNECTED) {
|
||||
return false;
|
||||
}
|
||||
@ -188,9 +204,10 @@ bool DtlsTransport::GetSslCipherSuite(int* cipher) {
|
||||
return dtls_->GetSslCipherSuite(cipher);
|
||||
}
|
||||
|
||||
bool DtlsTransport::SetRemoteFingerprint(const std::string& digest_alg,
|
||||
const uint8_t* digest,
|
||||
size_t digest_len) {
|
||||
bool DtlsTransportChannelWrapper::SetRemoteFingerprint(
|
||||
const std::string& digest_alg,
|
||||
const uint8_t* digest,
|
||||
size_t digest_len) {
|
||||
rtc::Buffer remote_fingerprint_value(digest, digest_len);
|
||||
|
||||
// Once we have the local certificate, the same remote fingerprint can be set
|
||||
@ -258,8 +275,8 @@ bool DtlsTransport::SetRemoteFingerprint(const std::string& digest_alg,
|
||||
return true;
|
||||
}
|
||||
|
||||
std::unique_ptr<rtc::SSLCertificate> DtlsTransport::GetRemoteSSLCertificate()
|
||||
const {
|
||||
std::unique_ptr<rtc::SSLCertificate>
|
||||
DtlsTransportChannelWrapper::GetRemoteSSLCertificate() const {
|
||||
if (!dtls_) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -267,8 +284,8 @@ std::unique_ptr<rtc::SSLCertificate> DtlsTransport::GetRemoteSSLCertificate()
|
||||
return dtls_->GetPeerCertificate();
|
||||
}
|
||||
|
||||
bool DtlsTransport::SetupDtls() {
|
||||
StreamInterfaceChannel* downward = new StreamInterfaceChannel(ice_transport_);
|
||||
bool DtlsTransportChannelWrapper::SetupDtls() {
|
||||
StreamInterfaceChannel* downward = new StreamInterfaceChannel(channel_);
|
||||
|
||||
dtls_.reset(rtc::SSLStreamAdapter::Create(downward));
|
||||
if (!dtls_) {
|
||||
@ -283,9 +300,9 @@ bool DtlsTransport::SetupDtls() {
|
||||
dtls_->SetMode(rtc::SSL_MODE_DTLS);
|
||||
dtls_->SetMaxProtocolVersion(ssl_max_version_);
|
||||
dtls_->SetServerRole(ssl_role_);
|
||||
dtls_->SignalEvent.connect(this, &DtlsTransport::OnDtlsEvent);
|
||||
dtls_->SignalSSLHandshakeError.connect(this,
|
||||
&DtlsTransport::OnDtlsHandshakeError);
|
||||
dtls_->SignalEvent.connect(this, &DtlsTransportChannelWrapper::OnDtlsEvent);
|
||||
dtls_->SignalSSLHandshakeError.connect(
|
||||
this, &DtlsTransportChannelWrapper::OnDtlsHandshakeError);
|
||||
if (remote_fingerprint_value_.size() &&
|
||||
!dtls_->SetPeerCertificateDigest(
|
||||
remote_fingerprint_algorithm_,
|
||||
@ -307,13 +324,14 @@ bool DtlsTransport::SetupDtls() {
|
||||
|
||||
LOG_J(LS_INFO, this) << "DTLS setup complete.";
|
||||
|
||||
// If the underlying ice_transport is already writable at this point, we may
|
||||
// be able to start DTLS right away.
|
||||
// If the underlying channel is already writable at this point, we may be
|
||||
// able to start DTLS right away.
|
||||
MaybeStartDtls();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransport::SetSrtpCryptoSuites(const std::vector<int>& ciphers) {
|
||||
bool DtlsTransportChannelWrapper::SetSrtpCryptoSuites(
|
||||
const std::vector<int>& ciphers) {
|
||||
if (srtp_ciphers_ == ciphers)
|
||||
return true;
|
||||
|
||||
@ -328,8 +346,7 @@ bool DtlsTransport::SetSrtpCryptoSuites(const std::vector<int>& ciphers) {
|
||||
// So for now, let's be happy (or sad) with a warning message.
|
||||
int current_srtp_cipher;
|
||||
if (!dtls_->GetDtlsSrtpCryptoSuite(¤t_srtp_cipher)) {
|
||||
LOG(LS_ERROR)
|
||||
<< "Failed to get the current SRTP cipher for DTLS transport";
|
||||
LOG(LS_ERROR) << "Failed to get the current SRTP cipher for DTLS channel";
|
||||
return false;
|
||||
}
|
||||
const std::vector<int>::const_iterator iter =
|
||||
@ -357,7 +374,7 @@ bool DtlsTransport::SetSrtpCryptoSuites(const std::vector<int>& ciphers) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DtlsTransport::GetSrtpCryptoSuite(int* cipher) {
|
||||
bool DtlsTransportChannelWrapper::GetSrtpCryptoSuite(int* cipher) {
|
||||
if (dtls_state() != DTLS_TRANSPORT_CONNECTED) {
|
||||
return false;
|
||||
}
|
||||
@ -367,13 +384,12 @@ bool DtlsTransport::GetSrtpCryptoSuite(int* cipher) {
|
||||
|
||||
|
||||
// Called from upper layers to send a media packet.
|
||||
int DtlsTransport::SendPacket(const char* data,
|
||||
size_t size,
|
||||
const rtc::PacketOptions& options,
|
||||
int flags) {
|
||||
int DtlsTransportChannelWrapper::SendPacket(
|
||||
const char* data, size_t size,
|
||||
const rtc::PacketOptions& options, int flags) {
|
||||
if (!dtls_active_) {
|
||||
// Not doing DTLS.
|
||||
return ice_transport_->SendPacket(data, size, options);
|
||||
return channel_->SendPacket(data, size, options);
|
||||
}
|
||||
|
||||
switch (dtls_state()) {
|
||||
@ -391,7 +407,7 @@ int DtlsTransport::SendPacket(const char* data,
|
||||
return -1;
|
||||
}
|
||||
|
||||
return ice_transport_->SendPacket(data, size, options);
|
||||
return channel_->SendPacket(data, size, options);
|
||||
} else {
|
||||
return (dtls_->WriteAll(data, size, NULL, NULL) == rtc::SR_SUCCESS)
|
||||
? static_cast<int>(size)
|
||||
@ -407,7 +423,7 @@ int DtlsTransport::SendPacket(const char* data,
|
||||
}
|
||||
}
|
||||
|
||||
bool DtlsTransport::IsDtlsConnected() {
|
||||
bool DtlsTransportChannelWrapper::IsDtlsConnected() {
|
||||
return dtls_ && dtls_->IsTlsConnected();
|
||||
}
|
||||
|
||||
@ -421,17 +437,18 @@ bool DtlsTransport::IsDtlsConnected() {
|
||||
// start the DTLS handshake
|
||||
// - Once the DTLS handshake completes, the state is that of the
|
||||
// impl again
|
||||
void DtlsTransport::OnWritableState(rtc::PacketTransportInterface* transport) {
|
||||
void DtlsTransportChannelWrapper::OnWritableState(
|
||||
rtc::PacketTransportInterface* transport) {
|
||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||
RTC_DCHECK(transport == ice_transport_);
|
||||
RTC_DCHECK(transport == channel_);
|
||||
LOG_J(LS_VERBOSE, this)
|
||||
<< "DTLSTransportChannelWrapper: ice_transport writable state changed to "
|
||||
<< ice_transport_->writable();
|
||||
<< "DTLSTransportChannelWrapper: channel writable state changed to "
|
||||
<< channel_->writable();
|
||||
|
||||
if (!dtls_active_) {
|
||||
// Not doing DTLS.
|
||||
// Note: SignalWritableState fired by set_writable.
|
||||
set_writable(ice_transport_->writable());
|
||||
set_writable(channel_->writable());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -441,7 +458,7 @@ void DtlsTransport::OnWritableState(rtc::PacketTransportInterface* transport) {
|
||||
break;
|
||||
case DTLS_TRANSPORT_CONNECTED:
|
||||
// Note: SignalWritableState fired by set_writable.
|
||||
set_writable(ice_transport_->writable());
|
||||
set_writable(channel_->writable());
|
||||
break;
|
||||
case DTLS_TRANSPORT_CONNECTING:
|
||||
// Do nothing.
|
||||
@ -453,25 +470,27 @@ void DtlsTransport::OnWritableState(rtc::PacketTransportInterface* transport) {
|
||||
}
|
||||
}
|
||||
|
||||
void DtlsTransport::OnReceivingState(rtc::PacketTransportInterface* transport) {
|
||||
void DtlsTransportChannelWrapper::OnReceivingState(
|
||||
rtc::PacketTransportInterface* transport) {
|
||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||
RTC_DCHECK(transport == ice_transport_);
|
||||
LOG_J(LS_VERBOSE, this) << "DTLSTransportChannelWrapper: ice_transport "
|
||||
"receiving state changed to "
|
||||
<< ice_transport_->receiving();
|
||||
RTC_DCHECK(transport == channel_);
|
||||
LOG_J(LS_VERBOSE, this)
|
||||
<< "DTLSTransportChannelWrapper: channel receiving state changed to "
|
||||
<< channel_->receiving();
|
||||
if (!dtls_active_ || dtls_state() == DTLS_TRANSPORT_CONNECTED) {
|
||||
// Note: SignalReceivingState fired by set_receiving.
|
||||
set_receiving(ice_transport_->receiving());
|
||||
set_receiving(channel_->receiving());
|
||||
}
|
||||
}
|
||||
|
||||
void DtlsTransport::OnReadPacket(rtc::PacketTransportInterface* transport,
|
||||
const char* data,
|
||||
size_t size,
|
||||
const rtc::PacketTime& packet_time,
|
||||
int flags) {
|
||||
void DtlsTransportChannelWrapper::OnReadPacket(
|
||||
rtc::PacketTransportInterface* transport,
|
||||
const char* data,
|
||||
size_t size,
|
||||
const rtc::PacketTime& packet_time,
|
||||
int flags) {
|
||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||
RTC_DCHECK(transport == ice_transport_);
|
||||
RTC_DCHECK(transport == channel_);
|
||||
RTC_DCHECK(flags == 0);
|
||||
|
||||
if (!dtls_active_) {
|
||||
@ -543,20 +562,23 @@ void DtlsTransport::OnReadPacket(rtc::PacketTransportInterface* transport,
|
||||
}
|
||||
}
|
||||
|
||||
void DtlsTransport::OnSentPacket(rtc::PacketTransportInterface* transport,
|
||||
const rtc::SentPacket& sent_packet) {
|
||||
void DtlsTransportChannelWrapper::OnSentPacket(
|
||||
rtc::PacketTransportInterface* transport,
|
||||
const rtc::SentPacket& sent_packet) {
|
||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||
|
||||
SignalSentPacket(this, sent_packet);
|
||||
}
|
||||
|
||||
void DtlsTransport::OnReadyToSend(rtc::PacketTransportInterface* transport) {
|
||||
void DtlsTransportChannelWrapper::OnReadyToSend(
|
||||
rtc::PacketTransportInterface* transport) {
|
||||
if (writable()) {
|
||||
SignalReadyToSend(this);
|
||||
}
|
||||
}
|
||||
|
||||
void DtlsTransport::OnDtlsEvent(rtc::StreamInterface* dtls, int sig, int err) {
|
||||
void DtlsTransportChannelWrapper::OnDtlsEvent(rtc::StreamInterface* dtls,
|
||||
int sig, int err) {
|
||||
RTC_DCHECK(rtc::Thread::Current() == network_thread_);
|
||||
RTC_DCHECK(dtls == dtls_.get());
|
||||
if (sig & rtc::SE_OPEN) {
|
||||
@ -578,12 +600,12 @@ void DtlsTransport::OnDtlsEvent(rtc::StreamInterface* dtls, int sig, int err) {
|
||||
SignalReadPacket(this, buf, read, rtc::CreatePacketTime(0), 0);
|
||||
} else if (ret == rtc::SR_EOS) {
|
||||
// Remote peer shut down the association with no error.
|
||||
LOG_J(LS_INFO, this) << "DTLS transport closed";
|
||||
LOG_J(LS_INFO, this) << "DTLS channel closed";
|
||||
set_writable(false);
|
||||
set_dtls_state(DTLS_TRANSPORT_CLOSED);
|
||||
} else if (ret == rtc::SR_ERROR) {
|
||||
// Remote peer shut down the association with an error.
|
||||
LOG_J(LS_INFO, this) << "DTLS transport error, code=" << read_error;
|
||||
LOG_J(LS_INFO, this) << "DTLS channel error, code=" << read_error;
|
||||
set_writable(false);
|
||||
set_dtls_state(DTLS_TRANSPORT_FAILED);
|
||||
}
|
||||
@ -592,17 +614,17 @@ void DtlsTransport::OnDtlsEvent(rtc::StreamInterface* dtls, int sig, int err) {
|
||||
RTC_DCHECK(sig == rtc::SE_CLOSE); // SE_CLOSE should be by itself.
|
||||
set_writable(false);
|
||||
if (!err) {
|
||||
LOG_J(LS_INFO, this) << "DTLS transport closed";
|
||||
LOG_J(LS_INFO, this) << "DTLS channel closed";
|
||||
set_dtls_state(DTLS_TRANSPORT_CLOSED);
|
||||
} else {
|
||||
LOG_J(LS_INFO, this) << "DTLS transport error, code=" << err;
|
||||
LOG_J(LS_INFO, this) << "DTLS channel error, code=" << err;
|
||||
set_dtls_state(DTLS_TRANSPORT_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DtlsTransport::MaybeStartDtls() {
|
||||
if (dtls_ && ice_transport_->writable()) {
|
||||
void DtlsTransportChannelWrapper::MaybeStartDtls() {
|
||||
if (dtls_ && channel_->writable()) {
|
||||
if (dtls_->StartSSL()) {
|
||||
// This should never fail:
|
||||
// Because we are operating in a nonblocking mode and all
|
||||
@ -615,7 +637,8 @@ void DtlsTransport::MaybeStartDtls() {
|
||||
set_dtls_state(DTLS_TRANSPORT_FAILED);
|
||||
return;
|
||||
}
|
||||
LOG_J(LS_INFO, this) << "DtlsTransport: Started DTLS handshake";
|
||||
LOG_J(LS_INFO, this)
|
||||
<< "DtlsTransportChannelWrapper: Started DTLS handshake";
|
||||
set_dtls_state(DTLS_TRANSPORT_CONNECTING);
|
||||
// Now that the handshake has started, we can process a cached ClientHello
|
||||
// (if one exists).
|
||||
@ -636,7 +659,8 @@ void DtlsTransport::MaybeStartDtls() {
|
||||
}
|
||||
|
||||
// Called from OnReadPacket when a DTLS packet is received.
|
||||
bool DtlsTransport::HandleDtlsPacket(const char* data, size_t size) {
|
||||
bool DtlsTransportChannelWrapper::HandleDtlsPacket(const char* data,
|
||||
size_t size) {
|
||||
// Sanity check we're not passing junk that
|
||||
// just looks like DTLS.
|
||||
const uint8_t* tmp_data = reinterpret_cast<const uint8_t*>(data);
|
||||
@ -658,38 +682,56 @@ bool DtlsTransport::HandleDtlsPacket(const char* data, size_t size) {
|
||||
return downward_->OnPacketReceived(data, size);
|
||||
}
|
||||
|
||||
void DtlsTransport::set_receiving(bool receiving) {
|
||||
if (receiving_ == receiving) {
|
||||
return;
|
||||
}
|
||||
receiving_ = receiving;
|
||||
SignalReceivingState(this);
|
||||
void DtlsTransportChannelWrapper::OnGatheringState(
|
||||
IceTransportInternal* channel) {
|
||||
RTC_DCHECK(channel == channel_);
|
||||
SignalGatheringState(this);
|
||||
}
|
||||
|
||||
void DtlsTransport::set_writable(bool writable) {
|
||||
if (writable_ == writable) {
|
||||
return;
|
||||
}
|
||||
LOG_J(LS_VERBOSE, this) << "set_writable from:" << writable_ << " to "
|
||||
<< writable;
|
||||
writable_ = writable;
|
||||
if (writable_) {
|
||||
SignalReadyToSend(this);
|
||||
}
|
||||
SignalWritableState(this);
|
||||
void DtlsTransportChannelWrapper::OnCandidateGathered(
|
||||
IceTransportInternal* channel,
|
||||
const Candidate& c) {
|
||||
RTC_DCHECK(channel == channel_);
|
||||
SignalCandidateGathered(this, c);
|
||||
}
|
||||
|
||||
void DtlsTransport::set_dtls_state(DtlsTransportState state) {
|
||||
if (dtls_state_ == state) {
|
||||
return;
|
||||
}
|
||||
LOG_J(LS_VERBOSE, this) << "set_dtls_state from:" << dtls_state_ << " to "
|
||||
<< state;
|
||||
dtls_state_ = state;
|
||||
SignalDtlsState(this, state);
|
||||
void DtlsTransportChannelWrapper::OnCandidatesRemoved(
|
||||
IceTransportInternal* channel,
|
||||
const Candidates& candidates) {
|
||||
RTC_DCHECK(channel == channel_);
|
||||
SignalCandidatesRemoved(this, candidates);
|
||||
}
|
||||
|
||||
void DtlsTransport::OnDtlsHandshakeError(rtc::SSLHandshakeError error) {
|
||||
void DtlsTransportChannelWrapper::OnRoleConflict(
|
||||
IceTransportInternal* channel) {
|
||||
RTC_DCHECK(channel == channel_);
|
||||
SignalRoleConflict(this);
|
||||
}
|
||||
|
||||
void DtlsTransportChannelWrapper::OnRouteChange(IceTransportInternal* channel,
|
||||
const Candidate& candidate) {
|
||||
RTC_DCHECK(channel == channel_);
|
||||
SignalRouteChange(this, candidate);
|
||||
}
|
||||
|
||||
void DtlsTransportChannelWrapper::OnSelectedCandidatePairChanged(
|
||||
IceTransportInternal* channel,
|
||||
CandidatePairInterface* selected_candidate_pair,
|
||||
int last_sent_packet_id,
|
||||
bool ready_to_send) {
|
||||
RTC_DCHECK(channel == channel_);
|
||||
SignalSelectedCandidatePairChanged(this, selected_candidate_pair,
|
||||
last_sent_packet_id, ready_to_send);
|
||||
}
|
||||
|
||||
void DtlsTransportChannelWrapper::OnChannelStateChanged(
|
||||
IceTransportInternal* channel) {
|
||||
RTC_DCHECK(channel == channel_);
|
||||
SignalStateChanged(this);
|
||||
}
|
||||
|
||||
void DtlsTransportChannelWrapper::OnDtlsHandshakeError(
|
||||
rtc::SSLHandshakeError error) {
|
||||
SignalDtlsHandshakeError(error);
|
||||
}
|
||||
|
||||
|
||||
@ -20,8 +20,8 @@
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/sslstreamadapter.h"
|
||||
#include "webrtc/base/stream.h"
|
||||
#include "webrtc/p2p/base/dtlstransportinternal.h"
|
||||
#include "webrtc/p2p/base/icetransportinternal.h"
|
||||
#include "webrtc/p2p/base/transportchannelimpl.h"
|
||||
|
||||
namespace rtc {
|
||||
class PacketTransportInterface;
|
||||
@ -33,7 +33,7 @@ namespace cricket {
|
||||
// the bottom and a StreamInterface on the top.
|
||||
class StreamInterfaceChannel : public rtc::StreamInterface {
|
||||
public:
|
||||
explicit StreamInterfaceChannel(IceTransportInternal* ice_transport);
|
||||
explicit StreamInterfaceChannel(IceTransportInternal* channel);
|
||||
|
||||
// Push in a packet; this gets pulled out from Read().
|
||||
bool OnPacketReceived(const char* data, size_t size);
|
||||
@ -51,7 +51,7 @@ class StreamInterfaceChannel : public rtc::StreamInterface {
|
||||
int* error) override;
|
||||
|
||||
private:
|
||||
IceTransportInternal* ice_transport_; // owned by DtlsTransport
|
||||
IceTransportInternal* channel_; // owned by DtlsTransportChannelWrapper
|
||||
rtc::StreamState state_;
|
||||
rtc::BufferQueue packets_;
|
||||
|
||||
@ -64,43 +64,36 @@ class StreamInterfaceChannel : public rtc::StreamInterface {
|
||||
// (e.g a P2PTransportChannel)
|
||||
// Here's the way this works:
|
||||
//
|
||||
// DtlsTransport {
|
||||
// DtlsTransportChannelWrapper {
|
||||
// SSLStreamAdapter* dtls_ {
|
||||
// StreamInterfaceChannel downward_ {
|
||||
// IceTransportInternal* ice_transport_;
|
||||
// TransportChannelImpl* channel_;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// - Data which comes into DtlsTransport from the underlying
|
||||
// ice_transport_ via OnReadPacket() is checked for whether it is DTLS
|
||||
// or not, and if it is, is passed to DtlsTransport::HandleDtlsPacket,
|
||||
// which pushes it into to downward_. dtls_ is listening for events on
|
||||
// downward_, so it immediately calls downward_->Read().
|
||||
// - Data which comes into DtlsTransportChannelWrapper from the underlying
|
||||
// channel_ via OnReadPacket() is checked for whether it is DTLS
|
||||
// or not, and if it is, is passed to DtlsTransportChannelWrapper::
|
||||
// HandleDtlsPacket, which pushes it into to downward_.
|
||||
// dtls_ is listening for events on downward_, so it immediately calls
|
||||
// downward_->Read().
|
||||
//
|
||||
// - Data written to DtlsTransport is passed either to downward_ or directly
|
||||
// to ice_transport_, depending on whether DTLS is negotiated and whether
|
||||
// the flags include PF_SRTP_BYPASS
|
||||
// - Data written to DtlsTransportChannelWrapper is passed either to
|
||||
// downward_ or directly to channel_, depending on whether DTLS is
|
||||
// negotiated and whether the flags include PF_SRTP_BYPASS
|
||||
//
|
||||
// - The SSLStreamAdapter writes to downward_->Write() which translates it
|
||||
// into packet writes on ice_transport_.
|
||||
class DtlsTransport : public DtlsTransportInternal {
|
||||
// - The SSLStreamAdapter writes to downward_->Write()
|
||||
// which translates it into packet writes on channel_.
|
||||
class DtlsTransportChannelWrapper : public TransportChannelImpl {
|
||||
public:
|
||||
// The parameters here is:
|
||||
// ice_transport -- the ice transport we are wrapping
|
||||
explicit DtlsTransport(IceTransportInternal* ice_transport);
|
||||
~DtlsTransport() override;
|
||||
|
||||
DtlsTransportState dtls_state() const override { return dtls_state_; }
|
||||
|
||||
const std::string& transport_name() const override { return transport_name_; }
|
||||
|
||||
int component() const override { return component_; }
|
||||
|
||||
// Returns false if no local certificate was set, or if the peer doesn't
|
||||
// support DTLS.
|
||||
bool IsDtlsActive() const override { return dtls_active_; }
|
||||
// The parameters here are:
|
||||
// channel -- the TransportChannel we are wrapping
|
||||
explicit DtlsTransportChannelWrapper(IceTransportInternal* channel);
|
||||
~DtlsTransportChannelWrapper() override;
|
||||
|
||||
void SetIceRole(IceRole role) override { channel_->SetIceRole(role); }
|
||||
IceRole GetIceRole() const override { return channel_->GetIceRole(); }
|
||||
bool SetLocalCertificate(
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate) override;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const override;
|
||||
@ -109,6 +102,9 @@ class DtlsTransport : public DtlsTransportInternal {
|
||||
const uint8_t* digest,
|
||||
size_t digest_len) override;
|
||||
|
||||
// Returns false if no local certificate was set, or if the peer doesn't
|
||||
// support DTLS.
|
||||
bool IsDtlsActive() const override { return dtls_active_; }
|
||||
|
||||
// Called to send a packet (via DTLS, if turned on).
|
||||
int SendPacket(const char* data,
|
||||
@ -116,8 +112,16 @@ class DtlsTransport : public DtlsTransportInternal {
|
||||
const rtc::PacketOptions& options,
|
||||
int flags) override;
|
||||
|
||||
// TransportChannel calls that we forward to the wrapped transport.
|
||||
int SetOption(rtc::Socket::Option opt, int value) override {
|
||||
return channel_->SetOption(opt, value);
|
||||
}
|
||||
bool GetOption(rtc::Socket::Option opt, int* value) override {
|
||||
return ice_transport_->GetOption(opt, value);
|
||||
return channel_->GetOption(opt, value);
|
||||
}
|
||||
int GetError() override { return channel_->GetError(); }
|
||||
bool GetStats(ConnectionInfos* infos) override {
|
||||
return channel_->GetStats(infos);
|
||||
}
|
||||
|
||||
virtual bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version);
|
||||
@ -140,9 +144,9 @@ class DtlsTransport : public DtlsTransportInternal {
|
||||
// use by the remote peer, for use in external identity verification.
|
||||
std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate() const override;
|
||||
|
||||
// Once DTLS has established (i.e., this ice_transport is writable), this
|
||||
// method extracts the keys negotiated during the DTLS handshake, for use in
|
||||
// external encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
|
||||
// Once DTLS has established (i.e., this channel is writable), this method
|
||||
// extracts the keys negotiated during the DTLS handshake, for use in external
|
||||
// encryption. DTLS-SRTP uses this to extract the needed SRTP keys.
|
||||
// See the SSLStreamAdapter documentation for info on the specific parameters.
|
||||
bool ExportKeyingMaterial(const std::string& label,
|
||||
const uint8_t* context,
|
||||
@ -157,40 +161,50 @@ class DtlsTransport : public DtlsTransportInternal {
|
||||
: false;
|
||||
}
|
||||
|
||||
IceTransportInternal* ice_transport() override { return ice_transport_; }
|
||||
// TransportChannelImpl calls.
|
||||
IceTransportState GetState() const override { return channel_->GetState(); }
|
||||
void SetIceTiebreaker(uint64_t tiebreaker) override {
|
||||
channel_->SetIceTiebreaker(tiebreaker);
|
||||
}
|
||||
void SetIceParameters(const IceParameters& ice_params) override {
|
||||
channel_->SetIceParameters(ice_params);
|
||||
}
|
||||
void SetRemoteIceParameters(const IceParameters& ice_params) override {
|
||||
channel_->SetRemoteIceParameters(ice_params);
|
||||
}
|
||||
void SetRemoteIceMode(IceMode mode) override {
|
||||
channel_->SetRemoteIceMode(mode);
|
||||
}
|
||||
|
||||
void MaybeStartGathering() override { channel_->MaybeStartGathering(); }
|
||||
|
||||
IceGatheringState gathering_state() const override {
|
||||
return channel_->gathering_state();
|
||||
}
|
||||
|
||||
void AddRemoteCandidate(const Candidate& candidate) override {
|
||||
channel_->AddRemoteCandidate(candidate);
|
||||
}
|
||||
void RemoveRemoteCandidate(const Candidate& candidate) override {
|
||||
channel_->RemoveRemoteCandidate(candidate);
|
||||
}
|
||||
|
||||
void SetMetricsObserver(webrtc::MetricsObserverInterface* observer) override {
|
||||
channel_->SetMetricsObserver(observer);
|
||||
}
|
||||
|
||||
void SetIceConfig(const IceConfig& config) override {
|
||||
channel_->SetIceConfig(config);
|
||||
}
|
||||
|
||||
// Needed by DtlsTransport.
|
||||
IceTransportInternal* channel() { return channel_; }
|
||||
|
||||
// For informational purposes. Tells if the DTLS handshake has finished.
|
||||
// This may be true even if writable() is false, if the remote fingerprint
|
||||
// has not yet been verified.
|
||||
bool IsDtlsConnected();
|
||||
|
||||
bool receiving() const override { return receiving_; }
|
||||
|
||||
bool writable() const override { return writable_; }
|
||||
|
||||
int GetError() override { return ice_transport_->GetError(); }
|
||||
|
||||
int SetOption(rtc::Socket::Option opt, int value) override {
|
||||
return ice_transport_->SetOption(opt, value);
|
||||
}
|
||||
|
||||
bool SetSrtpCiphers(const std::vector<std::string>& ciphers) override {
|
||||
std::vector<int> crypto_suites;
|
||||
for (const auto cipher : ciphers) {
|
||||
crypto_suites.push_back(rtc::SrtpCryptoSuiteFromName(cipher));
|
||||
}
|
||||
return SetSrtpCryptoSuites(crypto_suites);
|
||||
}
|
||||
|
||||
std::string ToString() const {
|
||||
const char RECEIVING_ABBREV[2] = {'_', 'R'};
|
||||
const char WRITABLE_ABBREV[2] = {'_', 'W'};
|
||||
std::stringstream ss;
|
||||
ss << "DtlsTransport[" << transport_name_ << "|" << component_ << "|"
|
||||
<< RECEIVING_ABBREV[receiving()] << WRITABLE_ABBREV[writable()] << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
private:
|
||||
void OnWritableState(rtc::PacketTransportInterface* transport);
|
||||
void OnReadPacket(rtc::PacketTransportInterface* transport,
|
||||
@ -206,22 +220,25 @@ class DtlsTransport : public DtlsTransportInternal {
|
||||
bool SetupDtls();
|
||||
void MaybeStartDtls();
|
||||
bool HandleDtlsPacket(const char* data, size_t size);
|
||||
void OnGatheringState(IceTransportInternal* channel);
|
||||
void OnCandidateGathered(IceTransportInternal* channel, const Candidate& c);
|
||||
void OnCandidatesRemoved(IceTransportInternal* channel,
|
||||
const Candidates& candidates);
|
||||
void OnRoleConflict(IceTransportInternal* channel);
|
||||
void OnRouteChange(IceTransportInternal* channel, const Candidate& candidate);
|
||||
void OnSelectedCandidatePairChanged(
|
||||
IceTransportInternal* channel,
|
||||
CandidatePairInterface* selected_candidate_pair,
|
||||
int last_sent_packet_id,
|
||||
bool ready_to_send);
|
||||
void OnChannelStateChanged(IceTransportInternal* channel);
|
||||
void OnDtlsHandshakeError(rtc::SSLHandshakeError error);
|
||||
|
||||
void set_receiving(bool receiving);
|
||||
void set_writable(bool writable);
|
||||
// Sets the DTLS state, signaling if necessary.
|
||||
void set_dtls_state(DtlsTransportState state);
|
||||
|
||||
std::string transport_name_;
|
||||
int component_;
|
||||
DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW;
|
||||
rtc::Thread* network_thread_; // Everything should occur on this thread.
|
||||
// Underlying ice_transport, not owned by this class.
|
||||
IceTransportInternal* const ice_transport_;
|
||||
// Underlying channel, not owned by this class.
|
||||
IceTransportInternal* const channel_;
|
||||
std::unique_ptr<rtc::SSLStreamAdapter> dtls_; // The DTLS stream
|
||||
StreamInterfaceChannel*
|
||||
downward_; // Wrapper for ice_transport_, owned by dtls_.
|
||||
StreamInterfaceChannel* downward_; // Wrapper for channel_, owned by dtls_.
|
||||
std::vector<int> srtp_ciphers_; // SRTP ciphers to use with DTLS.
|
||||
bool dtls_active_ = false;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_;
|
||||
@ -232,13 +249,11 @@ class DtlsTransport : public DtlsTransportInternal {
|
||||
|
||||
// Cached DTLS ClientHello packet that was received before we started the
|
||||
// DTLS handshake. This could happen if the hello was received before the
|
||||
// ice transport became writable, or before a remote fingerprint was received.
|
||||
// transport channel became writable, or before a remote fingerprint was
|
||||
// received.
|
||||
rtc::Buffer cached_client_hello_;
|
||||
|
||||
bool receiving_ = false;
|
||||
bool writable_ = false;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(DtlsTransport);
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(DtlsTransportChannelWrapper);
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -97,31 +97,30 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
fake_ice_channel->SignalReadPacket.connect(
|
||||
this, &DtlsTestClient::OnFakeTransportChannelReadPacket);
|
||||
|
||||
cricket::DtlsTransport* dtls =
|
||||
new cricket::DtlsTransport(fake_ice_channel);
|
||||
dtls->SetLocalCertificate(certificate_);
|
||||
dtls->ice_transport()->SetIceRole(role);
|
||||
dtls->ice_transport()->SetIceTiebreaker(
|
||||
(role == cricket::ICEROLE_CONTROLLING) ? 1 : 2);
|
||||
dtls->SetSslMaxProtocolVersion(ssl_max_version_);
|
||||
dtls->SignalWritableState.connect(
|
||||
this, &DtlsTestClient::OnTransportChannelWritableState);
|
||||
dtls->SignalReadPacket.connect(
|
||||
this, &DtlsTestClient::OnTransportChannelReadPacket);
|
||||
dtls->SignalSentPacket.connect(
|
||||
cricket::DtlsTransportChannelWrapper* channel =
|
||||
new cricket::DtlsTransportChannelWrapper(fake_ice_channel);
|
||||
channel->SetLocalCertificate(certificate_);
|
||||
channel->SetIceRole(role);
|
||||
channel->SetIceTiebreaker((role == cricket::ICEROLE_CONTROLLING) ? 1 : 2);
|
||||
channel->SetSslMaxProtocolVersion(ssl_max_version_);
|
||||
channel->SignalWritableState.connect(this,
|
||||
&DtlsTestClient::OnTransportChannelWritableState);
|
||||
channel->SignalReadPacket.connect(this,
|
||||
&DtlsTestClient::OnTransportChannelReadPacket);
|
||||
channel->SignalSentPacket.connect(
|
||||
this, &DtlsTestClient::OnTransportChannelSentPacket);
|
||||
fake_dtls_transports_.push_back(
|
||||
std::unique_ptr<cricket::DtlsTransport>(dtls));
|
||||
fake_ice_transports_.push_back(
|
||||
channels_.push_back(
|
||||
std::unique_ptr<cricket::DtlsTransportChannelWrapper>(channel));
|
||||
fake_channels_.push_back(
|
||||
std::unique_ptr<cricket::FakeIceTransport>(fake_ice_channel));
|
||||
transport_->AddChannel(dtls, i);
|
||||
transport_->AddChannel(channel, i);
|
||||
}
|
||||
}
|
||||
|
||||
cricket::JsepTransport* transport() { return transport_.get(); }
|
||||
|
||||
cricket::FakeIceTransport* GetFakeIceTransort(int component) {
|
||||
for (const auto& ch : fake_ice_transports_) {
|
||||
cricket::FakeIceTransport* GetFakeChannel(int component) {
|
||||
for (const auto& ch : fake_channels_) {
|
||||
if (ch->component() == component) {
|
||||
return ch.get();
|
||||
}
|
||||
@ -129,10 +128,10 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
cricket::DtlsTransport* GetDtlsTransport(int component) {
|
||||
for (const auto& dtls : fake_dtls_transports_) {
|
||||
if (dtls->component() == component) {
|
||||
return dtls.get();
|
||||
cricket::DtlsTransportChannelWrapper* GetDtlsChannel(int component) {
|
||||
for (const auto& ch : channels_) {
|
||||
if (ch->component() == component) {
|
||||
return ch.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@ -154,8 +153,8 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
std::vector<int> ciphers;
|
||||
ciphers.push_back(rtc::SRTP_AES128_CM_SHA1_80);
|
||||
// SRTP ciphers will be set only in the beginning.
|
||||
for (const auto& dtls : fake_dtls_transports_) {
|
||||
EXPECT_TRUE(dtls->SetSrtpCryptoSuites(ciphers));
|
||||
for (const auto& channel : channels_) {
|
||||
EXPECT_TRUE(channel->SetSrtpCryptoSuites(ciphers));
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,31 +213,31 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
bool Connect(DtlsTestClient* peer, bool asymmetric) {
|
||||
for (auto& ice : fake_ice_transports_) {
|
||||
ice->SetDestination(peer->GetFakeIceTransort(ice->component()),
|
||||
asymmetric);
|
||||
for (auto& channel : fake_channels_) {
|
||||
channel->SetDestination(peer->GetFakeChannel(channel->component()),
|
||||
asymmetric);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool all_dtls_transports_writable() const {
|
||||
if (fake_dtls_transports_.empty()) {
|
||||
bool all_channels_writable() const {
|
||||
if (channels_.empty()) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& dtls : fake_dtls_transports_) {
|
||||
if (!dtls->writable()) {
|
||||
for (const auto& channel : channels_) {
|
||||
if (!channel->writable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool all_ice_transports_writable() const {
|
||||
if (fake_dtls_transports_.empty()) {
|
||||
bool all_raw_channels_writable() const {
|
||||
if (channels_.empty()) {
|
||||
return false;
|
||||
}
|
||||
for (const auto& dtls : fake_dtls_transports_) {
|
||||
if (!dtls->ice_transport()->writable()) {
|
||||
for (const auto& channel : channels_) {
|
||||
if (!channel->channel()->writable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -271,10 +270,10 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
void CheckSrtp(int expected_crypto_suite) {
|
||||
for (const auto& dtls : fake_dtls_transports_) {
|
||||
for (const auto& channel : channels_) {
|
||||
int crypto_suite;
|
||||
|
||||
bool rv = dtls->GetSrtpCryptoSuite(&crypto_suite);
|
||||
bool rv = channel->GetSrtpCryptoSuite(&crypto_suite);
|
||||
if (negotiated_dtls() && expected_crypto_suite) {
|
||||
ASSERT_TRUE(rv);
|
||||
|
||||
@ -286,10 +285,10 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
}
|
||||
|
||||
void CheckSsl() {
|
||||
for (const auto& dtls : fake_dtls_transports_) {
|
||||
for (const auto& channel : channels_) {
|
||||
int cipher;
|
||||
|
||||
bool rv = dtls->GetSslCipherSuite(&cipher);
|
||||
bool rv = channel->GetSslCipherSuite(&cipher);
|
||||
if (negotiated_dtls()) {
|
||||
ASSERT_TRUE(rv);
|
||||
|
||||
@ -301,8 +300,8 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
}
|
||||
}
|
||||
|
||||
void SendPackets(size_t transport, size_t size, size_t count, bool srtp) {
|
||||
RTC_CHECK(transport < fake_dtls_transports_.size());
|
||||
void SendPackets(size_t channel, size_t size, size_t count, bool srtp) {
|
||||
RTC_CHECK(channel < channels_.size());
|
||||
std::unique_ptr<char[]> packet(new char[size]);
|
||||
size_t sent = 0;
|
||||
do {
|
||||
@ -317,7 +316,7 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
int flags = (certificate_ && srtp) ? cricket::PF_SRTP_BYPASS : 0;
|
||||
rtc::PacketOptions packet_options;
|
||||
packet_options.packet_id = kFakePacketId;
|
||||
int rv = fake_dtls_transports_[transport]->SendPacket(
|
||||
int rv = channels_[channel]->SendPacket(
|
||||
packet.get(), size, packet_options, flags);
|
||||
ASSERT_GT(rv, 0);
|
||||
ASSERT_EQ(size, static_cast<size_t>(rv));
|
||||
@ -325,18 +324,18 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
} while (sent < count);
|
||||
}
|
||||
|
||||
int SendInvalidSrtpPacket(size_t transport, size_t size) {
|
||||
RTC_CHECK(transport < fake_dtls_transports_.size());
|
||||
int SendInvalidSrtpPacket(size_t channel, size_t size) {
|
||||
RTC_CHECK(channel < channels_.size());
|
||||
std::unique_ptr<char[]> packet(new char[size]);
|
||||
// Fill the packet with 0 to form an invalid SRTP packet.
|
||||
memset(packet.get(), 0, size);
|
||||
|
||||
rtc::PacketOptions packet_options;
|
||||
return fake_dtls_transports_[transport]->SendPacket(
|
||||
return channels_[channel]->SendPacket(
|
||||
packet.get(), size, packet_options, cricket::PF_SRTP_BYPASS);
|
||||
}
|
||||
|
||||
void ExpectPackets(size_t transport, size_t size) {
|
||||
void ExpectPackets(size_t channel, size_t size) {
|
||||
packet_size_ = size;
|
||||
received_.clear();
|
||||
}
|
||||
@ -436,8 +435,8 @@ class DtlsTestClient : public sigslot::has_slots<> {
|
||||
private:
|
||||
std::string name_;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> certificate_;
|
||||
std::vector<std::unique_ptr<cricket::FakeIceTransport>> fake_ice_transports_;
|
||||
std::vector<std::unique_ptr<cricket::DtlsTransport>> fake_dtls_transports_;
|
||||
std::vector<std::unique_ptr<cricket::FakeIceTransport>> fake_channels_;
|
||||
std::vector<std::unique_ptr<cricket::DtlsTransportChannelWrapper>> channels_;
|
||||
std::unique_ptr<cricket::JsepTransport> transport_;
|
||||
size_t packet_size_ = 0u;
|
||||
std::set<int> received_;
|
||||
@ -528,11 +527,10 @@ class DtlsTransportChannelTestBase {
|
||||
if (!rv)
|
||||
return false;
|
||||
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client1_.all_dtls_transports_writable() &&
|
||||
client2_.all_dtls_transports_writable(),
|
||||
kTimeout, fake_clock_);
|
||||
if (!client1_.all_dtls_transports_writable() ||
|
||||
!client2_.all_dtls_transports_writable())
|
||||
EXPECT_TRUE_SIMULATED_WAIT(
|
||||
client1_.all_channels_writable() && client2_.all_channels_writable(),
|
||||
kTimeout, fake_clock_);
|
||||
if (!client1_.all_channels_writable() || !client2_.all_channels_writable())
|
||||
return false;
|
||||
|
||||
// Check that we used the right roles.
|
||||
@ -618,10 +616,10 @@ class DtlsTransportChannelTestBase {
|
||||
}
|
||||
}
|
||||
|
||||
void TestTransfer(size_t transport, size_t size, size_t count, bool srtp) {
|
||||
void TestTransfer(size_t channel, size_t size, size_t count, bool srtp) {
|
||||
LOG(LS_INFO) << "Expect packets, size=" << size;
|
||||
client2_.ExpectPackets(transport, size);
|
||||
client1_.SendPackets(transport, size, count, srtp);
|
||||
client2_.ExpectPackets(channel, size);
|
||||
client1_.SendPackets(channel, size, count, srtp);
|
||||
EXPECT_EQ_SIMULATED_WAIT(count, client2_.NumPacketsReceived(), kTimeout,
|
||||
fake_clock_);
|
||||
}
|
||||
@ -642,8 +640,8 @@ class DtlsTransportChannelTest : public DtlsTransportChannelTestBase,
|
||||
// Test that transport negotiation of ICE, no DTLS works properly.
|
||||
TEST_F(DtlsTransportChannelTest, TestChannelSetupIce) {
|
||||
Negotiate();
|
||||
cricket::FakeIceTransport* channel1 = client1_.GetFakeIceTransort(0);
|
||||
cricket::FakeIceTransport* channel2 = client2_.GetFakeIceTransort(0);
|
||||
cricket::FakeIceTransport* channel1 = client1_.GetFakeChannel(0);
|
||||
cricket::FakeIceTransport* channel2 = client2_.GetFakeChannel(0);
|
||||
ASSERT_TRUE(channel1 != NULL);
|
||||
ASSERT_TRUE(channel2 != NULL);
|
||||
EXPECT_EQ(cricket::ICEROLE_CONTROLLING, channel1->GetIceRole());
|
||||
@ -922,9 +920,9 @@ TEST_F(DtlsTransportChannelTest, TestRenegotiateBeforeConnect) {
|
||||
cricket::CONNECTIONROLE_ACTIVE, NF_REOFFER);
|
||||
bool rv = client1_.Connect(&client2_, false);
|
||||
EXPECT_TRUE(rv);
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client1_.all_dtls_transports_writable() &&
|
||||
client2_.all_dtls_transports_writable(),
|
||||
kTimeout, fake_clock_);
|
||||
EXPECT_TRUE_SIMULATED_WAIT(
|
||||
client1_.all_channels_writable() && client2_.all_channels_writable(),
|
||||
kTimeout, fake_clock_);
|
||||
|
||||
TestTransfer(0, 1000, 100, true);
|
||||
TestTransfer(1, 1000, 100, true);
|
||||
@ -947,8 +945,8 @@ TEST_F(DtlsTransportChannelTest, TestCertificatesBeforeConnect) {
|
||||
ASSERT_TRUE(client2_.transport()->GetLocalCertificate(&certificate2));
|
||||
ASSERT_NE(certificate1->ssl_certificate().ToPEMString(),
|
||||
certificate2->ssl_certificate().ToPEMString());
|
||||
ASSERT_FALSE(client1_.GetDtlsTransport(0)->GetRemoteSSLCertificate());
|
||||
ASSERT_FALSE(client2_.GetDtlsTransport(0)->GetRemoteSSLCertificate());
|
||||
ASSERT_FALSE(client1_.GetDtlsChannel(0)->GetRemoteSSLCertificate());
|
||||
ASSERT_FALSE(client2_.GetDtlsChannel(0)->GetRemoteSSLCertificate());
|
||||
}
|
||||
|
||||
// Test Certificates state after connection.
|
||||
@ -968,12 +966,12 @@ TEST_F(DtlsTransportChannelTest, TestCertificatesAfterConnect) {
|
||||
|
||||
// Each side's remote certificate is the other side's local certificate.
|
||||
std::unique_ptr<rtc::SSLCertificate> remote_cert1 =
|
||||
client1_.GetDtlsTransport(0)->GetRemoteSSLCertificate();
|
||||
client1_.GetDtlsChannel(0)->GetRemoteSSLCertificate();
|
||||
ASSERT_TRUE(remote_cert1);
|
||||
ASSERT_EQ(remote_cert1->ToPEMString(),
|
||||
certificate2->ssl_certificate().ToPEMString());
|
||||
std::unique_ptr<rtc::SSLCertificate> remote_cert2 =
|
||||
client2_.GetDtlsTransport(0)->GetRemoteSSLCertificate();
|
||||
client2_.GetDtlsChannel(0)->GetRemoteSSLCertificate();
|
||||
ASSERT_TRUE(remote_cert2);
|
||||
ASSERT_EQ(remote_cert2->ToPEMString(),
|
||||
certificate1->ssl_certificate().ToPEMString());
|
||||
@ -996,12 +994,12 @@ TEST_F(DtlsTransportChannelTest, TestRetransmissionSchedule) {
|
||||
// Make client2_ writable, but not client1_.
|
||||
// This means client1_ will send DTLS client hellos but get no response.
|
||||
EXPECT_TRUE(client2_.Connect(&client1_, true));
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client2_.all_ice_transports_writable(), kTimeout,
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client2_.all_raw_channels_writable(), kTimeout,
|
||||
fake_clock_);
|
||||
|
||||
// Wait for the first client hello to be sent.
|
||||
EXPECT_EQ_WAIT(1, client1_.received_dtls_client_hellos(), kTimeout);
|
||||
EXPECT_FALSE(client1_.all_ice_transports_writable());
|
||||
EXPECT_FALSE(client1_.all_raw_channels_writable());
|
||||
|
||||
static int timeout_schedule_ms[] = {50, 100, 200, 400, 800, 1600,
|
||||
3200, 6400, 12800, 25600, 51200, 60000};
|
||||
@ -1106,7 +1104,7 @@ class DtlsEventOrderingTest
|
||||
break;
|
||||
case CALLER_WRITABLE:
|
||||
EXPECT_TRUE(client1_.Connect(&client2_, true));
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client1_.all_ice_transports_writable(),
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client1_.all_raw_channels_writable(),
|
||||
kTimeout, fake_clock_);
|
||||
break;
|
||||
case CALLER_RECEIVES_CLIENTHELLO:
|
||||
@ -1114,19 +1112,19 @@ class DtlsEventOrderingTest
|
||||
EXPECT_EQ(0, client1_.received_dtls_client_hellos());
|
||||
// Making client2_ writable will cause it to send the ClientHello.
|
||||
EXPECT_TRUE(client2_.Connect(&client1_, true));
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client2_.all_ice_transports_writable(),
|
||||
EXPECT_TRUE_SIMULATED_WAIT(client2_.all_raw_channels_writable(),
|
||||
kTimeout, fake_clock_);
|
||||
EXPECT_EQ_SIMULATED_WAIT(1, client1_.received_dtls_client_hellos(),
|
||||
kTimeout, fake_clock_);
|
||||
break;
|
||||
case HANDSHAKE_FINISHES:
|
||||
// Sanity check that the handshake hasn't already finished.
|
||||
EXPECT_FALSE(client1_.GetDtlsTransport(0)->IsDtlsConnected() ||
|
||||
client1_.GetDtlsTransport(0)->dtls_state() ==
|
||||
EXPECT_FALSE(client1_.GetDtlsChannel(0)->IsDtlsConnected() ||
|
||||
client1_.GetDtlsChannel(0)->dtls_state() ==
|
||||
cricket::DTLS_TRANSPORT_FAILED);
|
||||
EXPECT_TRUE_SIMULATED_WAIT(
|
||||
client1_.GetDtlsTransport(0)->IsDtlsConnected() ||
|
||||
client1_.GetDtlsTransport(0)->dtls_state() ==
|
||||
client1_.GetDtlsChannel(0)->IsDtlsConnected() ||
|
||||
client1_.GetDtlsChannel(0)->dtls_state() ==
|
||||
cricket::DTLS_TRANSPORT_FAILED,
|
||||
kTimeout, fake_clock_);
|
||||
break;
|
||||
@ -1137,15 +1135,15 @@ class DtlsEventOrderingTest
|
||||
valid_fingerprint ? cricket::DTLS_TRANSPORT_CONNECTED
|
||||
: cricket::DTLS_TRANSPORT_FAILED;
|
||||
EXPECT_EQ_SIMULATED_WAIT(expected_final_state,
|
||||
client1_.GetDtlsTransport(0)->dtls_state(),
|
||||
kTimeout, fake_clock_);
|
||||
client1_.GetDtlsChannel(0)->dtls_state(), kTimeout,
|
||||
fake_clock_);
|
||||
EXPECT_EQ_SIMULATED_WAIT(expected_final_state,
|
||||
client2_.GetDtlsTransport(0)->dtls_state(),
|
||||
kTimeout, fake_clock_);
|
||||
client2_.GetDtlsChannel(0)->dtls_state(), kTimeout,
|
||||
fake_clock_);
|
||||
|
||||
// Channel should be writable iff there was a valid fingerprint.
|
||||
EXPECT_EQ(valid_fingerprint, client1_.GetDtlsTransport(0)->writable());
|
||||
EXPECT_EQ(valid_fingerprint, client2_.GetDtlsTransport(0)->writable());
|
||||
EXPECT_EQ(valid_fingerprint, client1_.GetDtlsChannel(0)->writable());
|
||||
EXPECT_EQ(valid_fingerprint, client2_.GetDtlsChannel(0)->writable());
|
||||
|
||||
// Check that no hello needed to be retransmitted.
|
||||
EXPECT_EQ(1, client1_.received_dtls_client_hellos());
|
||||
|
||||
@ -22,12 +22,6 @@
|
||||
|
||||
namespace cricket {
|
||||
|
||||
enum PacketFlags {
|
||||
PF_NORMAL = 0x00, // A normal packet.
|
||||
PF_SRTP_BYPASS = 0x01, // An encrypted SRTP packet; bypass any additional
|
||||
// crypto provided by the transport (e.g. DTLS)
|
||||
};
|
||||
|
||||
// DtlsTransportInternal is an internal interface that does DTLS.
|
||||
// Once the public interface is supported,
|
||||
// (https://www.w3.org/TR/webrtc/#rtcdtlstransport-interface)
|
||||
@ -100,9 +94,6 @@ class DtlsTransportInternal : public rtc::PacketTransportInterface {
|
||||
return transport_name() + " " + std::to_string(component());
|
||||
}
|
||||
|
||||
protected:
|
||||
DtlsTransportInternal() {}
|
||||
|
||||
private:
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(DtlsTransportInternal);
|
||||
};
|
||||
|
||||
@ -24,9 +24,9 @@
|
||||
#include "webrtc/base/sslfingerprint.h"
|
||||
#include "webrtc/base/thread.h"
|
||||
#include "webrtc/p2p/base/candidatepairinterface.h"
|
||||
#include "webrtc/p2p/base/dtlstransportinternal.h"
|
||||
#include "webrtc/p2p/base/icetransportinternal.h"
|
||||
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
#include "webrtc/p2p/base/transportchannelimpl.h"
|
||||
#include "webrtc/p2p/base/transportcontroller.h"
|
||||
|
||||
#ifdef HAVE_QUIC
|
||||
@ -263,75 +263,85 @@ class FakeIceTransport : public IceTransportInternal,
|
||||
bool receiving_ = false;
|
||||
};
|
||||
|
||||
class FakeDtlsTransport : public DtlsTransportInternal {
|
||||
// Fake transport channel class, which can be passed to anything that needs a
|
||||
// transport channel. Can be informed of another FakeTransportChannel via
|
||||
// SetDestination.
|
||||
// TODO(hbos): Move implementation to .cc file, this and other classes in file.
|
||||
class FakeTransportChannel : public TransportChannelImpl,
|
||||
public rtc::MessageHandler {
|
||||
public:
|
||||
explicit FakeDtlsTransport(FakeIceTransport* ice_transport)
|
||||
: ice_transport_(ice_transport),
|
||||
transport_name_(ice_transport->transport_name()),
|
||||
component_(ice_transport->component()),
|
||||
dtls_fingerprint_("", nullptr, 0) {
|
||||
ice_transport_->SignalReadPacket.connect(
|
||||
this, &FakeDtlsTransport::OnIceTransportReadPacket);
|
||||
}
|
||||
|
||||
explicit FakeDtlsTransport(const std::string& name, int component)
|
||||
: ice_transport_(new FakeIceTransport(name, component)),
|
||||
transport_name_(ice_transport_->transport_name()),
|
||||
component_(ice_transport_->component()),
|
||||
dtls_fingerprint_("", nullptr, 0) {
|
||||
ice_transport_->SignalReadPacket.connect(
|
||||
this, &FakeDtlsTransport::OnIceTransportReadPacket);
|
||||
}
|
||||
|
||||
~FakeDtlsTransport() override { Reset(); }
|
||||
|
||||
uint64_t IceTiebreaker() const { return ice_transport_->IceTiebreaker(); }
|
||||
IceMode remote_ice_mode() const { return ice_transport_->remote_ice_mode(); }
|
||||
const std::string& ice_ufrag() const { return ice_transport_->ice_ufrag(); }
|
||||
const std::string& ice_pwd() const { return ice_transport_->ice_pwd(); }
|
||||
const std::string& remote_ice_ufrag() const {
|
||||
return ice_transport_->remote_ice_ufrag();
|
||||
}
|
||||
const std::string& remote_ice_pwd() const {
|
||||
return ice_transport_->remote_ice_pwd();
|
||||
}
|
||||
|
||||
DtlsTransportState dtls_state() const override { return dtls_state_; }
|
||||
|
||||
const std::string& transport_name() const override { return transport_name_; }
|
||||
|
||||
int component() const override { return component_; }
|
||||
explicit FakeTransportChannel(const std::string& name, int component)
|
||||
: TransportChannelImpl(name, component),
|
||||
dtls_fingerprint_("", nullptr, 0) {}
|
||||
~FakeTransportChannel() { Reset(); }
|
||||
|
||||
uint64_t IceTiebreaker() const { return tiebreaker_; }
|
||||
IceMode remote_ice_mode() const { return remote_ice_mode_; }
|
||||
const std::string& ice_ufrag() const { return ice_ufrag_; }
|
||||
const std::string& ice_pwd() const { return ice_pwd_; }
|
||||
const std::string& remote_ice_ufrag() const { return remote_ice_ufrag_; }
|
||||
const std::string& remote_ice_pwd() const { return remote_ice_pwd_; }
|
||||
const rtc::SSLFingerprint& dtls_fingerprint() const {
|
||||
return dtls_fingerprint_;
|
||||
}
|
||||
|
||||
// If async, will send packets by "Post"-ing to message queue instead of
|
||||
// synchronously "Send"-ing.
|
||||
void SetAsync(bool async) { ice_transport_->SetAsync(async); }
|
||||
void SetAsyncDelay(int delay_ms) { ice_transport_->SetAsyncDelay(delay_ms); }
|
||||
void SetAsync(bool async) { async_ = async; }
|
||||
void SetAsyncDelay(int delay_ms) { async_delay_ms_ = delay_ms; }
|
||||
|
||||
IceRole GetIceRole() const { return ice_transport_->GetIceRole(); }
|
||||
IceTransportState GetState() const override {
|
||||
if (connection_count_ == 0) {
|
||||
return had_connection_ ? IceTransportState::STATE_FAILED
|
||||
: IceTransportState::STATE_INIT;
|
||||
}
|
||||
|
||||
if (connection_count_ == 1) {
|
||||
return IceTransportState::STATE_COMPLETED;
|
||||
}
|
||||
|
||||
return IceTransportState::STATE_CONNECTING;
|
||||
}
|
||||
|
||||
void SetIceRole(IceRole role) override { role_ = role; }
|
||||
IceRole GetIceRole() const override { return role_; }
|
||||
void SetIceTiebreaker(uint64_t tiebreaker) override {
|
||||
tiebreaker_ = tiebreaker;
|
||||
}
|
||||
void SetIceParameters(const IceParameters& ice_params) override {
|
||||
ice_ufrag_ = ice_params.ufrag;
|
||||
ice_pwd_ = ice_params.pwd;
|
||||
}
|
||||
void SetRemoteIceParameters(const IceParameters& params) override {
|
||||
remote_ice_ufrag_ = params.ufrag;
|
||||
remote_ice_pwd_ = params.pwd;
|
||||
}
|
||||
|
||||
void SetRemoteIceMode(IceMode mode) override { remote_ice_mode_ = mode; }
|
||||
bool SetRemoteFingerprint(const std::string& alg,
|
||||
const uint8_t* digest,
|
||||
size_t digest_len) override {
|
||||
dtls_fingerprint_ = rtc::SSLFingerprint(alg, digest, digest_len);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SetSslRole(rtc::SSLRole role) override {
|
||||
ssl_role_ = role;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetSslRole(rtc::SSLRole* role) const override {
|
||||
*role = ssl_role_;
|
||||
return true;
|
||||
}
|
||||
|
||||
IceGatheringState gathering_state() const {
|
||||
return ice_transport_->gathering_state();
|
||||
void MaybeStartGathering() override {
|
||||
if (gathering_state_ == kIceGatheringNew) {
|
||||
gathering_state_ = kIceGatheringGathering;
|
||||
SignalGatheringState(this);
|
||||
}
|
||||
}
|
||||
|
||||
IceGatheringState gathering_state() const override {
|
||||
return gathering_state_;
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
@ -348,9 +358,9 @@ class FakeDtlsTransport : public DtlsTransportInternal {
|
||||
void SetWritable(bool writable) { set_writable(writable); }
|
||||
|
||||
// Simulates the two transport channels connecting to each other.
|
||||
// If |asymmetric| is true this method only affects this FakeDtlsTransport.
|
||||
// If |asymmetric| is true this method only affects this FakeTransportChannel.
|
||||
// If false, it affects |dest| as well.
|
||||
void SetDestination(FakeDtlsTransport* dest, bool asymmetric = false) {
|
||||
void SetDestination(FakeTransportChannel* dest, bool asymmetric = false) {
|
||||
if (state_ == STATE_INIT && dest) {
|
||||
// This simulates the delivery of candidates.
|
||||
dest_ = dest;
|
||||
@ -359,58 +369,87 @@ class FakeDtlsTransport : public DtlsTransportInternal {
|
||||
NegotiateSrtpCiphers();
|
||||
}
|
||||
state_ = STATE_CONNECTED;
|
||||
SetWritable(true);
|
||||
set_writable(true);
|
||||
if (!asymmetric) {
|
||||
dest->SetDestination(this, true);
|
||||
}
|
||||
ice_transport_->SetDestination(
|
||||
static_cast<FakeIceTransport*>(dest->ice_transport()), asymmetric);
|
||||
} else if (state_ == STATE_CONNECTED && !dest) {
|
||||
// Simulates loss of connectivity, by asymmetrically forgetting dest_.
|
||||
dest_ = nullptr;
|
||||
state_ = STATE_INIT;
|
||||
SetWritable(false);
|
||||
ice_transport_->SetDestination(nullptr, asymmetric);
|
||||
set_writable(false);
|
||||
}
|
||||
}
|
||||
|
||||
void SetConnectionCount(size_t connection_count) {
|
||||
ice_transport_->SetConnectionCount(connection_count);
|
||||
size_t old_connection_count = connection_count_;
|
||||
connection_count_ = connection_count;
|
||||
if (connection_count)
|
||||
had_connection_ = true;
|
||||
// In this fake transport channel, |connection_count_| determines the
|
||||
// transport channel state.
|
||||
if (connection_count_ < old_connection_count)
|
||||
SignalStateChanged(this);
|
||||
}
|
||||
|
||||
void SetCandidatesGatheringComplete() {
|
||||
ice_transport_->SetCandidatesGatheringComplete();
|
||||
if (gathering_state_ != kIceGatheringComplete) {
|
||||
gathering_state_ = kIceGatheringComplete;
|
||||
SignalGatheringState(this);
|
||||
}
|
||||
}
|
||||
|
||||
void SetReceiving(bool receiving) {
|
||||
ice_transport_->SetReceiving(receiving);
|
||||
set_receiving(receiving);
|
||||
}
|
||||
void SetReceiving(bool receiving) { set_receiving(receiving); }
|
||||
|
||||
int receiving_timeout() const { return ice_transport_->receiving_timeout(); }
|
||||
bool gather_continually() const {
|
||||
return ice_transport_->gather_continually();
|
||||
}
|
||||
void SetIceConfig(const IceConfig& config) override { ice_config_ = config; }
|
||||
|
||||
int receiving_timeout() const { return ice_config_.receiving_timeout; }
|
||||
bool gather_continually() const { return ice_config_.gather_continually(); }
|
||||
|
||||
int SendPacket(const char* data,
|
||||
size_t len,
|
||||
const rtc::PacketOptions& options,
|
||||
int flags) override {
|
||||
return ice_transport_->SendPacket(data, len, options, flags);
|
||||
}
|
||||
if (state_ != STATE_CONNECTED) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags != PF_SRTP_BYPASS && flags != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
PacketMessageData* packet = new PacketMessageData(data, len);
|
||||
if (async_) {
|
||||
if (async_delay_ms_) {
|
||||
rtc::Thread::Current()->PostDelayed(RTC_FROM_HERE, async_delay_ms_,
|
||||
this, 0, packet);
|
||||
} else {
|
||||
rtc::Thread::Current()->Post(RTC_FROM_HERE, this, 0, packet);
|
||||
}
|
||||
} else {
|
||||
rtc::Thread::Current()->Send(RTC_FROM_HERE, this, 0, packet);
|
||||
}
|
||||
rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis());
|
||||
SignalSentPacket(this, sent_packet);
|
||||
return static_cast<int>(len);
|
||||
}
|
||||
int SetOption(rtc::Socket::Option opt, int value) override { return true; }
|
||||
bool GetOption(rtc::Socket::Option opt, int* value) override { return true; }
|
||||
int GetError() override { return 0; }
|
||||
|
||||
const Candidates& remote_candidates() const {
|
||||
return ice_transport_->remote_candidates();
|
||||
void AddRemoteCandidate(const Candidate& candidate) override {
|
||||
remote_candidates_.push_back(candidate);
|
||||
}
|
||||
|
||||
void OnIceTransportReadPacket(PacketTransportInterface* ice_,
|
||||
const char* data,
|
||||
size_t len,
|
||||
const rtc::PacketTime& time,
|
||||
int flags) {
|
||||
SignalReadPacket(this, data, len, time, flags);
|
||||
void RemoveRemoteCandidate(const Candidate& candidate) override {}
|
||||
|
||||
const Candidates& remote_candidates() const { return remote_candidates_; }
|
||||
|
||||
void OnMessage(rtc::Message* msg) override {
|
||||
PacketMessageData* data = static_cast<PacketMessageData*>(msg->pdata);
|
||||
dest_->SignalReadPacket(dest_, data->packet.data<char>(),
|
||||
data->packet.size(), rtc::CreatePacketTime(0), 0);
|
||||
delete data;
|
||||
}
|
||||
|
||||
bool SetLocalCertificate(
|
||||
@ -465,6 +504,13 @@ class FakeDtlsTransport : public DtlsTransportInternal {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GetStats(ConnectionInfos* infos) override {
|
||||
ConnectionInfo info;
|
||||
infos->clear();
|
||||
infos->push_back(info);
|
||||
return true;
|
||||
}
|
||||
|
||||
void set_ssl_max_protocol_version(rtc::SSLProtocolVersion version) {
|
||||
ssl_max_version_ = version;
|
||||
}
|
||||
@ -472,24 +518,7 @@ class FakeDtlsTransport : public DtlsTransportInternal {
|
||||
return ssl_max_version_;
|
||||
}
|
||||
|
||||
IceTransportInternal* ice_transport() override { return ice_transport_; }
|
||||
|
||||
bool writable() const override { return writable_; }
|
||||
|
||||
bool receiving() const override { return receiving_; }
|
||||
|
||||
int GetError() override { return ice_transport_->GetError(); }
|
||||
|
||||
int SetOption(rtc::Socket::Option opt, int value) override {
|
||||
return ice_transport_->SetOption(opt, value);
|
||||
}
|
||||
|
||||
bool SetSrtpCiphers(const std::vector<std::string>& ciphers) override {
|
||||
std::vector<int> crypto_suites;
|
||||
for (const auto cipher : ciphers) {
|
||||
crypto_suites.push_back(rtc::SrtpCryptoSuiteFromName(cipher));
|
||||
}
|
||||
return SetSrtpCryptoSuites(crypto_suites);
|
||||
void SetMetricsObserver(webrtc::MetricsObserverInterface* observer) override {
|
||||
}
|
||||
|
||||
private:
|
||||
@ -506,45 +535,31 @@ class FakeDtlsTransport : public DtlsTransportInternal {
|
||||
}
|
||||
}
|
||||
|
||||
void set_receiving(bool receiving) {
|
||||
if (receiving_ == receiving) {
|
||||
return;
|
||||
}
|
||||
receiving_ = receiving;
|
||||
SignalReceivingState(this);
|
||||
}
|
||||
|
||||
void set_writable(bool writable) {
|
||||
if (writable_ == writable) {
|
||||
return;
|
||||
}
|
||||
writable_ = writable;
|
||||
if (writable_) {
|
||||
SignalReadyToSend(this);
|
||||
}
|
||||
SignalWritableState(this);
|
||||
}
|
||||
|
||||
enum State { STATE_INIT, STATE_CONNECTED };
|
||||
FakeIceTransport* ice_transport_;
|
||||
std::string transport_name_;
|
||||
int component_;
|
||||
FakeDtlsTransport* dest_ = nullptr;
|
||||
FakeTransportChannel* dest_ = nullptr;
|
||||
State state_ = STATE_INIT;
|
||||
bool async_ = false;
|
||||
int async_delay_ms_ = 0;
|
||||
Candidates remote_candidates_;
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> local_cert_;
|
||||
rtc::FakeSSLCertificate* remote_cert_ = nullptr;
|
||||
bool do_dtls_ = false;
|
||||
std::vector<int> srtp_ciphers_;
|
||||
int chosen_crypto_suite_ = rtc::SRTP_INVALID_CRYPTO_SUITE;
|
||||
IceConfig ice_config_;
|
||||
IceRole role_ = ICEROLE_UNKNOWN;
|
||||
uint64_t tiebreaker_ = 0;
|
||||
std::string ice_ufrag_;
|
||||
std::string ice_pwd_;
|
||||
std::string remote_ice_ufrag_;
|
||||
std::string remote_ice_pwd_;
|
||||
IceMode remote_ice_mode_ = ICEMODE_FULL;
|
||||
rtc::SSLProtocolVersion ssl_max_version_ = rtc::SSL_PROTOCOL_DTLS_12;
|
||||
rtc::SSLFingerprint dtls_fingerprint_;
|
||||
rtc::SSLRole ssl_role_ = rtc::SSL_CLIENT;
|
||||
|
||||
DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW;
|
||||
|
||||
bool receiving_ = false;
|
||||
bool writable_ = false;
|
||||
size_t connection_count_ = 0;
|
||||
IceGatheringState gathering_state_ = kIceGatheringNew;
|
||||
bool had_connection_ = false;
|
||||
};
|
||||
|
||||
// Fake candidate pair class, which can be passed to BaseChannel for testing
|
||||
@ -599,9 +614,10 @@ class FakeTransportController : public TransportController {
|
||||
SetIceRole(role);
|
||||
}
|
||||
|
||||
FakeDtlsTransport* GetFakeDtlsTransport_n(const std::string& transport_name,
|
||||
int component) {
|
||||
return static_cast<FakeDtlsTransport*>(
|
||||
FakeTransportChannel* GetFakeTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component) {
|
||||
return static_cast<FakeTransportChannel*>(
|
||||
get_channel_for_testing(transport_name, component));
|
||||
}
|
||||
|
||||
@ -650,8 +666,8 @@ class FakeTransportController : public TransportController {
|
||||
}
|
||||
|
||||
void DestroyRtcpTransport(const std::string& transport_name) {
|
||||
DestroyDtlsTransport_n(transport_name,
|
||||
cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
DestroyTransportChannel_n(transport_name,
|
||||
cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -661,21 +677,21 @@ class FakeTransportController : public TransportController {
|
||||
IceTransportInternal* CreateIceTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component) override {
|
||||
return new FakeIceTransport(transport_name, component);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
DtlsTransportInternal* CreateDtlsTransportChannel_n(
|
||||
TransportChannelImpl* CreateDtlsTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component,
|
||||
IceTransportInternal* ice) override {
|
||||
return new FakeDtlsTransport(static_cast<FakeIceTransport*>(ice));
|
||||
IceTransportInternal*) override {
|
||||
return new FakeTransportChannel(transport_name, component);
|
||||
}
|
||||
|
||||
private:
|
||||
void SetChannelDestinations_n(FakeTransportController* dest) {
|
||||
for (DtlsTransportInternal* tc : channels_for_testing()) {
|
||||
FakeDtlsTransport* local = static_cast<FakeDtlsTransport*>(tc);
|
||||
FakeDtlsTransport* remote = dest->GetFakeDtlsTransport_n(
|
||||
for (TransportChannelImpl* tc : channels_for_testing()) {
|
||||
FakeTransportChannel* local = static_cast<FakeTransportChannel*>(tc);
|
||||
FakeTransportChannel* remote = dest->GetFakeTransportChannel_n(
|
||||
local->transport_name(), local->component());
|
||||
if (remote) {
|
||||
bool asymmetric = false;
|
||||
|
||||
@ -25,11 +25,7 @@ class MetricsObserverInterface;
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class IceTransportInternal;
|
||||
typedef IceTransportInternal IceTransportInternal2;
|
||||
|
||||
// TODO(zhihuang): Replace this with
|
||||
// PeerConnectionInterface::IceConnectionState.
|
||||
// TODO(zhihuang): replace it with PeerConnectionInterface::IceConnectionState.
|
||||
enum class IceTransportState {
|
||||
STATE_INIT,
|
||||
STATE_CONNECTING, // Will enter this state once a connection is created
|
||||
@ -138,7 +134,7 @@ class IceTransportInternal : public rtc::PacketTransportInterface {
|
||||
sigslot::signal1<IceTransportInternal*> SignalDestroyed;
|
||||
|
||||
// Debugging description of this transport.
|
||||
std::string debug_name() const override {
|
||||
const std::string debug_name() const override {
|
||||
return transport_name() + " " + std::to_string(component());
|
||||
}
|
||||
};
|
||||
|
||||
@ -8,19 +8,20 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "webrtc/p2p/base/jseptransport.h"
|
||||
|
||||
#include <memory>
|
||||
#include <utility> // for std::pair
|
||||
|
||||
#include "webrtc/base/bind.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/p2p/base/jseptransport.h"
|
||||
|
||||
#include "webrtc/p2p/base/candidate.h"
|
||||
#include "webrtc/p2p/base/dtlstransportchannel.h"
|
||||
#include "webrtc/p2p/base/p2pconstants.h"
|
||||
#include "webrtc/p2p/base/p2ptransportchannel.h"
|
||||
#include "webrtc/p2p/base/port.h"
|
||||
#include "webrtc/p2p/base/transportchannelimpl.h"
|
||||
#include "webrtc/base/bind.h"
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
@ -126,7 +127,7 @@ JsepTransport::JsepTransport(
|
||||
const rtc::scoped_refptr<rtc::RTCCertificate>& certificate)
|
||||
: mid_(mid), certificate_(certificate) {}
|
||||
|
||||
bool JsepTransport::AddChannel(DtlsTransportInternal* dtls, int component) {
|
||||
bool JsepTransport::AddChannel(TransportChannelImpl* dtls, int component) {
|
||||
if (channels_.find(component) != channels_.end()) {
|
||||
LOG(LS_ERROR) << "Adding channel for component " << component << " twice.";
|
||||
return false;
|
||||
@ -285,14 +286,13 @@ bool JsepTransport::GetStats(TransportStats* stats) {
|
||||
stats->transport_name = mid();
|
||||
stats->channel_stats.clear();
|
||||
for (auto& kv : channels_) {
|
||||
DtlsTransportInternal* dtls_transport = kv.second;
|
||||
TransportChannelImpl* channel = kv.second;
|
||||
TransportChannelStats substats;
|
||||
substats.component = kv.first;
|
||||
dtls_transport->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
|
||||
dtls_transport->GetSslCipherSuite(&substats.ssl_cipher_suite);
|
||||
substats.dtls_state = dtls_transport->dtls_state();
|
||||
if (!dtls_transport->ice_transport()->GetStats(
|
||||
&substats.connection_infos)) {
|
||||
channel->GetSrtpCryptoSuite(&substats.srtp_crypto_suite);
|
||||
channel->GetSslCipherSuite(&substats.ssl_cipher_suite);
|
||||
substats.dtls_state = channel->dtls_state();
|
||||
if (!channel->GetStats(&substats.connection_infos)) {
|
||||
return false;
|
||||
}
|
||||
stats->channel_stats.push_back(substats);
|
||||
@ -325,39 +325,36 @@ bool JsepTransport::VerifyCertificateFingerprint(
|
||||
}
|
||||
|
||||
bool JsepTransport::ApplyLocalTransportDescription(
|
||||
DtlsTransportInternal* dtls_transport,
|
||||
TransportChannelImpl* channel,
|
||||
std::string* error_desc) {
|
||||
dtls_transport->ice_transport()->SetIceParameters(
|
||||
local_description_->GetIceParameters());
|
||||
channel->SetIceParameters(local_description_->GetIceParameters());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsepTransport::ApplyRemoteTransportDescription(
|
||||
DtlsTransportInternal* dtls_transport,
|
||||
TransportChannelImpl* channel,
|
||||
std::string* error_desc) {
|
||||
// Currently, all ICE-related calls still go through this DTLS channel. But
|
||||
// that will change once we get rid of TransportChannelImpl, and the DTLS
|
||||
// channel interface no longer includes ICE-specific methods. Then this class
|
||||
// will need to call dtls->ice()->SetIceRole(), for example, assuming the Dtls
|
||||
// interface will expose its inner ICE channel.
|
||||
dtls_transport->ice_transport()->SetRemoteIceParameters(
|
||||
remote_description_->GetIceParameters());
|
||||
dtls_transport->ice_transport()->SetRemoteIceMode(
|
||||
remote_description_->ice_mode);
|
||||
channel->SetRemoteIceParameters(remote_description_->GetIceParameters());
|
||||
channel->SetRemoteIceMode(remote_description_->ice_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsepTransport::ApplyNegotiatedTransportDescription(
|
||||
DtlsTransportInternal* dtls_transport,
|
||||
TransportChannelImpl* channel,
|
||||
std::string* error_desc) {
|
||||
// Set SSL role. Role must be set before fingerprint is applied, which
|
||||
// initiates DTLS setup.
|
||||
if (!dtls_transport->SetSslRole(secure_role_)) {
|
||||
if (!channel->SetSslRole(secure_role_)) {
|
||||
return BadTransportDescription("Failed to set SSL role for the channel.",
|
||||
error_desc);
|
||||
}
|
||||
// Apply remote fingerprint.
|
||||
if (!dtls_transport->SetRemoteFingerprint(
|
||||
if (!channel->SetRemoteFingerprint(
|
||||
remote_fingerprint_->algorithm,
|
||||
reinterpret_cast<const uint8_t*>(remote_fingerprint_->digest.data()),
|
||||
remote_fingerprint_->digest.size())) {
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class DtlsTransportInternal;
|
||||
class TransportChannelImpl;
|
||||
class TransportChannelImpl;
|
||||
enum class IceCandidatePairState;
|
||||
|
||||
typedef std::vector<Candidate> Candidates;
|
||||
@ -246,7 +247,7 @@ class JsepTransport : public sigslot::has_slots<> {
|
||||
// Add or remove channel that is affected when a local/remote transport
|
||||
// description is set on this transport. Need to add all channels before
|
||||
// setting a transport description.
|
||||
bool AddChannel(DtlsTransportInternal* dtls, int component);
|
||||
bool AddChannel(TransportChannelImpl* dtls, int component);
|
||||
bool RemoveChannel(int component);
|
||||
bool HasChannels() const;
|
||||
|
||||
@ -332,18 +333,17 @@ class JsepTransport : public sigslot::has_slots<> {
|
||||
|
||||
// Pushes down the transport parameters from the local description, such
|
||||
// as the ICE ufrag and pwd.
|
||||
bool ApplyLocalTransportDescription(DtlsTransportInternal* dtls_transport,
|
||||
bool ApplyLocalTransportDescription(TransportChannelImpl* channel,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters from the remote description to the
|
||||
// transport channel.
|
||||
bool ApplyRemoteTransportDescription(DtlsTransportInternal* dtls_transport,
|
||||
bool ApplyRemoteTransportDescription(TransportChannelImpl* channel,
|
||||
std::string* error_desc);
|
||||
|
||||
// Pushes down the transport parameters obtained via negotiation.
|
||||
bool ApplyNegotiatedTransportDescription(
|
||||
DtlsTransportInternal* dtls_transport,
|
||||
std::string* error_desc);
|
||||
bool ApplyNegotiatedTransportDescription(TransportChannelImpl* channel,
|
||||
std::string* error_desc);
|
||||
|
||||
const std::string mid_;
|
||||
// needs-ice-restart bit as described in JSEP.
|
||||
@ -357,7 +357,7 @@ class JsepTransport : public sigslot::has_slots<> {
|
||||
bool remote_description_set_ = false;
|
||||
|
||||
// Candidate component => DTLS channel
|
||||
std::map<int, DtlsTransportInternal*> channels_;
|
||||
std::map<int, TransportChannelImpl*> channels_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
|
||||
};
|
||||
|
||||
@ -17,8 +17,7 @@
|
||||
|
||||
using cricket::JsepTransport;
|
||||
using cricket::TransportChannel;
|
||||
using cricket::FakeDtlsTransport;
|
||||
using cricket::FakeIceTransport;
|
||||
using cricket::FakeTransportChannel;
|
||||
using cricket::IceRole;
|
||||
using cricket::TransportDescription;
|
||||
using rtc::SocketAddress;
|
||||
@ -34,15 +33,15 @@ class JsepTransportTest : public testing::Test, public sigslot::has_slots<> {
|
||||
JsepTransportTest()
|
||||
: transport_(new JsepTransport("test content name", nullptr)) {}
|
||||
bool SetupChannel() {
|
||||
fake_ice_channel_.reset(new FakeIceTransport(transport_->mid(), 1));
|
||||
fake_dtls_transport_.reset(new FakeDtlsTransport(fake_ice_channel_.get()));
|
||||
return transport_->AddChannel(fake_dtls_transport_.get(), 1);
|
||||
fake_ice_channel_.reset(new FakeTransportChannel(transport_->mid(), 1));
|
||||
fake_dtls_channel_.reset(new FakeTransportChannel(transport_->mid(), 1));
|
||||
return transport_->AddChannel(fake_dtls_channel_.get(), 1);
|
||||
}
|
||||
void DestroyChannel() { transport_->RemoveChannel(1); }
|
||||
|
||||
protected:
|
||||
std::unique_ptr<FakeDtlsTransport> fake_dtls_transport_;
|
||||
std::unique_ptr<FakeIceTransport> fake_ice_channel_;
|
||||
std::unique_ptr<FakeTransportChannel> fake_dtls_channel_;
|
||||
std::unique_ptr<FakeTransportChannel> fake_ice_channel_;
|
||||
std::unique_ptr<JsepTransport> transport_;
|
||||
};
|
||||
|
||||
@ -53,16 +52,16 @@ TEST_F(JsepTransportTest, TestChannelIceParameters) {
|
||||
ASSERT_TRUE(transport_->SetLocalTransportDescription(
|
||||
local_desc, cricket::CA_OFFER, NULL));
|
||||
EXPECT_TRUE(SetupChannel());
|
||||
EXPECT_EQ(cricket::ICEMODE_FULL, fake_dtls_transport_->remote_ice_mode());
|
||||
EXPECT_EQ(kIceUfrag1, fake_dtls_transport_->ice_ufrag());
|
||||
EXPECT_EQ(kIcePwd1, fake_dtls_transport_->ice_pwd());
|
||||
EXPECT_EQ(cricket::ICEMODE_FULL, fake_dtls_channel_->remote_ice_mode());
|
||||
EXPECT_EQ(kIceUfrag1, fake_dtls_channel_->ice_ufrag());
|
||||
EXPECT_EQ(kIcePwd1, fake_dtls_channel_->ice_pwd());
|
||||
|
||||
cricket::TransportDescription remote_desc(kIceUfrag1, kIcePwd1);
|
||||
ASSERT_TRUE(transport_->SetRemoteTransportDescription(
|
||||
remote_desc, cricket::CA_ANSWER, NULL));
|
||||
EXPECT_EQ(cricket::ICEMODE_FULL, fake_dtls_transport_->remote_ice_mode());
|
||||
EXPECT_EQ(kIceUfrag1, fake_dtls_transport_->remote_ice_ufrag());
|
||||
EXPECT_EQ(kIcePwd1, fake_dtls_transport_->remote_ice_pwd());
|
||||
EXPECT_EQ(cricket::ICEMODE_FULL, fake_dtls_channel_->remote_ice_mode());
|
||||
EXPECT_EQ(kIceUfrag1, fake_dtls_channel_->remote_ice_ufrag());
|
||||
EXPECT_EQ(kIcePwd1, fake_dtls_channel_->remote_ice_pwd());
|
||||
}
|
||||
|
||||
// Verifies that IceCredentialsChanged returns true when either ufrag or pwd
|
||||
@ -113,7 +112,7 @@ TEST_F(JsepTransportTest, TestGetStats) {
|
||||
EXPECT_TRUE(SetupChannel());
|
||||
cricket::TransportStats stats;
|
||||
EXPECT_TRUE(transport_->GetStats(&stats));
|
||||
// Note that this tests the behavior of a FakeIceTransport.
|
||||
// Note that this tests the behavior of a FakeTransportChannel.
|
||||
ASSERT_EQ(1U, stats.channel_stats.size());
|
||||
EXPECT_EQ(1, stats.channel_stats[0].component);
|
||||
// Set local transport description for FakeTransport before connecting.
|
||||
|
||||
@ -14,8 +14,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// This is included for PacketOptions.
|
||||
#include "webrtc/base/asyncpacketsocket.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/socket.h"
|
||||
|
||||
@ -33,7 +31,7 @@ class PacketTransportInterface : public sigslot::has_slots<> {
|
||||
virtual ~PacketTransportInterface() {}
|
||||
|
||||
// Identify the object for logging and debug purpose.
|
||||
virtual std::string debug_name() const = 0;
|
||||
virtual const std::string debug_name() const = 0;
|
||||
|
||||
// The transport has been established.
|
||||
virtual bool writable() const = 0;
|
||||
|
||||
70
webrtc/p2p/base/transportchannel.cc
Normal file
70
webrtc/p2p/base/transportchannel.cc
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2004 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 <sstream>
|
||||
#include "webrtc/p2p/base/common.h"
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
std::string TransportChannel::ToString() const {
|
||||
const char RECEIVING_ABBREV[2] = { '_', 'R' };
|
||||
const char WRITABLE_ABBREV[2] = { '_', 'W' };
|
||||
std::stringstream ss;
|
||||
ss << "Channel[" << transport_name_ << "|" << component_ << "|"
|
||||
<< RECEIVING_ABBREV[receiving_] << WRITABLE_ABBREV[writable_] << "]";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void TransportChannel::set_receiving(bool receiving) {
|
||||
if (receiving_ == receiving) {
|
||||
return;
|
||||
}
|
||||
receiving_ = receiving;
|
||||
SignalReceivingState(this);
|
||||
}
|
||||
|
||||
void TransportChannel::set_writable(bool writable) {
|
||||
if (writable_ == writable) {
|
||||
return;
|
||||
}
|
||||
LOG_J(LS_VERBOSE, this) << "set_writable from:" << writable_ << " to "
|
||||
<< writable;
|
||||
writable_ = writable;
|
||||
if (writable_) {
|
||||
SignalReadyToSend(this);
|
||||
}
|
||||
SignalWritableState(this);
|
||||
}
|
||||
|
||||
void TransportChannel::set_dtls_state(DtlsTransportState state) {
|
||||
if (dtls_state_ == state) {
|
||||
return;
|
||||
}
|
||||
LOG_J(LS_VERBOSE, this) << "set_dtls_state from:" << dtls_state_ << " to "
|
||||
<< state;
|
||||
dtls_state_ = state;
|
||||
SignalDtlsState(this, state);
|
||||
}
|
||||
|
||||
bool TransportChannel::SetSrtpCryptoSuites(const std::vector<int>& ciphers) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO(guoweis): Remove this function once everything is moved away.
|
||||
bool TransportChannel::SetSrtpCiphers(const std::vector<std::string>& ciphers) {
|
||||
std::vector<int> crypto_suites;
|
||||
for (const auto cipher : ciphers) {
|
||||
crypto_suites.push_back(rtc::SrtpCryptoSuiteFromName(cipher));
|
||||
}
|
||||
return SetSrtpCryptoSuites(crypto_suites);
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
163
webrtc/p2p/base/transportchannel.h
Normal file
163
webrtc/p2p/base/transportchannel.h
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 2004 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_TRANSPORTCHANNEL_H_
|
||||
#define WEBRTC_P2P_BASE_TRANSPORTCHANNEL_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/asyncpacketsocket.h"
|
||||
#include "webrtc/base/basictypes.h"
|
||||
#include "webrtc/base/constructormagic.h"
|
||||
#include "webrtc/base/dscp.h"
|
||||
#include "webrtc/base/sigslot.h"
|
||||
#include "webrtc/base/socket.h"
|
||||
#include "webrtc/base/sslidentity.h"
|
||||
#include "webrtc/base/sslstreamadapter.h"
|
||||
#include "webrtc/p2p/base/candidate.h"
|
||||
#include "webrtc/p2p/base/candidatepairinterface.h"
|
||||
#include "webrtc/p2p/base/icetransportinternal.h"
|
||||
#include "webrtc/p2p/base/jseptransport.h"
|
||||
#include "webrtc/p2p/base/packettransportinterface.h"
|
||||
#include "webrtc/p2p/base/transportdescription.h"
|
||||
|
||||
namespace cricket {
|
||||
|
||||
class Candidate;
|
||||
|
||||
// Flags for SendPacket/SignalReadPacket.
|
||||
enum PacketFlags {
|
||||
PF_NORMAL = 0x00, // A normal packet.
|
||||
PF_SRTP_BYPASS = 0x01, // An encrypted SRTP packet; bypass any additional
|
||||
// crypto provided by the transport (e.g. DTLS)
|
||||
};
|
||||
|
||||
// A TransportChannel represents one logical stream of packets that are sent
|
||||
// between the two sides of a session.
|
||||
// TODO(deadbeef): This interface currently represents the unity of an ICE
|
||||
// transport and a DTLS transport. They need to be separated apart.
|
||||
class TransportChannel : public rtc::PacketTransportInterface {
|
||||
public:
|
||||
TransportChannel(const std::string& transport_name, int component)
|
||||
: transport_name_(transport_name),
|
||||
component_(component),
|
||||
writable_(false),
|
||||
receiving_(false) {}
|
||||
virtual ~TransportChannel() {}
|
||||
|
||||
// TODO(guoweis) - Make this pure virtual once all subclasses of
|
||||
// TransportChannel have this defined.
|
||||
virtual IceTransportState GetState() const {
|
||||
return IceTransportState::STATE_CONNECTING;
|
||||
}
|
||||
|
||||
const std::string& transport_name() const { return transport_name_; }
|
||||
int component() const { return component_; }
|
||||
const std::string debug_name() const override {
|
||||
return transport_name() + " " + std::to_string(component());
|
||||
}
|
||||
|
||||
// Returns the states of this channel. Each time one of these states changes,
|
||||
// a signal is raised. These states are aggregated by the TransportManager.
|
||||
bool writable() const override { return writable_; }
|
||||
bool receiving() const override { return receiving_; }
|
||||
DtlsTransportState dtls_state() const { return dtls_state_; }
|
||||
// Emitted whenever DTLS-SRTP is setup which will require setting up a new
|
||||
// SRTP context.
|
||||
sigslot::signal2<TransportChannel*, DtlsTransportState> SignalDtlsState;
|
||||
|
||||
// Returns the current stats for this connection.
|
||||
virtual bool GetStats(ConnectionInfos* infos) = 0;
|
||||
|
||||
// Is DTLS active?
|
||||
virtual bool IsDtlsActive() const = 0;
|
||||
|
||||
// Default implementation.
|
||||
virtual bool GetSslRole(rtc::SSLRole* role) const = 0;
|
||||
|
||||
// Sets up the ciphers to use for DTLS-SRTP. TODO(guoweis): Make this pure
|
||||
// virtual once all dependencies have implementation.
|
||||
virtual bool SetSrtpCryptoSuites(const std::vector<int>& ciphers);
|
||||
|
||||
// Keep the original one for backward compatibility until all dependencies
|
||||
// move away. TODO(guoweis): Remove this function.
|
||||
virtual bool SetSrtpCiphers(const std::vector<std::string>& ciphers);
|
||||
|
||||
// Finds out which DTLS-SRTP cipher was negotiated.
|
||||
// TODO(guoweis): Remove this once all dependencies implement this.
|
||||
virtual bool GetSrtpCryptoSuite(int* cipher) { return false; }
|
||||
|
||||
// Finds out which DTLS cipher was negotiated.
|
||||
// TODO(guoweis): Remove this once all dependencies implement this.
|
||||
virtual bool GetSslCipherSuite(int* cipher) { return false; }
|
||||
|
||||
// Gets the local RTCCertificate used for DTLS.
|
||||
virtual rtc::scoped_refptr<rtc::RTCCertificate>
|
||||
GetLocalCertificate() const = 0;
|
||||
|
||||
// Gets a copy of the remote side's SSL certificate.
|
||||
virtual std::unique_ptr<rtc::SSLCertificate> GetRemoteSSLCertificate()
|
||||
const = 0;
|
||||
|
||||
// Allows key material to be extracted for external encryption.
|
||||
virtual bool ExportKeyingMaterial(const std::string& label,
|
||||
const uint8_t* context,
|
||||
size_t context_len,
|
||||
bool use_context,
|
||||
uint8_t* result,
|
||||
size_t result_len) = 0;
|
||||
|
||||
// Deprecated by SignalSelectedCandidatePairChanged
|
||||
// This signal occurs when there is a change in the way that packets are
|
||||
// being routed, i.e. to a different remote location. The candidate
|
||||
// indicates where and how we are currently sending media.
|
||||
sigslot::signal2<TransportChannel*, const Candidate&> SignalRouteChange;
|
||||
|
||||
// Signalled when the current selected candidate pair has changed.
|
||||
// The first parameter is the transport channel that signals the event.
|
||||
// The second parameter is the new selected candidate pair. The third
|
||||
// parameter is the last packet id sent on the previous candidate pair.
|
||||
// The fourth parameter is a boolean which is true if the TransportChannel
|
||||
// is ready to send with this candidate pair.
|
||||
sigslot::signal4<TransportChannel*, CandidatePairInterface*, int, bool>
|
||||
SignalSelectedCandidatePairChanged;
|
||||
|
||||
// Invoked when the channel is being destroyed.
|
||||
sigslot::signal1<TransportChannel*> SignalDestroyed;
|
||||
|
||||
// Debugging description of this transport channel.
|
||||
std::string ToString() const;
|
||||
|
||||
protected:
|
||||
// Sets the writable state, signaling if necessary.
|
||||
void set_writable(bool writable);
|
||||
|
||||
// Sets the receiving state, signaling if necessary.
|
||||
void set_receiving(bool receiving);
|
||||
|
||||
// Sets the DTLS state, signaling if necessary.
|
||||
void set_dtls_state(DtlsTransportState state);
|
||||
|
||||
private:
|
||||
// Used mostly for debugging.
|
||||
std::string transport_name_;
|
||||
int component_;
|
||||
bool writable_;
|
||||
bool receiving_;
|
||||
DtlsTransportState dtls_state_ = DTLS_TRANSPORT_NEW;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(TransportChannel);
|
||||
};
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
#endif // WEBRTC_P2P_BASE_TRANSPORTCHANNEL_H_
|
||||
@ -45,22 +45,22 @@ namespace cricket {
|
||||
class TransportController::ChannelPair {
|
||||
public:
|
||||
// TODO(deadbeef): Change the types of |dtls| and |ice| to
|
||||
// DtlsTransport and P2PTransportChannelWrapper, once TransportChannelImpl is
|
||||
// removed.
|
||||
ChannelPair(DtlsTransportInternal* dtls, IceTransportInternal* ice)
|
||||
// DtlsTransportChannelWrapper and P2PTransportChannelWrapper,
|
||||
// once TransportChannelImpl is removed.
|
||||
ChannelPair(TransportChannelImpl* dtls, IceTransportInternal* ice)
|
||||
: ice_(ice), dtls_(dtls) {}
|
||||
|
||||
// Currently, all ICE-related calls still go through this DTLS channel. But
|
||||
// that will change once we get rid of TransportChannelImpl, and the DTLS
|
||||
// channel interface no longer includes ICE-specific methods.
|
||||
const DtlsTransportInternal* dtls() const { return dtls_.get(); }
|
||||
DtlsTransportInternal* dtls() { return dtls_.get(); }
|
||||
const TransportChannelImpl* dtls() const { return dtls_.get(); }
|
||||
TransportChannelImpl* dtls() { return dtls_.get(); }
|
||||
const IceTransportInternal* ice() const { return ice_.get(); }
|
||||
IceTransportInternal* ice() { return ice_.get(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<IceTransportInternal> ice_;
|
||||
std::unique_ptr<DtlsTransportInternal> dtls_;
|
||||
std::unique_ptr<TransportChannelImpl> dtls_;
|
||||
|
||||
RTC_DISALLOW_COPY_AND_ASSIGN(ChannelPair);
|
||||
};
|
||||
@ -227,15 +227,15 @@ void TransportController::SetMetricsObserver(
|
||||
metrics_observer));
|
||||
}
|
||||
|
||||
DtlsTransportInternal* TransportController::CreateDtlsTransport(
|
||||
TransportChannel* TransportController::CreateTransportChannel(
|
||||
const std::string& transport_name,
|
||||
int component) {
|
||||
return network_thread_->Invoke<DtlsTransportInternal*>(
|
||||
RTC_FROM_HERE, rtc::Bind(&TransportController::CreateDtlsTransport_n,
|
||||
return network_thread_->Invoke<TransportChannel*>(
|
||||
RTC_FROM_HERE, rtc::Bind(&TransportController::CreateTransportChannel_n,
|
||||
this, transport_name, component));
|
||||
}
|
||||
|
||||
DtlsTransportInternal* TransportController::CreateDtlsTransport_n(
|
||||
TransportChannel* TransportController::CreateTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
@ -256,12 +256,12 @@ DtlsTransportInternal* TransportController::CreateDtlsTransport_n(
|
||||
// TODO(deadbeef): To support QUIC, would need to create a
|
||||
// QuicTransportChannel here. What is "dtls" in this file would then become
|
||||
// "dtls or quic".
|
||||
DtlsTransportInternal* dtls =
|
||||
TransportChannelImpl* dtls =
|
||||
CreateDtlsTransportChannel_n(transport_name, component, ice);
|
||||
dtls->ice_transport()->SetMetricsObserver(metrics_observer_);
|
||||
dtls->ice_transport()->SetIceRole(ice_role_);
|
||||
dtls->ice_transport()->SetIceTiebreaker(ice_tiebreaker_);
|
||||
dtls->ice_transport()->SetIceConfig(ice_config_);
|
||||
dtls->SetMetricsObserver(metrics_observer_);
|
||||
dtls->SetIceRole(ice_role_);
|
||||
dtls->SetIceTiebreaker(ice_tiebreaker_);
|
||||
dtls->SetIceConfig(ice_config_);
|
||||
if (certificate_) {
|
||||
bool set_cert_success = dtls->SetLocalCertificate(certificate_);
|
||||
RTC_DCHECK(set_cert_success);
|
||||
@ -274,18 +274,18 @@ DtlsTransportInternal* TransportController::CreateDtlsTransport_n(
|
||||
this, &TransportController::OnChannelWritableState_n);
|
||||
dtls->SignalReceivingState.connect(
|
||||
this, &TransportController::OnChannelReceivingState_n);
|
||||
dtls->SignalGatheringState.connect(
|
||||
this, &TransportController::OnChannelGatheringState_n);
|
||||
dtls->SignalCandidateGathered.connect(
|
||||
this, &TransportController::OnChannelCandidateGathered_n);
|
||||
dtls->SignalCandidatesRemoved.connect(
|
||||
this, &TransportController::OnChannelCandidatesRemoved_n);
|
||||
dtls->SignalRoleConflict.connect(
|
||||
this, &TransportController::OnChannelRoleConflict_n);
|
||||
dtls->SignalStateChanged.connect(
|
||||
this, &TransportController::OnChannelStateChanged_n);
|
||||
dtls->SignalDtlsHandshakeError.connect(
|
||||
this, &TransportController::OnDtlsHandshakeError);
|
||||
dtls->ice_transport()->SignalGatheringState.connect(
|
||||
this, &TransportController::OnChannelGatheringState_n);
|
||||
dtls->ice_transport()->SignalCandidateGathered.connect(
|
||||
this, &TransportController::OnChannelCandidateGathered_n);
|
||||
dtls->ice_transport()->SignalCandidatesRemoved.connect(
|
||||
this, &TransportController::OnChannelCandidatesRemoved_n);
|
||||
dtls->ice_transport()->SignalRoleConflict.connect(
|
||||
this, &TransportController::OnChannelRoleConflict_n);
|
||||
dtls->ice_transport()->SignalStateChanged.connect(
|
||||
this, &TransportController::OnChannelStateChanged_n);
|
||||
RefCountedChannel* new_pair = new RefCountedChannel(dtls, ice);
|
||||
new_pair->AddRef();
|
||||
channels_.insert(channels_.end(), new_pair);
|
||||
@ -296,15 +296,15 @@ DtlsTransportInternal* TransportController::CreateDtlsTransport_n(
|
||||
return dtls;
|
||||
}
|
||||
|
||||
void TransportController::DestroyDtlsTransport(
|
||||
void TransportController::DestroyTransportChannel(
|
||||
const std::string& transport_name,
|
||||
int component) {
|
||||
network_thread_->Invoke<void>(
|
||||
RTC_FROM_HERE, rtc::Bind(&TransportController::DestroyDtlsTransport_n,
|
||||
RTC_FROM_HERE, rtc::Bind(&TransportController::DestroyTransportChannel_n,
|
||||
this, transport_name, component));
|
||||
}
|
||||
|
||||
void TransportController::DestroyDtlsTransport_n(
|
||||
void TransportController::DestroyTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
@ -340,16 +340,15 @@ std::vector<std::string> TransportController::transport_names_for_testing() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<DtlsTransportInternal*>
|
||||
TransportController::channels_for_testing() {
|
||||
std::vector<DtlsTransportInternal*> ret;
|
||||
std::vector<TransportChannelImpl*> TransportController::channels_for_testing() {
|
||||
std::vector<TransportChannelImpl*> ret;
|
||||
for (RefCountedChannel* channel : channels_) {
|
||||
ret.push_back(channel->dtls());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DtlsTransportInternal* TransportController::get_channel_for_testing(
|
||||
TransportChannelImpl* TransportController::get_channel_for_testing(
|
||||
const std::string& transport_name,
|
||||
int component) {
|
||||
RefCountedChannel* ch = GetChannel_n(transport_name, component);
|
||||
@ -362,11 +361,11 @@ IceTransportInternal* TransportController::CreateIceTransportChannel_n(
|
||||
return new P2PTransportChannel(transport_name, component, port_allocator_);
|
||||
}
|
||||
|
||||
DtlsTransportInternal* TransportController::CreateDtlsTransportChannel_n(
|
||||
TransportChannelImpl* TransportController::CreateDtlsTransportChannel_n(
|
||||
const std::string&,
|
||||
int,
|
||||
IceTransportInternal* ice) {
|
||||
DtlsTransport* dtls = new DtlsTransport(ice);
|
||||
DtlsTransportChannelWrapper* dtls = new DtlsTransportChannelWrapper(ice);
|
||||
dtls->SetSslMaxProtocolVersion(ssl_max_version_);
|
||||
return dtls;
|
||||
}
|
||||
@ -504,7 +503,7 @@ void TransportController::SetIceConfig_n(const IceConfig& config) {
|
||||
|
||||
ice_config_ = config;
|
||||
for (auto& channel : channels_) {
|
||||
channel->dtls()->ice_transport()->SetIceConfig(ice_config_);
|
||||
channel->dtls()->SetIceConfig(ice_config_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -513,7 +512,7 @@ void TransportController::SetIceRole_n(IceRole ice_role) {
|
||||
|
||||
ice_role_ = ice_role;
|
||||
for (auto& channel : channels_) {
|
||||
channel->dtls()->ice_transport()->SetIceRole(ice_role_);
|
||||
channel->dtls()->SetIceRole(ice_role_);
|
||||
}
|
||||
}
|
||||
|
||||
@ -645,7 +644,7 @@ bool TransportController::SetRemoteTransportDescription_n(
|
||||
|
||||
void TransportController::MaybeStartGathering_n() {
|
||||
for (auto& channel : channels_) {
|
||||
channel->dtls()->ice_transport()->MaybeStartGathering();
|
||||
channel->dtls()->MaybeStartGathering();
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,7 +674,7 @@ bool TransportController::AddRemoteCandidates_n(
|
||||
" for content: " + transport_name;
|
||||
return false;
|
||||
}
|
||||
channel->dtls()->ice_transport()->AddRemoteCandidate(candidate);
|
||||
channel->dtls()->AddRemoteCandidate(candidate);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -709,7 +708,7 @@ bool TransportController::RemoveRemoteCandidates_n(const Candidates& candidates,
|
||||
RefCountedChannel* channel =
|
||||
GetChannel_n(transport_name, candidate.component());
|
||||
if (channel) {
|
||||
channel->dtls()->ice_transport()->RemoveRemoteCandidate(candidate);
|
||||
channel->dtls()->RemoveRemoteCandidate(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -743,7 +742,7 @@ void TransportController::SetMetricsObserver_n(
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
metrics_observer_ = metrics_observer;
|
||||
for (auto& channel : channels_) {
|
||||
channel->dtls()->ice_transport()->SetMetricsObserver(metrics_observer);
|
||||
channel->dtls()->SetMetricsObserver(metrics_observer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -762,13 +761,13 @@ void TransportController::OnChannelReceivingState_n(
|
||||
}
|
||||
|
||||
void TransportController::OnChannelGatheringState_n(
|
||||
IceTransportInternal* channel) {
|
||||
TransportChannelImpl* channel) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
UpdateAggregateStates_n();
|
||||
}
|
||||
|
||||
void TransportController::OnChannelCandidateGathered_n(
|
||||
IceTransportInternal* channel,
|
||||
TransportChannelImpl* channel,
|
||||
const Candidate& candidate) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
|
||||
@ -785,7 +784,7 @@ void TransportController::OnChannelCandidateGathered_n(
|
||||
}
|
||||
|
||||
void TransportController::OnChannelCandidatesRemoved_n(
|
||||
IceTransportInternal* channel,
|
||||
TransportChannelImpl* channel,
|
||||
const Candidates& candidates) {
|
||||
invoker_.AsyncInvoke<void>(
|
||||
RTC_FROM_HERE, signaling_thread_,
|
||||
@ -800,7 +799,7 @@ void TransportController::OnChannelCandidatesRemoved(
|
||||
}
|
||||
|
||||
void TransportController::OnChannelRoleConflict_n(
|
||||
IceTransportInternal* channel) {
|
||||
TransportChannelImpl* channel) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
// Note: since the role conflict is handled entirely on the network thread,
|
||||
// we don't need to worry about role conflicts occurring on two ports at once.
|
||||
@ -816,7 +815,7 @@ void TransportController::OnChannelRoleConflict_n(
|
||||
}
|
||||
|
||||
void TransportController::OnChannelStateChanged_n(
|
||||
IceTransportInternal* channel) {
|
||||
TransportChannelImpl* channel) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
LOG(LS_INFO) << channel->transport_name() << " TransportChannel "
|
||||
<< channel->component()
|
||||
@ -838,23 +837,20 @@ void TransportController::UpdateAggregateStates_n() {
|
||||
for (const auto& channel : channels_) {
|
||||
any_receiving = any_receiving || channel->dtls()->receiving();
|
||||
any_failed = any_failed ||
|
||||
channel->dtls()->ice_transport()->GetState() ==
|
||||
IceTransportState::STATE_FAILED;
|
||||
channel->dtls()->GetState() == IceTransportState::STATE_FAILED;
|
||||
all_connected = all_connected && channel->dtls()->writable();
|
||||
all_completed =
|
||||
all_completed && channel->dtls()->writable() &&
|
||||
channel->dtls()->ice_transport()->GetState() ==
|
||||
IceTransportState::STATE_COMPLETED &&
|
||||
channel->dtls()->ice_transport()->GetIceRole() == ICEROLE_CONTROLLING &&
|
||||
channel->dtls()->ice_transport()->gathering_state() ==
|
||||
kIceGatheringComplete;
|
||||
channel->dtls()->GetState() == IceTransportState::STATE_COMPLETED &&
|
||||
channel->dtls()->GetIceRole() == ICEROLE_CONTROLLING &&
|
||||
channel->dtls()->gathering_state() == kIceGatheringComplete;
|
||||
any_gathering =
|
||||
any_gathering ||
|
||||
channel->dtls()->ice_transport()->gathering_state() != kIceGatheringNew;
|
||||
all_done_gathering = all_done_gathering &&
|
||||
channel->dtls()->ice_transport()->gathering_state() ==
|
||||
kIceGatheringComplete;
|
||||
any_gathering || channel->dtls()->gathering_state() != kIceGatheringNew;
|
||||
all_done_gathering =
|
||||
all_done_gathering &&
|
||||
channel->dtls()->gathering_state() == kIceGatheringComplete;
|
||||
}
|
||||
|
||||
if (any_failed) {
|
||||
new_connection_state = kIceConnectionFailed;
|
||||
} else if (all_completed) {
|
||||
|
||||
@ -113,18 +113,18 @@ class TransportController : public sigslot::has_slots<>,
|
||||
|
||||
// Creates a channel if it doesn't exist. Otherwise, increments a reference
|
||||
// count and returns an existing channel.
|
||||
DtlsTransportInternal* CreateDtlsTransport(const std::string& transport_name,
|
||||
int component);
|
||||
virtual DtlsTransportInternal* CreateDtlsTransport_n(
|
||||
TransportChannel* CreateTransportChannel(const std::string& transport_name,
|
||||
int component);
|
||||
virtual TransportChannel* CreateTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component);
|
||||
|
||||
// Decrements a channel's reference count, and destroys the channel if
|
||||
// nothing is referencing it.
|
||||
virtual void DestroyDtlsTransport(const std::string& transport_name,
|
||||
int component);
|
||||
virtual void DestroyDtlsTransport_n(const std::string& transport_name,
|
||||
int component);
|
||||
virtual void DestroyTransportChannel(const std::string& transport_name,
|
||||
int component);
|
||||
virtual void DestroyTransportChannel_n(const std::string& transport_name,
|
||||
int component);
|
||||
|
||||
void use_quic() { quic_ = true; }
|
||||
bool quic() const { return quic_; }
|
||||
@ -135,8 +135,8 @@ class TransportController : public sigslot::has_slots<>,
|
||||
return certificate_;
|
||||
}
|
||||
std::vector<std::string> transport_names_for_testing();
|
||||
std::vector<DtlsTransportInternal*> channels_for_testing();
|
||||
DtlsTransportInternal* get_channel_for_testing(
|
||||
std::vector<TransportChannelImpl*> channels_for_testing();
|
||||
TransportChannelImpl* get_channel_for_testing(
|
||||
const std::string& transport_name,
|
||||
int component);
|
||||
|
||||
@ -171,7 +171,7 @@ class TransportController : public sigslot::has_slots<>,
|
||||
virtual IceTransportInternal* CreateIceTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component);
|
||||
virtual DtlsTransportInternal* CreateDtlsTransportChannel_n(
|
||||
virtual TransportChannelImpl* CreateDtlsTransportChannel_n(
|
||||
const std::string& transport_name,
|
||||
int component,
|
||||
IceTransportInternal* ice);
|
||||
@ -233,14 +233,14 @@ class TransportController : public sigslot::has_slots<>,
|
||||
// Handlers for signals from Transport.
|
||||
void OnChannelWritableState_n(rtc::PacketTransportInterface* transport);
|
||||
void OnChannelReceivingState_n(rtc::PacketTransportInterface* transport);
|
||||
void OnChannelGatheringState_n(IceTransportInternal* channel);
|
||||
void OnChannelCandidateGathered_n(IceTransportInternal* channel,
|
||||
void OnChannelGatheringState_n(TransportChannelImpl* channel);
|
||||
void OnChannelCandidateGathered_n(TransportChannelImpl* channel,
|
||||
const Candidate& candidate);
|
||||
void OnChannelCandidatesRemoved(const Candidates& candidates);
|
||||
void OnChannelCandidatesRemoved_n(IceTransportInternal* channel,
|
||||
void OnChannelCandidatesRemoved_n(TransportChannelImpl* channel,
|
||||
const Candidates& candidates);
|
||||
void OnChannelRoleConflict_n(IceTransportInternal* channel);
|
||||
void OnChannelStateChanged_n(IceTransportInternal* channel);
|
||||
void OnChannelRoleConflict_n(TransportChannelImpl* channel);
|
||||
void OnChannelStateChanged_n(TransportChannelImpl* channel);
|
||||
|
||||
void UpdateAggregateStates_n();
|
||||
|
||||
|
||||
@ -71,14 +71,15 @@ class TransportControllerTest : public testing::Test,
|
||||
this, &TransportControllerTest::OnCandidatesGathered);
|
||||
}
|
||||
|
||||
FakeDtlsTransport* CreateChannel(const std::string& content, int component) {
|
||||
DtlsTransportInternal* channel =
|
||||
transport_controller_->CreateDtlsTransport_n(content, component);
|
||||
return static_cast<FakeDtlsTransport*>(channel);
|
||||
FakeTransportChannel* CreateChannel(const std::string& content,
|
||||
int component) {
|
||||
TransportChannel* channel =
|
||||
transport_controller_->CreateTransportChannel_n(content, component);
|
||||
return static_cast<FakeTransportChannel*>(channel);
|
||||
}
|
||||
|
||||
void DestroyChannel(const std::string& content, int component) {
|
||||
transport_controller_->DestroyDtlsTransport_n(content, component);
|
||||
transport_controller_->DestroyTransportChannel_n(content, component);
|
||||
}
|
||||
|
||||
Candidate CreateCandidate(int component) {
|
||||
@ -101,9 +102,9 @@ class TransportControllerTest : public testing::Test,
|
||||
|
||||
void CreateChannelsAndCompleteConnection_w() {
|
||||
transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
|
||||
TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
|
||||
@ -115,10 +116,8 @@ class TransportControllerTest : public testing::Test,
|
||||
transport_controller_->SetLocalTransportDescription("video", local_desc,
|
||||
CA_OFFER, &err);
|
||||
transport_controller_->MaybeStartGathering();
|
||||
channel1->ice_transport()->SignalCandidateGathered(
|
||||
channel1->ice_transport(), CreateCandidate(1));
|
||||
channel2->ice_transport()->SignalCandidateGathered(
|
||||
channel2->ice_transport(), CreateCandidate(1));
|
||||
channel1->SignalCandidateGathered(channel1, CreateCandidate(1));
|
||||
channel2->SignalCandidateGathered(channel2, CreateCandidate(1));
|
||||
channel1->SetCandidatesGatheringComplete();
|
||||
channel2->SetCandidatesGatheringComplete();
|
||||
channel1->SetConnectionCount(2);
|
||||
@ -196,7 +195,7 @@ class TransportControllerTest : public testing::Test,
|
||||
};
|
||||
|
||||
TEST_F(TransportControllerTest, TestSetIceConfig) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
|
||||
transport_controller_->SetIceConfig(
|
||||
@ -207,7 +206,7 @@ TEST_F(TransportControllerTest, TestSetIceConfig) {
|
||||
transport_controller_->SetIceConfig(
|
||||
CreateIceConfig(1000, GATHER_CONTINUALLY_AND_RECOVER));
|
||||
// Test that value stored in controller is applied to new channels.
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
EXPECT_EQ(1000, channel2->receiving_timeout());
|
||||
EXPECT_TRUE(channel2->gather_continually());
|
||||
@ -216,7 +215,7 @@ TEST_F(TransportControllerTest, TestSetIceConfig) {
|
||||
TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) {
|
||||
EXPECT_TRUE(transport_controller_->SetSslMaxProtocolVersion(
|
||||
rtc::SSL_PROTOCOL_DTLS_12));
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
|
||||
ASSERT_NE(nullptr, channel);
|
||||
EXPECT_EQ(rtc::SSL_PROTOCOL_DTLS_12, channel->ssl_max_protocol_version());
|
||||
@ -227,7 +226,7 @@ TEST_F(TransportControllerTest, TestSetSslMaxProtocolVersion) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestSetIceRole) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
|
||||
transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
@ -236,7 +235,7 @@ TEST_F(TransportControllerTest, TestSetIceRole) {
|
||||
EXPECT_EQ(ICEROLE_CONTROLLED, channel1->GetIceRole());
|
||||
|
||||
// Test that value stored in controller is applied to new channels.
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
EXPECT_EQ(ICEROLE_CONTROLLED, channel2->GetIceRole());
|
||||
}
|
||||
@ -244,28 +243,28 @@ TEST_F(TransportControllerTest, TestSetIceRole) {
|
||||
// Test that when one channel encounters a role conflict, the ICE role is
|
||||
// swapped on every channel.
|
||||
TEST_F(TransportControllerTest, TestIceRoleConflict) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
|
||||
transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
EXPECT_EQ(ICEROLE_CONTROLLING, channel1->GetIceRole());
|
||||
EXPECT_EQ(ICEROLE_CONTROLLING, channel2->GetIceRole());
|
||||
|
||||
channel1->ice_transport()->SignalRoleConflict(channel1->ice_transport());
|
||||
channel1->SignalRoleConflict(channel1);
|
||||
EXPECT_EQ(ICEROLE_CONTROLLED, channel1->GetIceRole());
|
||||
EXPECT_EQ(ICEROLE_CONTROLLED, channel2->GetIceRole());
|
||||
|
||||
// Should be able to handle a second role conflict. The remote endpoint can
|
||||
// change its role/tie-breaker when it does an ICE restart.
|
||||
channel2->ice_transport()->SignalRoleConflict(channel2->ice_transport());
|
||||
channel2->SignalRoleConflict(channel2);
|
||||
EXPECT_EQ(ICEROLE_CONTROLLING, channel1->GetIceRole());
|
||||
EXPECT_EQ(ICEROLE_CONTROLLING, channel2->GetIceRole());
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestGetSslRole) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
ASSERT_TRUE(channel->SetSslRole(rtc::SSL_CLIENT));
|
||||
rtc::SSLRole role;
|
||||
@ -283,7 +282,7 @@ TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) {
|
||||
rtc::SSLIdentity::Generate("session2", rtc::KT_DEFAULT)));
|
||||
rtc::scoped_refptr<rtc::RTCCertificate> returned_certificate;
|
||||
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
|
||||
EXPECT_TRUE(transport_controller_->SetLocalCertificate(certificate1));
|
||||
@ -297,7 +296,7 @@ TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) {
|
||||
"video", &returned_certificate));
|
||||
|
||||
// Test that identity stored in controller is applied to new channels.
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
EXPECT_TRUE(transport_controller_->GetLocalCertificate(
|
||||
"video", &returned_certificate));
|
||||
@ -311,7 +310,7 @@ TEST_F(TransportControllerTest, TestSetAndGetLocalCertificate) {
|
||||
TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) {
|
||||
rtc::FakeSSLCertificate fake_certificate("fake_data");
|
||||
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
|
||||
channel->SetRemoteSSLCertificate(&fake_certificate);
|
||||
@ -326,7 +325,7 @@ TEST_F(TransportControllerTest, TestGetRemoteSSLCertificate) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
TransportDescription local_desc(std::vector<std::string>(), kIceUfrag1,
|
||||
kIcePwd1, ICEMODE_FULL,
|
||||
@ -345,7 +344,7 @@ TEST_F(TransportControllerTest, TestSetLocalTransportDescription) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
TransportDescription remote_desc(std::vector<std::string>(), kIceUfrag1,
|
||||
kIcePwd1, ICEMODE_FULL,
|
||||
@ -359,7 +358,7 @@ TEST_F(TransportControllerTest, TestSetRemoteTransportDescription) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestAddRemoteCandidates) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
Candidates candidates;
|
||||
candidates.push_back(CreateCandidate(1));
|
||||
@ -370,7 +369,7 @@ TEST_F(TransportControllerTest, TestAddRemoteCandidates) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
// We expect to be ready for remote candidates only after local and remote
|
||||
// descriptions are set.
|
||||
@ -393,11 +392,11 @@ TEST_F(TransportControllerTest, TestReadyForRemoteCandidates) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestGetStats) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("audio", 2);
|
||||
FakeTransportChannel* channel2 = CreateChannel("audio", 2);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
FakeDtlsTransport* channel3 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel3 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel3);
|
||||
|
||||
TransportStats stats;
|
||||
@ -408,12 +407,12 @@ TEST_F(TransportControllerTest, TestGetStats) {
|
||||
|
||||
// Test that transport gets destroyed when it has no more channels.
|
||||
TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
ASSERT_EQ(channel1, channel2);
|
||||
FakeDtlsTransport* channel3 = CreateChannel("audio", 2);
|
||||
FakeTransportChannel* channel3 = CreateChannel("audio", 2);
|
||||
ASSERT_NE(nullptr, channel3);
|
||||
|
||||
// Using GetStats to check if transport is destroyed from an outside class's
|
||||
@ -430,9 +429,9 @@ TEST_F(TransportControllerTest, TestCreateAndDestroyChannel) {
|
||||
TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) {
|
||||
// Need controlling ICE role to get in failed state.
|
||||
transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
|
||||
// Should signal "failed" if any channel failed; channel is considered failed
|
||||
@ -447,11 +446,11 @@ TEST_F(TransportControllerTest, TestSignalConnectionStateFailed) {
|
||||
|
||||
TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) {
|
||||
transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
FakeDtlsTransport* channel3 = CreateChannel("video", 2);
|
||||
FakeTransportChannel* channel3 = CreateChannel("video", 2);
|
||||
ASSERT_NE(nullptr, channel3);
|
||||
|
||||
// First, have one channel connect, and another fail, to ensure that
|
||||
@ -480,15 +479,15 @@ TEST_F(TransportControllerTest, TestSignalConnectionStateConnected) {
|
||||
|
||||
TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) {
|
||||
transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
FakeDtlsTransport* channel3 = CreateChannel("video", 2);
|
||||
FakeTransportChannel* channel3 = CreateChannel("video", 2);
|
||||
ASSERT_NE(nullptr, channel3);
|
||||
|
||||
// Similar to above test, but we're now reaching the completed state, which
|
||||
// means only one connection per FakeDtlsTransport.
|
||||
// means only one connection per FakeTransportChannel.
|
||||
channel1->SetCandidatesGatheringComplete();
|
||||
channel1->SetConnectionCount(1);
|
||||
channel1->SetWritable(true);
|
||||
@ -520,9 +519,9 @@ TEST_F(TransportControllerTest, TestSignalConnectionStateComplete) {
|
||||
// Make sure that if we're "connected" and remove a transport, we stay in the
|
||||
// "connected" state.
|
||||
TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
|
||||
channel1->SetCandidatesGatheringComplete();
|
||||
@ -546,7 +545,7 @@ TEST_F(TransportControllerTest, TestDestroyTransportAndStayConnected) {
|
||||
// If we destroy the last/only transport, we should simply transition to
|
||||
// "connecting".
|
||||
TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
|
||||
channel->SetCandidatesGatheringComplete();
|
||||
@ -562,9 +561,9 @@ TEST_F(TransportControllerTest, TestDestroyLastTransportWhileConnected) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestSignalReceiving) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
|
||||
// Should signal receiving as soon as any channel is receiving.
|
||||
@ -580,23 +579,23 @@ TEST_F(TransportControllerTest, TestSignalReceiving) {
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestSignalGatheringStateGathering) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
channel->ice_transport()->MaybeStartGathering();
|
||||
channel->MaybeStartGathering();
|
||||
// Should be in the gathering state as soon as any transport starts gathering.
|
||||
EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
|
||||
EXPECT_EQ(1, gathering_state_signal_count_);
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
FakeDtlsTransport* channel3 = CreateChannel("data", 1);
|
||||
FakeTransportChannel* channel3 = CreateChannel("data", 1);
|
||||
ASSERT_NE(nullptr, channel3);
|
||||
|
||||
channel3->ice_transport()->MaybeStartGathering();
|
||||
channel3->MaybeStartGathering();
|
||||
EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
|
||||
EXPECT_EQ(1, gathering_state_signal_count_);
|
||||
|
||||
@ -608,8 +607,8 @@ TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
|
||||
EXPECT_EQ(2, gathering_state_signal_count_);
|
||||
|
||||
// Make remaining channels start and then finish gathering.
|
||||
channel1->ice_transport()->MaybeStartGathering();
|
||||
channel2->ice_transport()->MaybeStartGathering();
|
||||
channel1->MaybeStartGathering();
|
||||
channel2->MaybeStartGathering();
|
||||
EXPECT_EQ_WAIT(kIceGatheringGathering, gathering_state_, kTimeout);
|
||||
EXPECT_EQ(3, gathering_state_signal_count_);
|
||||
|
||||
@ -626,9 +625,9 @@ TEST_F(TransportControllerTest, TestSignalGatheringStateComplete) {
|
||||
TEST_F(TransportControllerTest,
|
||||
TestSignalingWhenLastIncompleteTransportDestroyed) {
|
||||
transport_controller_->SetIceRole(ICEROLE_CONTROLLING);
|
||||
FakeDtlsTransport* channel1 = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel1 = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel1);
|
||||
FakeDtlsTransport* channel2 = CreateChannel("video", 1);
|
||||
FakeTransportChannel* channel2 = CreateChannel("video", 1);
|
||||
ASSERT_NE(nullptr, channel2);
|
||||
|
||||
channel1->SetCandidatesGatheringComplete();
|
||||
@ -645,7 +644,7 @@ TEST_F(TransportControllerTest,
|
||||
}
|
||||
|
||||
TEST_F(TransportControllerTest, TestSignalCandidatesGathered) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
|
||||
// Transport won't signal candidates until it has a local description.
|
||||
@ -657,8 +656,7 @@ TEST_F(TransportControllerTest, TestSignalCandidatesGathered) {
|
||||
"audio", local_desc, CA_OFFER, &err));
|
||||
transport_controller_->MaybeStartGathering();
|
||||
|
||||
channel->ice_transport()->SignalCandidateGathered(channel->ice_transport(),
|
||||
CreateCandidate(1));
|
||||
channel->SignalCandidateGathered(channel, CreateCandidate(1));
|
||||
EXPECT_EQ_WAIT(1, candidates_signal_count_, kTimeout);
|
||||
EXPECT_EQ(1U, candidates_["audio"].size());
|
||||
}
|
||||
@ -692,7 +690,7 @@ TEST_F(TransportControllerTest, TestSignalingOccursOnSignalingThread) {
|
||||
// TODO(deadbeef): Remove this when these old versions of Chrome reach a low
|
||||
// enough population.
|
||||
TEST_F(TransportControllerTest, IceRoleRedeterminedOnIceRestartByDefault) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
std::string err;
|
||||
// Do an initial offer answer, so that the next offer is an ICE restart.
|
||||
@ -725,7 +723,7 @@ TEST_F(TransportControllerTest, IceRoleRedeterminedOnIceRestartByDefault) {
|
||||
TEST_F(TransportControllerTest, IceRoleNotRedetermined) {
|
||||
bool redetermine_role = false;
|
||||
transport_controller_.reset(new TransportControllerForTest(redetermine_role));
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
std::string err;
|
||||
// Do an initial offer answer, so that the next offer is an ICE restart.
|
||||
@ -753,7 +751,7 @@ TEST_F(TransportControllerTest, IceRoleNotRedetermined) {
|
||||
|
||||
// Tests channel role is reversed after receiving ice-lite from remote.
|
||||
TEST_F(TransportControllerTest, TestSetRemoteIceLiteInOffer) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
std::string err;
|
||||
|
||||
@ -773,7 +771,7 @@ TEST_F(TransportControllerTest, TestSetRemoteIceLiteInOffer) {
|
||||
|
||||
// Tests ice-lite in remote answer.
|
||||
TEST_F(TransportControllerTest, TestSetRemoteIceLiteInAnswer) {
|
||||
FakeDtlsTransport* channel = CreateChannel("audio", 1);
|
||||
FakeTransportChannel* channel = CreateChannel("audio", 1);
|
||||
ASSERT_NE(nullptr, channel);
|
||||
std::string err;
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ class UdpTransport : public webrtc::UdpTransportInterface,
|
||||
rtc::SocketAddress GetRemoteAddress() const override;
|
||||
|
||||
// Overrides of PacketTransportInterface, used by webrtc internally.
|
||||
std::string debug_name() const override { return transport_name_; }
|
||||
const std::string debug_name() const override { return transport_name_; }
|
||||
|
||||
bool receiving() const override {
|
||||
// TODO(johan): Implement method and signal.
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "webrtc/media/base/mediaconstants.h"
|
||||
#include "webrtc/media/base/rtputils.h"
|
||||
#include "webrtc/p2p/base/packettransportinterface.h"
|
||||
#include "webrtc/p2p/base/transportchannel.h"
|
||||
#include "webrtc/pc/channelmanager.h"
|
||||
|
||||
namespace cricket {
|
||||
@ -197,11 +198,11 @@ void BaseChannel::DisconnectTransportChannels_n() {
|
||||
|
||||
// Stop signals from transport channels, but keep them alive because
|
||||
// media_channel may use them from a different thread.
|
||||
if (rtp_dtls_transport_) {
|
||||
DisconnectFromTransport(rtp_dtls_transport_);
|
||||
if (rtp_transport_) {
|
||||
DisconnectFromTransportChannel(rtp_transport_);
|
||||
}
|
||||
if (rtcp_dtls_transport_) {
|
||||
DisconnectFromTransport(rtcp_dtls_transport_);
|
||||
if (rtcp_transport_) {
|
||||
DisconnectFromTransportChannel(rtcp_transport_);
|
||||
}
|
||||
|
||||
// Clear pending read packets/messages.
|
||||
@ -209,11 +210,11 @@ void BaseChannel::DisconnectTransportChannels_n() {
|
||||
network_thread_->Clear(this);
|
||||
}
|
||||
|
||||
bool BaseChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport) {
|
||||
bool BaseChannel::Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport) {
|
||||
if (!network_thread_->Invoke<bool>(
|
||||
RTC_FROM_HERE, Bind(&BaseChannel::InitNetwork_n, this,
|
||||
rtp_dtls_transport, rtcp_dtls_transport))) {
|
||||
RTC_FROM_HERE, Bind(&BaseChannel::InitNetwork_n, this, rtp_transport,
|
||||
rtcp_transport))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -224,16 +225,15 @@ bool BaseChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseChannel::InitNetwork_n(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport) {
|
||||
bool BaseChannel::InitNetwork_n(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
SetTransports_n(rtp_dtls_transport, rtcp_dtls_transport);
|
||||
SetTransports_n(rtp_transport, rtcp_transport);
|
||||
|
||||
if (!SetDtlsSrtpCryptoSuites_n(rtp_dtls_transport_, false)) {
|
||||
if (!SetDtlsSrtpCryptoSuites_n(rtp_transport_, false)) {
|
||||
return false;
|
||||
}
|
||||
if (rtcp_dtls_transport_ &&
|
||||
!SetDtlsSrtpCryptoSuites_n(rtcp_dtls_transport_, true)) {
|
||||
if (rtcp_transport_ && !SetDtlsSrtpCryptoSuites_n(rtcp_transport_, true)) {
|
||||
return false;
|
||||
}
|
||||
if (rtcp_mux_required_) {
|
||||
@ -252,33 +252,30 @@ void BaseChannel::Deinit() {
|
||||
RTC_FROM_HERE, Bind(&BaseChannel::DisconnectTransportChannels_n, this));
|
||||
}
|
||||
|
||||
void BaseChannel::SetTransports(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport) {
|
||||
network_thread_->Invoke<void>(RTC_FROM_HERE,
|
||||
Bind(&BaseChannel::SetTransports_n, this,
|
||||
rtp_dtls_transport, rtcp_dtls_transport));
|
||||
void BaseChannel::SetTransports(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport) {
|
||||
network_thread_->Invoke<void>(
|
||||
RTC_FROM_HERE,
|
||||
Bind(&BaseChannel::SetTransports_n, this, rtp_transport, rtcp_transport));
|
||||
}
|
||||
|
||||
void BaseChannel::SetTransports_n(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport) {
|
||||
void BaseChannel::SetTransports_n(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
if (!rtp_dtls_transport && !rtcp_dtls_transport) {
|
||||
LOG(LS_ERROR) << "Setting nullptr to RTP Transport and RTCP Transport.";
|
||||
return;
|
||||
// Verify some assumptions (as described in the comment above SetTransport).
|
||||
RTC_DCHECK(rtp_transport);
|
||||
RTC_DCHECK(NeedsRtcpTransport() == (rtcp_transport != nullptr));
|
||||
if (rtcp_transport) {
|
||||
RTC_DCHECK(rtp_transport->transport_name() ==
|
||||
rtcp_transport->transport_name());
|
||||
}
|
||||
|
||||
if (rtcp_dtls_transport) {
|
||||
RTC_DCHECK(rtp_dtls_transport->transport_name() ==
|
||||
rtcp_dtls_transport->transport_name());
|
||||
RTC_DCHECK(NeedsRtcpTransport());
|
||||
}
|
||||
|
||||
if (rtp_dtls_transport->transport_name() == transport_name_) {
|
||||
if (rtp_transport->transport_name() == transport_name_) {
|
||||
// Nothing to do if transport name isn't changing.
|
||||
return;
|
||||
}
|
||||
|
||||
transport_name_ = rtp_dtls_transport->transport_name();
|
||||
transport_name_ = rtp_transport->transport_name();
|
||||
|
||||
// When using DTLS-SRTP, we must reset the SrtpFilter every time the transport
|
||||
// changes and wait until the DTLS handshake is complete to set the newly
|
||||
@ -294,15 +291,15 @@ void BaseChannel::SetTransports_n(DtlsTransportInternal* rtp_dtls_transport,
|
||||
// negotiated RTCP mux, we need an RTCP transport.
|
||||
if (NeedsRtcpTransport()) {
|
||||
LOG(LS_INFO) << "Setting RTCP Transport for " << content_name() << " on "
|
||||
<< transport_name() << " transport " << rtcp_dtls_transport;
|
||||
SetTransport_n(true, rtcp_dtls_transport);
|
||||
RTC_DCHECK(rtcp_dtls_transport_);
|
||||
<< transport_name() << " transport " << rtcp_transport;
|
||||
SetTransportChannel_n(true, rtcp_transport);
|
||||
RTC_DCHECK(rtcp_transport_);
|
||||
}
|
||||
|
||||
LOG(LS_INFO) << "Setting non-RTCP Transport for " << content_name() << " on "
|
||||
<< transport_name() << " transport " << rtp_dtls_transport;
|
||||
SetTransport_n(false, rtp_dtls_transport);
|
||||
RTC_DCHECK(rtp_dtls_transport_);
|
||||
<< transport_name() << " transport " << rtp_transport;
|
||||
SetTransportChannel_n(false, rtp_transport);
|
||||
RTC_DCHECK(rtp_transport_);
|
||||
|
||||
// Update aggregate writable/ready-to-send state between RTP and RTCP upon
|
||||
// setting new transport channels.
|
||||
@ -316,26 +313,23 @@ void BaseChannel::SetTransports_n(DtlsTransportInternal* rtp_dtls_transport,
|
||||
// This won't always be accurate (the last SendPacket call from another
|
||||
// BaseChannel could have resulted in an error), but even so, we'll just
|
||||
// encounter the error again and update "ready to send" accordingly.
|
||||
SetTransportChannelReadyToSend(false,
|
||||
rtp_transport_ && rtp_transport_->writable());
|
||||
SetTransportChannelReadyToSend(
|
||||
false, rtp_dtls_transport_ && rtp_dtls_transport_->writable());
|
||||
SetTransportChannelReadyToSend(
|
||||
true, rtcp_dtls_transport_ && rtcp_dtls_transport_->writable());
|
||||
true, rtcp_transport_ && rtcp_transport_->writable());
|
||||
}
|
||||
|
||||
void BaseChannel::SetTransport_n(bool rtcp,
|
||||
DtlsTransportInternal* new_transport) {
|
||||
void BaseChannel::SetTransportChannel_n(bool rtcp,
|
||||
TransportChannel* new_transport) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
DtlsTransportInternal*& old_transport =
|
||||
rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
|
||||
|
||||
TransportChannel*& old_transport = rtcp ? rtcp_transport_ : rtp_transport_;
|
||||
if (!old_transport && !new_transport) {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
RTC_DCHECK(old_transport != new_transport);
|
||||
if (old_transport) {
|
||||
DisconnectFromTransport(old_transport);
|
||||
DisconnectFromTransportChannel(old_transport);
|
||||
}
|
||||
|
||||
old_transport = new_transport;
|
||||
@ -346,7 +340,7 @@ void BaseChannel::SetTransport_n(bool rtcp,
|
||||
<< "Setting RTCP for DTLS/SRTP after SrtpFilter is active "
|
||||
<< "should never happen.";
|
||||
}
|
||||
ConnectToTransport(new_transport);
|
||||
ConnectToTransportChannel(new_transport);
|
||||
auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_;
|
||||
for (const auto& pair : socket_options) {
|
||||
new_transport->SetOption(pair.first, pair.second);
|
||||
@ -354,30 +348,28 @@ void BaseChannel::SetTransport_n(bool rtcp,
|
||||
}
|
||||
}
|
||||
|
||||
void BaseChannel::ConnectToTransport(DtlsTransportInternal* transport) {
|
||||
void BaseChannel::ConnectToTransportChannel(TransportChannel* tc) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
|
||||
transport->SignalWritableState.connect(this, &BaseChannel::OnWritableState);
|
||||
transport->SignalReadPacket.connect(this, &BaseChannel::OnPacketRead);
|
||||
transport->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend);
|
||||
transport->SignalDtlsState.connect(this, &BaseChannel::OnDtlsState);
|
||||
transport->SignalSentPacket.connect(this, &BaseChannel::SignalSentPacket_n);
|
||||
transport->ice_transport()->SignalSelectedCandidatePairChanged.connect(
|
||||
tc->SignalWritableState.connect(this, &BaseChannel::OnWritableState);
|
||||
tc->SignalReadPacket.connect(this, &BaseChannel::OnPacketRead);
|
||||
tc->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend);
|
||||
tc->SignalDtlsState.connect(this, &BaseChannel::OnDtlsState);
|
||||
tc->SignalSelectedCandidatePairChanged.connect(
|
||||
this, &BaseChannel::OnSelectedCandidatePairChanged);
|
||||
tc->SignalSentPacket.connect(this, &BaseChannel::SignalSentPacket_n);
|
||||
}
|
||||
|
||||
void BaseChannel::DisconnectFromTransport(DtlsTransportInternal* transport) {
|
||||
void BaseChannel::DisconnectFromTransportChannel(TransportChannel* tc) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
OnSelectedCandidatePairChanged(transport->ice_transport(), nullptr, -1,
|
||||
false);
|
||||
OnSelectedCandidatePairChanged(tc, nullptr, -1, false);
|
||||
|
||||
transport->SignalWritableState.disconnect(this);
|
||||
transport->SignalReadPacket.disconnect(this);
|
||||
transport->SignalReadyToSend.disconnect(this);
|
||||
transport->SignalDtlsState.disconnect(this);
|
||||
transport->SignalSentPacket.disconnect(this);
|
||||
transport->ice_transport()->SignalSelectedCandidatePairChanged.disconnect(
|
||||
this);
|
||||
tc->SignalWritableState.disconnect(this);
|
||||
tc->SignalReadPacket.disconnect(this);
|
||||
tc->SignalReadyToSend.disconnect(this);
|
||||
tc->SignalDtlsState.disconnect(this);
|
||||
tc->SignalSelectedCandidatePairChanged.disconnect(this);
|
||||
tc->SignalSentPacket.disconnect(this);
|
||||
}
|
||||
|
||||
bool BaseChannel::Enable(bool enable) {
|
||||
@ -425,8 +417,8 @@ bool BaseChannel::SetRemoteContent(const MediaContentDescription* content,
|
||||
}
|
||||
|
||||
void BaseChannel::StartConnectionMonitor(int cms) {
|
||||
// We pass in the BaseChannel instead of the rtp_dtls_transport_
|
||||
// because if the rtp_dtls_transport_ changes, the ConnectionMonitor
|
||||
// We pass in the BaseChannel instead of the rtp_transport_
|
||||
// because if the rtp_transport_ changes, the ConnectionMonitor
|
||||
// would be pointing to the wrong TransportChannel.
|
||||
// We pass in the network thread because on that thread connection monitor
|
||||
// will call BaseChannel::GetConnectionStats which must be called on the
|
||||
@ -447,7 +439,7 @@ void BaseChannel::StopConnectionMonitor() {
|
||||
|
||||
bool BaseChannel::GetConnectionStats(ConnectionInfos* infos) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
return rtp_dtls_transport_->ice_transport()->GetStats(infos);
|
||||
return rtp_transport_->GetStats(infos);
|
||||
}
|
||||
|
||||
bool BaseChannel::NeedsRtcpTransport() {
|
||||
@ -496,20 +488,20 @@ int BaseChannel::SetOption_n(SocketType type,
|
||||
rtc::Socket::Option opt,
|
||||
int value) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
DtlsTransportInternal* transport = nullptr;
|
||||
TransportChannel* channel = nullptr;
|
||||
switch (type) {
|
||||
case ST_RTP:
|
||||
transport = rtp_dtls_transport_;
|
||||
channel = rtp_transport_;
|
||||
socket_options_.push_back(
|
||||
std::pair<rtc::Socket::Option, int>(opt, value));
|
||||
break;
|
||||
case ST_RTCP:
|
||||
transport = rtcp_dtls_transport_;
|
||||
channel = rtcp_transport_;
|
||||
rtcp_socket_options_.push_back(
|
||||
std::pair<rtc::Socket::Option, int>(opt, value));
|
||||
break;
|
||||
}
|
||||
return transport ? transport->ice_transport()->SetOption(opt, value) : -1;
|
||||
return channel ? channel->SetOption(opt, value) : -1;
|
||||
}
|
||||
|
||||
bool BaseChannel::SetCryptoOptions(const rtc::CryptoOptions& crypto_options) {
|
||||
@ -518,8 +510,7 @@ bool BaseChannel::SetCryptoOptions(const rtc::CryptoOptions& crypto_options) {
|
||||
}
|
||||
|
||||
void BaseChannel::OnWritableState(rtc::PacketTransportInterface* transport) {
|
||||
RTC_DCHECK(transport == rtp_dtls_transport_ ||
|
||||
transport == rtcp_dtls_transport_);
|
||||
RTC_DCHECK(transport == rtp_transport_ || transport == rtcp_transport_);
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
UpdateWritableState_n();
|
||||
}
|
||||
@ -541,12 +532,11 @@ void BaseChannel::OnPacketRead(rtc::PacketTransportInterface* transport,
|
||||
}
|
||||
|
||||
void BaseChannel::OnReadyToSend(rtc::PacketTransportInterface* transport) {
|
||||
RTC_DCHECK(transport == rtp_dtls_transport_ ||
|
||||
transport == rtcp_dtls_transport_);
|
||||
SetTransportChannelReadyToSend(transport == rtcp_dtls_transport_, true);
|
||||
RTC_DCHECK(transport == rtp_transport_ || transport == rtcp_transport_);
|
||||
SetTransportChannelReadyToSend(transport == rtcp_transport_, true);
|
||||
}
|
||||
|
||||
void BaseChannel::OnDtlsState(DtlsTransportInternal* transport,
|
||||
void BaseChannel::OnDtlsState(TransportChannel* channel,
|
||||
DtlsTransportState state) {
|
||||
if (!ShouldSetupDtlsSrtp_n()) {
|
||||
return;
|
||||
@ -554,7 +544,7 @@ void BaseChannel::OnDtlsState(DtlsTransportInternal* transport,
|
||||
|
||||
// Reset the srtp filter if it's not the CONNECTED state. For the CONNECTED
|
||||
// state, setting up DTLS-SRTP context is deferred to ChannelWritable_w to
|
||||
// cover other scenarios like the whole transport is writable (not just this
|
||||
// cover other scenarios like the whole channel is writable (not just this
|
||||
// TransportChannel) or when TransportChannel is attached after DTLS is
|
||||
// negotiated.
|
||||
if (state != DTLS_TRANSPORT_CONNECTED) {
|
||||
@ -563,15 +553,14 @@ void BaseChannel::OnDtlsState(DtlsTransportInternal* transport,
|
||||
}
|
||||
|
||||
void BaseChannel::OnSelectedCandidatePairChanged(
|
||||
IceTransportInternal* ice_transport,
|
||||
TransportChannel* channel,
|
||||
CandidatePairInterface* selected_candidate_pair,
|
||||
int last_sent_packet_id,
|
||||
bool ready_to_send) {
|
||||
RTC_DCHECK(ice_transport == rtp_dtls_transport_->ice_transport() ||
|
||||
ice_transport == rtcp_dtls_transport_->ice_transport());
|
||||
RTC_DCHECK(channel == rtp_transport_ || channel == rtcp_transport_);
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
selected_candidate_pair_ = selected_candidate_pair;
|
||||
std::string transport_name = ice_transport->transport_name();
|
||||
std::string transport_name = channel->transport_name();
|
||||
rtc::NetworkRoute network_route;
|
||||
if (selected_candidate_pair) {
|
||||
network_route = rtc::NetworkRoute(
|
||||
@ -597,8 +586,8 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) {
|
||||
|
||||
bool ready_to_send =
|
||||
(rtp_ready_to_send_ &&
|
||||
// In the case of rtcp mux |rtcp_dtls_transport_| will be null.
|
||||
(rtcp_ready_to_send_ || !rtcp_dtls_transport_));
|
||||
// In the case of rtcp mux |rtcp_transport_| will be null.
|
||||
(rtcp_ready_to_send_ || !rtcp_transport_));
|
||||
|
||||
invoker_.AsyncInvoke<void>(
|
||||
RTC_FROM_HERE, worker_thread_,
|
||||
@ -608,7 +597,7 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) {
|
||||
bool BaseChannel::PacketIsRtcp(const rtc::PacketTransportInterface* transport,
|
||||
const char* data,
|
||||
size_t len) {
|
||||
return (transport == rtcp_dtls_transport_ ||
|
||||
return (transport == rtcp_transport_ ||
|
||||
rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len)));
|
||||
}
|
||||
|
||||
@ -637,10 +626,9 @@ bool BaseChannel::SendPacket(bool rtcp,
|
||||
// packet before doing anything. (We might get RTCP packets that we don't
|
||||
// intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
|
||||
// transport.
|
||||
DtlsTransportInternal* transport = (!rtcp || rtcp_mux_filter_.IsActive())
|
||||
? rtp_dtls_transport_
|
||||
: rtcp_dtls_transport_;
|
||||
if (!transport || !transport->writable()) {
|
||||
TransportChannel* channel =
|
||||
(!rtcp || rtcp_mux_filter_.IsActive()) ? rtp_transport_ : rtcp_transport_;
|
||||
if (!channel || !channel->writable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -731,10 +719,10 @@ bool BaseChannel::SendPacket(bool rtcp,
|
||||
|
||||
// Bon voyage.
|
||||
int flags = (secure() && secure_dtls()) ? PF_SRTP_BYPASS : PF_NORMAL;
|
||||
int ret = transport->SendPacket(packet->data<char>(), packet->size(),
|
||||
updated_options, flags);
|
||||
int ret = channel->SendPacket(packet->data<char>(), packet->size(),
|
||||
updated_options, flags);
|
||||
if (ret != static_cast<int>(packet->size())) {
|
||||
if (transport->GetError() == ENOTCONN) {
|
||||
if (channel->GetError() == ENOTCONN) {
|
||||
LOG(LS_WARNING) << "Got ENOTCONN from transport.";
|
||||
SetTransportChannelReadyToSend(rtcp, false);
|
||||
}
|
||||
@ -809,12 +797,11 @@ void BaseChannel::HandlePacket(bool rtcp, rtc::CopyOnWriteBuffer* packet,
|
||||
// a) we got SRTP packets before we received the SDES keys, in which case
|
||||
// we can't decrypt it anyway, or
|
||||
// b) we got SRTP packets before DTLS completed on both the RTP and RTCP
|
||||
// transports, so we haven't yet extracted keys, even if DTLS did
|
||||
// complete on the transport that the packets are being sent on. It's
|
||||
// really good practice to wait for both RTP and RTCP to be good to go
|
||||
// before sending media, to prevent weird failure modes, so it's fine
|
||||
// for us to just eat packets here. This is all sidestepped if RTCP mux
|
||||
// is used anyway.
|
||||
// channels, so we haven't yet extracted keys, even if DTLS did complete
|
||||
// on the channel that the packets are being sent on. It's really good
|
||||
// practice to wait for both RTP and RTCP to be good to go before sending
|
||||
// media, to prevent weird failure modes, so it's fine for us to just eat
|
||||
// packets here. This is all sidestepped if RTCP mux is used anyway.
|
||||
LOG(LS_WARNING) << "Can't process incoming " << PacketType(rtcp)
|
||||
<< " packet when SRTP is inactive and crypto is required";
|
||||
return;
|
||||
@ -888,8 +875,8 @@ void BaseChannel::DisableMedia_w() {
|
||||
}
|
||||
|
||||
void BaseChannel::UpdateWritableState_n() {
|
||||
if (rtp_dtls_transport_ && rtp_dtls_transport_->writable() &&
|
||||
(!rtcp_dtls_transport_ || rtcp_dtls_transport_->writable())) {
|
||||
if (rtp_transport_ && rtp_transport_->writable() &&
|
||||
(!rtcp_transport_ || rtcp_transport_->writable())) {
|
||||
ChannelWritable_n();
|
||||
} else {
|
||||
ChannelNotWritable_n();
|
||||
@ -930,8 +917,7 @@ void BaseChannel::SignalDtlsSrtpSetupFailure_s(bool rtcp) {
|
||||
SignalDtlsSrtpSetupFailure(this, rtcp);
|
||||
}
|
||||
|
||||
bool BaseChannel::SetDtlsSrtpCryptoSuites_n(DtlsTransportInternal* transport,
|
||||
bool rtcp) {
|
||||
bool BaseChannel::SetDtlsSrtpCryptoSuites_n(TransportChannel* tc, bool rtcp) {
|
||||
std::vector<int> crypto_suites;
|
||||
// We always use the default SRTP crypto suites for RTCP, but we may use
|
||||
// different crypto suites for RTP depending on the media type.
|
||||
@ -940,34 +926,34 @@ bool BaseChannel::SetDtlsSrtpCryptoSuites_n(DtlsTransportInternal* transport,
|
||||
} else {
|
||||
GetDefaultSrtpCryptoSuites(crypto_options(), &crypto_suites);
|
||||
}
|
||||
return transport->SetSrtpCryptoSuites(crypto_suites);
|
||||
return tc->SetSrtpCryptoSuites(crypto_suites);
|
||||
}
|
||||
|
||||
bool BaseChannel::ShouldSetupDtlsSrtp_n() const {
|
||||
// Since DTLS is applied to all transports, checking RTP should be enough.
|
||||
return rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
|
||||
// Since DTLS is applied to all channels, checking RTP should be enough.
|
||||
return rtp_transport_ && rtp_transport_->IsDtlsActive();
|
||||
}
|
||||
|
||||
// This function returns true if either DTLS-SRTP is not in use
|
||||
// *or* DTLS-SRTP is successfully set up.
|
||||
bool BaseChannel::SetupDtlsSrtp_n(bool rtcp) {
|
||||
bool BaseChannel::SetupDtlsSrtp_n(bool rtcp_channel) {
|
||||
RTC_DCHECK(network_thread_->IsCurrent());
|
||||
bool ret = false;
|
||||
|
||||
DtlsTransportInternal* transport =
|
||||
rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
|
||||
TransportChannel* channel = rtcp_channel ? rtcp_transport_ : rtp_transport_;
|
||||
|
||||
RTC_DCHECK(transport->IsDtlsActive());
|
||||
RTC_DCHECK(channel->IsDtlsActive());
|
||||
|
||||
int selected_crypto_suite;
|
||||
|
||||
if (!transport->GetSrtpCryptoSuite(&selected_crypto_suite)) {
|
||||
if (!channel->GetSrtpCryptoSuite(&selected_crypto_suite)) {
|
||||
LOG(LS_ERROR) << "No DTLS-SRTP selected crypto suite";
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG(LS_INFO) << "Installing keys from DTLS-SRTP on " << content_name() << " "
|
||||
<< PacketType(rtcp);
|
||||
LOG(LS_INFO) << "Installing keys from DTLS-SRTP on "
|
||||
<< content_name() << " "
|
||||
<< PacketType(rtcp_channel);
|
||||
|
||||
int key_len;
|
||||
int salt_len;
|
||||
@ -981,8 +967,10 @@ bool BaseChannel::SetupDtlsSrtp_n(bool rtcp) {
|
||||
std::vector<unsigned char> dtls_buffer(key_len * 2 + salt_len * 2);
|
||||
|
||||
// RFC 5705 exporter using the RFC 5764 parameters
|
||||
if (!transport->ExportKeyingMaterial(kDtlsSrtpExporterLabel, NULL, 0, false,
|
||||
&dtls_buffer[0], dtls_buffer.size())) {
|
||||
if (!channel->ExportKeyingMaterial(
|
||||
kDtlsSrtpExporterLabel,
|
||||
NULL, 0, false,
|
||||
&dtls_buffer[0], dtls_buffer.size())) {
|
||||
LOG(LS_WARNING) << "DTLS-SRTP key export failed";
|
||||
RTC_NOTREACHED(); // This should never happen
|
||||
return false;
|
||||
@ -1002,7 +990,7 @@ bool BaseChannel::SetupDtlsSrtp_n(bool rtcp) {
|
||||
|
||||
std::vector<unsigned char> *send_key, *recv_key;
|
||||
rtc::SSLRole role;
|
||||
if (!transport->GetSslRole(&role)) {
|
||||
if (!channel->GetSslRole(&role)) {
|
||||
LOG(LS_WARNING) << "GetSslRole failed";
|
||||
return false;
|
||||
}
|
||||
@ -1015,7 +1003,7 @@ bool BaseChannel::SetupDtlsSrtp_n(bool rtcp) {
|
||||
recv_key = &server_write_key;
|
||||
}
|
||||
|
||||
if (rtcp) {
|
||||
if (rtcp_channel) {
|
||||
ret = srtp_filter_.SetRtcpParams(selected_crypto_suite, &(*send_key)[0],
|
||||
static_cast<int>(send_key->size()),
|
||||
selected_crypto_suite, &(*recv_key)[0],
|
||||
@ -1050,7 +1038,7 @@ void BaseChannel::MaybeSetupDtlsSrtp_n() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rtcp_dtls_transport_) {
|
||||
if (rtcp_transport_) {
|
||||
if (!SetupDtlsSrtp_n(true)) {
|
||||
SignalDtlsSrtpSetupFailure_n(true);
|
||||
return;
|
||||
@ -1102,12 +1090,12 @@ bool BaseChannel::SetRtpTransportParameters_n(
|
||||
return true;
|
||||
}
|
||||
|
||||
// |dtls| will be set to true if DTLS is active for transport and crypto is
|
||||
// empty.
|
||||
// |dtls| will be set to true if DTLS is active for transport channel and
|
||||
// crypto is empty.
|
||||
bool BaseChannel::CheckSrtpConfig_n(const std::vector<CryptoParams>& cryptos,
|
||||
bool* dtls,
|
||||
std::string* error_desc) {
|
||||
*dtls = rtp_dtls_transport_->IsDtlsActive();
|
||||
*dtls = rtp_transport_->IsDtlsActive();
|
||||
if (*dtls && !cryptos.empty()) {
|
||||
SafeSetError("Cryptos must be empty when DTLS is active.", error_desc);
|
||||
return false;
|
||||
@ -1181,7 +1169,7 @@ bool BaseChannel::SetRtcpMux_n(bool enable,
|
||||
ret = rtcp_mux_filter_.SetOffer(enable, src);
|
||||
break;
|
||||
case CA_PRANSWER:
|
||||
// This may activate RTCP muxing, but we don't yet destroy the transport
|
||||
// This may activate RTCP muxing, but we don't yet destroy the channel
|
||||
// because the final answer may deactivate it.
|
||||
ret = rtcp_mux_filter_.SetProvisionalAnswer(enable, src);
|
||||
break;
|
||||
@ -1190,11 +1178,11 @@ bool BaseChannel::SetRtcpMux_n(bool enable,
|
||||
if (ret && rtcp_mux_filter_.IsActive()) {
|
||||
// We activated RTCP mux, close down the RTCP transport.
|
||||
LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name()
|
||||
<< " by destroying RTCP transport for "
|
||||
<< " by destroying RTCP transport channel for "
|
||||
<< transport_name();
|
||||
if (rtcp_dtls_transport()) {
|
||||
SetTransport_n(true, nullptr);
|
||||
SignalRtcpMuxFullyActive(rtp_dtls_transport()->transport_name());
|
||||
if (rtcp_transport()) {
|
||||
SetTransportChannel_n(true, nullptr);
|
||||
SignalRtcpMuxFullyActive(rtp_transport()->transport_name());
|
||||
}
|
||||
UpdateWritableState_n();
|
||||
SetTransportChannelReadyToSend(true, false);
|
||||
@ -1212,11 +1200,11 @@ bool BaseChannel::SetRtcpMux_n(bool enable,
|
||||
return false;
|
||||
}
|
||||
// |rtcp_mux_filter_| can be active if |action| is CA_PRANSWER or
|
||||
// CA_ANSWER, but we only want to tear down the RTCP transport if we received
|
||||
// a final answer.
|
||||
// CA_ANSWER, but we only want to tear down the RTCP transport channel if we
|
||||
// received a final answer.
|
||||
if (rtcp_mux_filter_.IsActive()) {
|
||||
// If the RTP transport is already writable, then so are we.
|
||||
if (rtp_dtls_transport_->writable()) {
|
||||
if (rtp_transport_->writable()) {
|
||||
ChannelWritable_n();
|
||||
}
|
||||
}
|
||||
@ -1476,9 +1464,9 @@ VoiceChannel::~VoiceChannel() {
|
||||
Deinit();
|
||||
}
|
||||
|
||||
bool VoiceChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport) {
|
||||
return BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport);
|
||||
bool VoiceChannel::Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport) {
|
||||
return BaseChannel::Init_w(rtp_transport, rtcp_transport);
|
||||
}
|
||||
|
||||
bool VoiceChannel::SetAudioSend(uint32_t ssrc,
|
||||
@ -1878,9 +1866,9 @@ VideoChannel::VideoChannel(rtc::Thread* worker_thread,
|
||||
rtcp_mux_required,
|
||||
srtp_required) {}
|
||||
|
||||
bool VideoChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport) {
|
||||
return BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport);
|
||||
bool VideoChannel::Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport) {
|
||||
return BaseChannel::Init_w(rtp_transport, rtcp_transport);
|
||||
}
|
||||
|
||||
VideoChannel::~VideoChannel() {
|
||||
@ -2148,9 +2136,9 @@ RtpDataChannel::~RtpDataChannel() {
|
||||
Deinit();
|
||||
}
|
||||
|
||||
bool RtpDataChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport) {
|
||||
if (!BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
|
||||
bool RtpDataChannel::Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport) {
|
||||
if (!BaseChannel::Init_w(rtp_transport, rtcp_transport)) {
|
||||
return false;
|
||||
}
|
||||
media_channel()->SignalDataReceived.connect(this,
|
||||
|
||||
@ -86,8 +86,8 @@ class BaseChannel
|
||||
bool rtcp_mux_required,
|
||||
bool srtp_required);
|
||||
virtual ~BaseChannel();
|
||||
bool Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
bool Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport);
|
||||
// Deinit may be called multiple times and is simply ignored if it's already
|
||||
// done.
|
||||
void Deinit();
|
||||
@ -113,8 +113,8 @@ class BaseChannel
|
||||
// RTCP muxing is not fully active yet).
|
||||
// |rtp_transport| and |rtcp_transport| must share the same transport name as
|
||||
// well.
|
||||
void SetTransports(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
void SetTransports(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport);
|
||||
bool PushdownLocalDescription(const SessionDescription* local_desc,
|
||||
ContentAction action,
|
||||
std::string* error_desc);
|
||||
@ -159,7 +159,7 @@ class BaseChannel
|
||||
// Used for latency measurements.
|
||||
sigslot::signal1<BaseChannel*> SignalFirstPacketReceived;
|
||||
|
||||
// Forward SignalSentPacket to worker thread.
|
||||
// Forward TransportChannel SignalSentPacket to worker thread.
|
||||
sigslot::signal1<const rtc::SentPacket&> SignalSentPacket;
|
||||
|
||||
// Emitted whenever rtcp-mux is fully negotiated and the rtcp-transport can
|
||||
@ -167,13 +167,8 @@ class BaseChannel
|
||||
// Fired on the network thread.
|
||||
sigslot::signal1<const std::string&> SignalRtcpMuxFullyActive;
|
||||
|
||||
// Only public for unit tests. Otherwise, consider private.
|
||||
DtlsTransportInternal* rtp_dtls_transport() const {
|
||||
return rtp_dtls_transport_;
|
||||
}
|
||||
DtlsTransportInternal* rtcp_dtls_transport() const {
|
||||
return rtcp_dtls_transport_;
|
||||
}
|
||||
TransportChannel* rtp_transport() const { return rtp_transport_; }
|
||||
TransportChannel* rtcp_transport() const { return rtcp_transport_; }
|
||||
|
||||
bool NeedsRtcpTransport();
|
||||
|
||||
@ -205,12 +200,12 @@ class BaseChannel
|
||||
protected:
|
||||
virtual MediaChannel* media_channel() const { return media_channel_; }
|
||||
|
||||
void SetTransports_n(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
void SetTransports_n(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport);
|
||||
|
||||
// This does not update writability or "ready-to-send" state; it just
|
||||
// disconnects from the old channel and connects to the new one.
|
||||
void SetTransport_n(bool rtcp, DtlsTransportInternal* new_transport);
|
||||
void SetTransportChannel_n(bool rtcp, TransportChannel* new_transport);
|
||||
|
||||
bool was_ever_writable() const { return was_ever_writable_; }
|
||||
void set_local_content_direction(MediaContentDirection direction) {
|
||||
@ -233,8 +228,8 @@ class BaseChannel
|
||||
bool IsReadyToSendMedia_w() const;
|
||||
rtc::Thread* signaling_thread() { return signaling_thread_; }
|
||||
|
||||
void ConnectToTransport(DtlsTransportInternal* transport);
|
||||
void DisconnectFromTransport(DtlsTransportInternal* transport);
|
||||
void ConnectToTransportChannel(TransportChannel* tc);
|
||||
void DisconnectFromTransportChannel(TransportChannel* tc);
|
||||
|
||||
void FlushRtcpMessages_n();
|
||||
|
||||
@ -253,10 +248,10 @@ class BaseChannel
|
||||
int flags);
|
||||
void OnReadyToSend(rtc::PacketTransportInterface* transport);
|
||||
|
||||
void OnDtlsState(DtlsTransportInternal* transport, DtlsTransportState state);
|
||||
void OnDtlsState(TransportChannel* channel, DtlsTransportState state);
|
||||
|
||||
void OnSelectedCandidatePairChanged(
|
||||
IceTransportInternal* ice_transport,
|
||||
TransportChannel* channel,
|
||||
CandidatePairInterface* selected_candidate_pair,
|
||||
int last_sent_packet_id,
|
||||
bool ready_to_send);
|
||||
@ -292,10 +287,10 @@ class BaseChannel
|
||||
bool ShouldSetupDtlsSrtp_n() const;
|
||||
// Do the DTLS key expansion and impose it on the SRTP/SRTCP filters.
|
||||
// |rtcp_channel| indicates whether to set up the RTP or RTCP filter.
|
||||
bool SetupDtlsSrtp_n(bool rtcp);
|
||||
bool SetupDtlsSrtp_n(bool rtcp_channel);
|
||||
void MaybeSetupDtlsSrtp_n();
|
||||
// Set the DTLS-SRTP cipher policy on this channel as appropriate.
|
||||
bool SetDtlsSrtpCryptoSuites_n(DtlsTransportInternal* transport, bool rtcp);
|
||||
bool SetDtlsSrtpCryptoSuites_n(TransportChannel* tc, bool rtcp);
|
||||
|
||||
// Should be called whenever the conditions for
|
||||
// IsReadyToReceiveMedia/IsReadyToSendMedia are satisfied (or unsatisfied).
|
||||
@ -365,8 +360,8 @@ class BaseChannel
|
||||
}
|
||||
|
||||
private:
|
||||
bool InitNetwork_n(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
bool InitNetwork_n(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport);
|
||||
void DisconnectTransportChannels_n();
|
||||
void SignalSentPacket_n(rtc::PacketTransportInterface* transport,
|
||||
const rtc::SentPacket& sent_packet);
|
||||
@ -388,10 +383,10 @@ class BaseChannel
|
||||
// True if RTCP-multiplexing is required. In other words, no standalone RTCP
|
||||
// transport will ever be used for this channel.
|
||||
const bool rtcp_mux_required_;
|
||||
|
||||
DtlsTransportInternal* rtp_dtls_transport_ = nullptr;
|
||||
// TODO(johan): Replace TransportChannel* with rtc::PacketTransportInterface*.
|
||||
TransportChannel* rtp_transport_ = nullptr;
|
||||
std::vector<std::pair<rtc::Socket::Option, int> > socket_options_;
|
||||
DtlsTransportInternal* rtcp_dtls_transport_ = nullptr;
|
||||
TransportChannel* rtcp_transport_ = nullptr;
|
||||
std::vector<std::pair<rtc::Socket::Option, int> > rtcp_socket_options_;
|
||||
SrtpFilter srtp_filter_;
|
||||
RtcpMuxFilter rtcp_mux_filter_;
|
||||
@ -433,8 +428,8 @@ class VoiceChannel : public BaseChannel {
|
||||
bool rtcp_mux_required,
|
||||
bool srtp_required);
|
||||
~VoiceChannel();
|
||||
bool Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
bool Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport);
|
||||
|
||||
// Configure sending media on the stream with SSRC |ssrc|
|
||||
// If there is only one sending stream SSRC 0 can be used.
|
||||
@ -552,8 +547,8 @@ class VideoChannel : public BaseChannel {
|
||||
bool rtcp_mux_required,
|
||||
bool srtp_required);
|
||||
~VideoChannel();
|
||||
bool Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
bool Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport);
|
||||
|
||||
// downcasts a MediaChannel
|
||||
VideoMediaChannel* media_channel() const override {
|
||||
@ -632,8 +627,8 @@ class RtpDataChannel : public BaseChannel {
|
||||
bool rtcp_mux_required,
|
||||
bool srtp_required);
|
||||
~RtpDataChannel();
|
||||
bool Init_w(DtlsTransportInternal* rtp_dtls_transport,
|
||||
DtlsTransportInternal* rtcp_dtls_transport);
|
||||
bool Init_w(TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport);
|
||||
|
||||
virtual bool SendData(const SendDataParams& params,
|
||||
const rtc::CopyOnWriteBuffer& payload,
|
||||
|
||||
@ -21,8 +21,8 @@
|
||||
#include "webrtc/media/base/fakertp.h"
|
||||
#include "webrtc/media/base/mediachannel.h"
|
||||
#include "webrtc/media/base/testutils.h"
|
||||
#include "webrtc/p2p/base/dtlstransportinternal.h"
|
||||
#include "webrtc/p2p/base/faketransportcontroller.h"
|
||||
#include "webrtc/p2p/base/transportchannelimpl.h"
|
||||
#include "webrtc/pc/channel.h"
|
||||
|
||||
#define MAYBE_SKIP_TEST(feature) \
|
||||
@ -35,9 +35,9 @@ using cricket::CA_OFFER;
|
||||
using cricket::CA_PRANSWER;
|
||||
using cricket::CA_ANSWER;
|
||||
using cricket::CA_UPDATE;
|
||||
using cricket::DtlsTransportInternal;
|
||||
using cricket::FakeVoiceMediaChannel;
|
||||
using cricket::StreamParams;
|
||||
using cricket::TransportChannel;
|
||||
|
||||
namespace {
|
||||
const cricket::AudioCodec kPcmuCodec(0, "PCMU", 64000, 8000, 1);
|
||||
@ -216,15 +216,15 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
rtc::CryptoOptions crypto_options;
|
||||
crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0;
|
||||
channel->SetCryptoOptions(crypto_options);
|
||||
cricket::DtlsTransportInternal* rtp_dtls_transport =
|
||||
transport_controller->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller->CreateTransportChannel(
|
||||
channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
|
||||
cricket::TransportChannel* rtcp_transport = nullptr;
|
||||
if (channel->NeedsRtcpTransport()) {
|
||||
rtcp_dtls_transport = transport_controller->CreateDtlsTransport(
|
||||
rtcp_transport = transport_controller->CreateTransportChannel(
|
||||
channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
if (!channel->Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
|
||||
if (!channel->Init_w(rtp_transport, rtcp_transport)) {
|
||||
delete channel;
|
||||
channel = NULL;
|
||||
}
|
||||
@ -299,21 +299,21 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
return channel1_->RemoveRecvStream(id);
|
||||
}
|
||||
|
||||
std::vector<cricket::DtlsTransportInternal*> GetChannels1() {
|
||||
std::vector<cricket::TransportChannelImpl*> GetChannels1() {
|
||||
return transport_controller1_->channels_for_testing();
|
||||
}
|
||||
|
||||
std::vector<cricket::DtlsTransportInternal*> GetChannels2() {
|
||||
std::vector<cricket::TransportChannelImpl*> GetChannels2() {
|
||||
return transport_controller2_->channels_for_testing();
|
||||
}
|
||||
|
||||
cricket::FakeDtlsTransport* GetFakeChannel1(int component) {
|
||||
return transport_controller1_->GetFakeDtlsTransport_n(
|
||||
cricket::FakeTransportChannel* GetFakeChannel1(int component) {
|
||||
return transport_controller1_->GetFakeTransportChannel_n(
|
||||
channel1_->content_name(), component);
|
||||
}
|
||||
|
||||
cricket::FakeDtlsTransport* GetFakeChannel2(int component) {
|
||||
return transport_controller2_->GetFakeDtlsTransport_n(
|
||||
cricket::FakeTransportChannel* GetFakeChannel2(int component) {
|
||||
return transport_controller2_->GetFakeTransportChannel_n(
|
||||
channel2_->content_name(), component);
|
||||
}
|
||||
|
||||
@ -411,7 +411,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
// Returns true if so.
|
||||
bool CheckGcmCipher(typename T::Channel* channel, int flags) {
|
||||
int suite;
|
||||
if (!channel->rtp_dtls_transport()->GetSrtpCryptoSuite(&suite)) {
|
||||
if (!channel->rtp_transport()->GetSrtpCryptoSuite(&suite)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -541,43 +541,43 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
// mux.
|
||||
void TestSetContentsRtcpMux() {
|
||||
CreateChannels(0, 0);
|
||||
EXPECT_TRUE(channel1_->rtcp_dtls_transport() != NULL);
|
||||
EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
|
||||
EXPECT_TRUE(channel1_->rtcp_transport() != NULL);
|
||||
EXPECT_TRUE(channel2_->rtcp_transport() != NULL);
|
||||
typename T::Content content;
|
||||
CreateContent(0, kPcmuCodec, kH264Codec, &content);
|
||||
// Both sides agree on mux. Should no longer be a separate RTCP channel.
|
||||
content.set_rtcp_mux(true);
|
||||
EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL));
|
||||
EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL));
|
||||
EXPECT_TRUE(channel1_->rtcp_dtls_transport() == NULL);
|
||||
EXPECT_TRUE(channel1_->rtcp_transport() == NULL);
|
||||
// Only initiator supports mux. Should still have a separate RTCP channel.
|
||||
EXPECT_TRUE(channel2_->SetLocalContent(&content, CA_OFFER, NULL));
|
||||
content.set_rtcp_mux(false);
|
||||
EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_ANSWER, NULL));
|
||||
EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
|
||||
EXPECT_TRUE(channel2_->rtcp_transport() != NULL);
|
||||
}
|
||||
|
||||
// Test that SetLocalContent and SetRemoteContent properly set RTCP
|
||||
// mux when a provisional answer is received.
|
||||
void TestSetContentsRtcpMuxWithPrAnswer() {
|
||||
CreateChannels(0, 0);
|
||||
EXPECT_TRUE(channel1_->rtcp_dtls_transport() != NULL);
|
||||
EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
|
||||
EXPECT_TRUE(channel1_->rtcp_transport() != NULL);
|
||||
EXPECT_TRUE(channel2_->rtcp_transport() != NULL);
|
||||
typename T::Content content;
|
||||
CreateContent(0, kPcmuCodec, kH264Codec, &content);
|
||||
content.set_rtcp_mux(true);
|
||||
EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL));
|
||||
EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_PRANSWER, NULL));
|
||||
EXPECT_TRUE(channel1_->rtcp_dtls_transport() != NULL);
|
||||
EXPECT_TRUE(channel1_->rtcp_transport() != NULL);
|
||||
EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL));
|
||||
// Both sides agree on mux. Should no longer be a separate RTCP channel.
|
||||
EXPECT_TRUE(channel1_->rtcp_dtls_transport() == NULL);
|
||||
EXPECT_TRUE(channel1_->rtcp_transport() == NULL);
|
||||
// Only initiator supports mux. Should still have a separate RTCP channel.
|
||||
EXPECT_TRUE(channel2_->SetLocalContent(&content, CA_OFFER, NULL));
|
||||
content.set_rtcp_mux(false);
|
||||
EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_PRANSWER, NULL));
|
||||
EXPECT_TRUE(channel2_->SetRemoteContent(&content, CA_ANSWER, NULL));
|
||||
EXPECT_TRUE(channel2_->rtcp_dtls_transport() != NULL);
|
||||
EXPECT_TRUE(channel2_->rtcp_transport() != NULL);
|
||||
}
|
||||
|
||||
// Test that SetRemoteContent properly deals with a content update.
|
||||
@ -957,8 +957,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
|
||||
CreateChannels(0, 0);
|
||||
|
||||
cricket::DtlsTransportInternal* transport_channel1 =
|
||||
channel1_->rtp_dtls_transport();
|
||||
cricket::TransportChannel* transport_channel1 = channel1_->rtp_transport();
|
||||
ASSERT_TRUE(transport_channel1);
|
||||
typename T::MediaChannel* media_channel1 =
|
||||
static_cast<typename T::MediaChannel*>(channel1_->media_channel());
|
||||
@ -967,8 +966,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
media_channel1->set_num_network_route_changes(0);
|
||||
network_thread_->Invoke<void>(RTC_FROM_HERE, [transport_channel1] {
|
||||
// The transport channel becomes disconnected.
|
||||
transport_channel1->ice_transport()->SignalSelectedCandidatePairChanged(
|
||||
transport_channel1->ice_transport(), nullptr, -1, false);
|
||||
transport_channel1->SignalSelectedCandidatePairChanged(
|
||||
transport_channel1, nullptr, -1, false);
|
||||
});
|
||||
WaitForThreads();
|
||||
EXPECT_EQ(1, media_channel1->num_network_route_changes());
|
||||
@ -984,9 +983,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
std::unique_ptr<cricket::CandidatePairInterface> candidate_pair(
|
||||
transport_controller1_->CreateFakeCandidatePair(
|
||||
local_address, kLocalNetId, remote_address, kRemoteNetId));
|
||||
transport_channel1->ice_transport()->SignalSelectedCandidatePairChanged(
|
||||
transport_channel1->ice_transport(), candidate_pair.get(),
|
||||
kLastPacketId, true);
|
||||
transport_channel1->SignalSelectedCandidatePairChanged(
|
||||
transport_channel1, candidate_pair.get(), kLastPacketId, true);
|
||||
});
|
||||
WaitForThreads();
|
||||
EXPECT_EQ(1, media_channel1->num_network_route_changes());
|
||||
@ -1475,7 +1473,6 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
WaitForThreads();
|
||||
EXPECT_TRUE(CheckRtp1());
|
||||
EXPECT_TRUE(CheckNoRtp2());
|
||||
EXPECT_TRUE(CheckNoRtp1());
|
||||
|
||||
// Gain writability back
|
||||
network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
|
||||
@ -1785,8 +1782,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
error_handler.mode_ = cricket::SrtpFilter::UNPROTECT;
|
||||
|
||||
network_thread_->Invoke<void>(RTC_FROM_HERE, [this] {
|
||||
cricket::DtlsTransportInternal* transport_channel =
|
||||
channel2_->rtp_dtls_transport();
|
||||
cricket::TransportChannel* transport_channel = channel2_->rtp_transport();
|
||||
transport_channel->SignalReadPacket(
|
||||
transport_channel, reinterpret_cast<const char*>(kBadPacket),
|
||||
sizeof(kBadPacket), rtc::PacketTime(), 0);
|
||||
@ -1799,8 +1795,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
|
||||
void TestOnReadyToSend() {
|
||||
CreateChannels(0, 0);
|
||||
DtlsTransportInternal* rtp = channel1_->rtp_dtls_transport();
|
||||
DtlsTransportInternal* rtcp = channel1_->rtcp_dtls_transport();
|
||||
TransportChannel* rtp = channel1_->rtp_transport();
|
||||
TransportChannel* rtcp = channel1_->rtcp_transport();
|
||||
EXPECT_FALSE(media_channel1_->ready_to_send());
|
||||
|
||||
network_thread_->Invoke<void>(RTC_FROM_HERE,
|
||||
@ -1850,8 +1846,8 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
content.set_rtcp_mux(true);
|
||||
EXPECT_TRUE(channel1_->SetLocalContent(&content, CA_OFFER, NULL));
|
||||
EXPECT_TRUE(channel1_->SetRemoteContent(&content, CA_ANSWER, NULL));
|
||||
EXPECT_TRUE(channel1_->rtcp_dtls_transport() == NULL);
|
||||
DtlsTransportInternal* rtp = channel1_->rtp_dtls_transport();
|
||||
EXPECT_TRUE(channel1_->rtcp_transport() == NULL);
|
||||
TransportChannel* rtp = channel1_->rtp_transport();
|
||||
EXPECT_FALSE(media_channel1_->ready_to_send());
|
||||
// In the case of rtcp mux, the SignalReadyToSend() from rtp channel
|
||||
// should trigger the MediaChannel's OnReadyToSend.
|
||||
@ -2030,15 +2026,15 @@ cricket::VideoChannel* ChannelTest<VideoTraits>::CreateChannel(
|
||||
rtc::CryptoOptions crypto_options;
|
||||
crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0;
|
||||
channel->SetCryptoOptions(crypto_options);
|
||||
cricket::DtlsTransportInternal* rtp_dtls_transport =
|
||||
transport_controller->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller->CreateTransportChannel(
|
||||
channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
|
||||
cricket::TransportChannel* rtcp_transport = nullptr;
|
||||
if (channel->NeedsRtcpTransport()) {
|
||||
rtcp_dtls_transport = transport_controller->CreateDtlsTransport(
|
||||
rtcp_transport = transport_controller->CreateTransportChannel(
|
||||
channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
if (!channel->Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
|
||||
if (!channel->Init_w(rtp_transport, rtcp_transport)) {
|
||||
delete channel;
|
||||
channel = NULL;
|
||||
}
|
||||
@ -3264,15 +3260,15 @@ cricket::RtpDataChannel* ChannelTest<DataTraits>::CreateChannel(
|
||||
rtc::CryptoOptions crypto_options;
|
||||
crypto_options.enable_gcm_crypto_suites = (flags & GCM_CIPHER) != 0;
|
||||
channel->SetCryptoOptions(crypto_options);
|
||||
cricket::DtlsTransportInternal* rtp_dtls_transport =
|
||||
transport_controller->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller->CreateTransportChannel(
|
||||
channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* rtcp_dtls_transport = nullptr;
|
||||
cricket::TransportChannel* rtcp_transport = nullptr;
|
||||
if (channel->NeedsRtcpTransport()) {
|
||||
rtcp_dtls_transport = transport_controller->CreateDtlsTransport(
|
||||
rtcp_transport = transport_controller->CreateTransportChannel(
|
||||
channel->content_name(), cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
}
|
||||
if (!channel->Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
|
||||
if (!channel->Init_w(rtp_transport, rtcp_transport)) {
|
||||
delete channel;
|
||||
channel = NULL;
|
||||
}
|
||||
@ -3600,9 +3596,9 @@ class BaseChannelDeathTest : public testing::Test {
|
||||
cricket::CN_AUDIO,
|
||||
false,
|
||||
true) {
|
||||
rtp_transport_ = fake_transport_controller_.CreateDtlsTransport(
|
||||
rtp_transport_ = fake_transport_controller_.CreateTransportChannel(
|
||||
"foo", cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
rtcp_transport_ = fake_transport_controller_.CreateDtlsTransport(
|
||||
rtcp_transport_ = fake_transport_controller_.CreateTransportChannel(
|
||||
"foo", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
EXPECT_TRUE(voice_channel_.Init_w(rtp_transport_, rtcp_transport_));
|
||||
}
|
||||
@ -3613,20 +3609,20 @@ class BaseChannelDeathTest : public testing::Test {
|
||||
cricket::VoiceChannel voice_channel_;
|
||||
// Will be cleaned up by FakeTransportController, don't need to worry about
|
||||
// deleting them in this test.
|
||||
cricket::DtlsTransportInternal* rtp_transport_;
|
||||
cricket::DtlsTransportInternal* rtcp_transport_;
|
||||
cricket::TransportChannel* rtp_transport_;
|
||||
cricket::TransportChannel* rtcp_transport_;
|
||||
};
|
||||
|
||||
TEST_F(BaseChannelDeathTest, SetTransportWithNullRtpTransport) {
|
||||
cricket::DtlsTransportInternal* new_rtcp_transport =
|
||||
fake_transport_controller_.CreateDtlsTransport(
|
||||
cricket::TransportChannel* new_rtcp_transport =
|
||||
fake_transport_controller_.CreateTransportChannel(
|
||||
"bar", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
EXPECT_DEATH(voice_channel_.SetTransports(nullptr, new_rtcp_transport), "");
|
||||
}
|
||||
|
||||
TEST_F(BaseChannelDeathTest, SetTransportWithMissingRtcpTransport) {
|
||||
cricket::DtlsTransportInternal* new_rtp_transport =
|
||||
fake_transport_controller_.CreateDtlsTransport(
|
||||
cricket::TransportChannel* new_rtp_transport =
|
||||
fake_transport_controller_.CreateTransportChannel(
|
||||
"bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
EXPECT_DEATH(voice_channel_.SetTransports(new_rtp_transport, nullptr), "");
|
||||
}
|
||||
@ -3637,11 +3633,11 @@ TEST_F(BaseChannelDeathTest, SetTransportWithUnneededRtcpTransport) {
|
||||
content.set_rtcp_mux(true);
|
||||
ASSERT_TRUE(voice_channel_.SetLocalContent(&content, CA_OFFER, nullptr));
|
||||
ASSERT_TRUE(voice_channel_.SetRemoteContent(&content, CA_ANSWER, nullptr));
|
||||
cricket::DtlsTransportInternal* new_rtp_transport =
|
||||
fake_transport_controller_.CreateDtlsTransport(
|
||||
cricket::TransportChannel* new_rtp_transport =
|
||||
fake_transport_controller_.CreateTransportChannel(
|
||||
"bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* new_rtcp_transport =
|
||||
fake_transport_controller_.CreateDtlsTransport(
|
||||
cricket::TransportChannel* new_rtcp_transport =
|
||||
fake_transport_controller_.CreateTransportChannel(
|
||||
"bar", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
// After muxing is enabled, no RTCP transport should be passed in here.
|
||||
EXPECT_DEATH(
|
||||
@ -3651,11 +3647,11 @@ TEST_F(BaseChannelDeathTest, SetTransportWithUnneededRtcpTransport) {
|
||||
// This test will probably go away if/when we move the transport name out of
|
||||
// the transport classes and into their parent classes.
|
||||
TEST_F(BaseChannelDeathTest, SetTransportWithMismatchingTransportNames) {
|
||||
cricket::DtlsTransportInternal* new_rtp_transport =
|
||||
fake_transport_controller_.CreateDtlsTransport(
|
||||
cricket::TransportChannel* new_rtp_transport =
|
||||
fake_transport_controller_.CreateTransportChannel(
|
||||
"bar", cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::DtlsTransportInternal* new_rtcp_transport =
|
||||
fake_transport_controller_.CreateDtlsTransport(
|
||||
cricket::TransportChannel* new_rtcp_transport =
|
||||
fake_transport_controller_.CreateTransportChannel(
|
||||
"baz", cricket::ICE_CANDIDATE_COMPONENT_RTCP);
|
||||
EXPECT_DEATH(
|
||||
voice_channel_.SetTransports(new_rtp_transport, new_rtcp_transport), "");
|
||||
|
||||
@ -207,8 +207,8 @@ void ChannelManager::Terminate_w() {
|
||||
|
||||
VoiceChannel* ChannelManager::CreateVoiceChannel(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -224,8 +224,8 @@ VoiceChannel* ChannelManager::CreateVoiceChannel(
|
||||
|
||||
VoiceChannel* ChannelManager::CreateVoiceChannel_w(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -279,8 +279,8 @@ void ChannelManager::DestroyVoiceChannel_w(VoiceChannel* voice_channel) {
|
||||
|
||||
VideoChannel* ChannelManager::CreateVideoChannel(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -296,8 +296,8 @@ VideoChannel* ChannelManager::CreateVideoChannel(
|
||||
|
||||
VideoChannel* ChannelManager::CreateVideoChannel_w(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -351,8 +351,8 @@ void ChannelManager::DestroyVideoChannel_w(VideoChannel* video_channel) {
|
||||
|
||||
RtpDataChannel* ChannelManager::CreateRtpDataChannel(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -367,8 +367,8 @@ RtpDataChannel* ChannelManager::CreateRtpDataChannel(
|
||||
|
||||
RtpDataChannel* ChannelManager::CreateRtpDataChannel_w(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
|
||||
@ -90,8 +90,8 @@ class ChannelManager {
|
||||
// Creates a voice channel, to be associated with the specified session.
|
||||
VoiceChannel* CreateVoiceChannel(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -104,8 +104,8 @@ class ChannelManager {
|
||||
// associated with the specified session.
|
||||
VideoChannel* CreateVideoChannel(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -116,8 +116,8 @@ class ChannelManager {
|
||||
void DestroyVideoChannel(VideoChannel* video_channel);
|
||||
RtpDataChannel* CreateRtpDataChannel(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -167,8 +167,8 @@ class ChannelManager {
|
||||
bool SetCryptoOptions_w(const rtc::CryptoOptions& crypto_options);
|
||||
VoiceChannel* CreateVoiceChannel_w(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -178,8 +178,8 @@ class ChannelManager {
|
||||
void DestroyVoiceChannel_w(VoiceChannel* voice_channel);
|
||||
VideoChannel* CreateVideoChannel_w(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
@ -189,8 +189,8 @@ class ChannelManager {
|
||||
void DestroyVideoChannel_w(VideoChannel* video_channel);
|
||||
RtpDataChannel* CreateRtpDataChannel_w(
|
||||
webrtc::MediaControllerInterface* media_controller,
|
||||
DtlsTransportInternal* rtp_transport,
|
||||
DtlsTransportInternal* rtcp_transport,
|
||||
TransportChannel* rtp_transport,
|
||||
TransportChannel* rtcp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
const std::string* bundle_transport_name,
|
||||
|
||||
@ -102,8 +102,8 @@ TEST_F(ChannelManagerTest, StartupShutdownOnThread) {
|
||||
// Test that we can create and destroy a voice and video channel.
|
||||
TEST_F(ChannelManagerTest, CreateDestroyChannels) {
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
cricket::DtlsTransportInternal* rtp_transport =
|
||||
transport_controller_->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller_->CreateTransportChannel(
|
||||
cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
|
||||
&fake_mc_, rtp_transport, nullptr /*rtcp_transport*/,
|
||||
@ -136,8 +136,8 @@ TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) {
|
||||
delete transport_controller_;
|
||||
transport_controller_ =
|
||||
new cricket::FakeTransportController(&network_, ICEROLE_CONTROLLING);
|
||||
cricket::DtlsTransportInternal* rtp_transport =
|
||||
transport_controller_->CreateDtlsTransport(
|
||||
cricket::TransportChannel* rtp_transport =
|
||||
transport_controller_->CreateTransportChannel(
|
||||
cricket::CN_AUDIO, cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
||||
cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
|
||||
&fake_mc_, rtp_transport, nullptr /*rtcp_transport*/,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user