зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1486012: Rework ICE restart. r=mjf
Differential Revision: https://phabricator.services.mozilla.com/D5897 --HG-- rename : dom/media/tests/mochitest/test_peerConnection_restartIceLocalAndRemoteRollback.html => dom/media/tests/mochitest/test_peerConnection_restartIceLocalAndRemoteRollbackNoSubsequentRestart.html rename : dom/media/tests/mochitest/test_peerConnection_restartIceLocalRollback.html => dom/media/tests/mochitest/test_peerConnection_restartIceLocalRollbackNoSubsequentRestart.html extra : moz-landing-system : lando
This commit is contained in:
Родитель
f3e06a8e36
Коммит
93985b16c9
|
@ -231,8 +231,12 @@ skip-if = toolkit == 'android'
|
|||
skip-if = toolkit == 'android'
|
||||
[test_peerConnection_restartIceLocalRollback.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_peerConnection_restartIceLocalRollbackNoSubsequentRestart.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_peerConnection_restartIceLocalAndRemoteRollback.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_peerConnection_restartIceLocalAndRemoteRollbackNoSubsequentRestart.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_peerConnection_restartIceBadAnswer.html]
|
||||
skip-if = toolkit == 'android'
|
||||
[test_peerConnection_scaleResolution.html]
|
||||
|
|
|
@ -64,13 +64,13 @@
|
|||
STABLE);
|
||||
},
|
||||
|
||||
// Rolling back should shut down gathering
|
||||
// Rolling back should shut down gathering for the offerer,
|
||||
// but because the answerer never set a local description, no ICE
|
||||
// gathering has happened yet, so there's no changes to ICE gathering
|
||||
// state
|
||||
function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
|
||||
return test.pcLocal.endOfTrickleIce;
|
||||
},
|
||||
function PC_REMOTE_WAIT_FOR_END_OF_TRICKLE(test) {
|
||||
return test.pcRemote.endOfTrickleIce;
|
||||
},
|
||||
|
||||
function PC_LOCAL_EXPECT_ICE_CHECKING(test) {
|
||||
test.pcLocal.expectIceChecking();
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "906986",
|
||||
title: "Renegotiation: restart ice, local and remote rollback, without a subsequent ICE restart"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
|
||||
addRenegotiation(test.chain,
|
||||
[
|
||||
// causes a full, normal ice restart
|
||||
function PC_LOCAL_SET_OFFER_OPTION(test) {
|
||||
test.setOfferOptions({ iceRestart: true });
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
test.chain.replaceAfter('PC_REMOTE_CREATE_ANSWER',
|
||||
[
|
||||
function PC_LOCAL_SETUP_ICE_HANDLER(test) {
|
||||
test.pcLocal.setupIceCandidateHandler(test);
|
||||
if (test.testOptions.steeplechase) {
|
||||
test.pcLocal.endOfTrickleIce.then(() => {
|
||||
send_message({"type": "end_of_trickle_ice"});
|
||||
});
|
||||
}
|
||||
},
|
||||
function PC_REMOTE_SETUP_ICE_HANDLER(test) {
|
||||
test.pcRemote.setupIceCandidateHandler(test);
|
||||
if (test.testOptions.steeplechase) {
|
||||
test.pcRemote.endOfTrickleIce.then(() => {
|
||||
send_message({"type": "end_of_trickle_ice"});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
function PC_REMOTE_ROLLBACK(test) {
|
||||
return test.setRemoteDescription(test.pcRemote, { type: "rollback" },
|
||||
STABLE);
|
||||
},
|
||||
|
||||
function PC_LOCAL_ROLLBACK(test) {
|
||||
// We haven't negotiated the new stream yet.
|
||||
test.pcLocal.expectNegotiationNeeded();
|
||||
return test.setLocalDescription(
|
||||
test.pcLocal,
|
||||
new RTCSessionDescription({ type: "rollback", sdp: ""}),
|
||||
STABLE);
|
||||
},
|
||||
|
||||
// Rolling back should shut down gathering for the offerer,
|
||||
// but because the answerer never set a local description, no ICE
|
||||
// gathering has happened yet, so there's no changes to ICE gathering
|
||||
// state
|
||||
function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
|
||||
return test.pcLocal.endOfTrickleIce;
|
||||
},
|
||||
|
||||
function PC_LOCAL_SET_OFFER_OPTION(test) {
|
||||
test.setOfferOptions({ iceRestart: false });
|
||||
}
|
||||
],
|
||||
1 // Replaces after second PC_REMOTE_CREATE_ANSWER
|
||||
);
|
||||
test.chain.append(commandsPeerConnectionOfferAnswer);
|
||||
|
||||
// for now, only use one stream, because rollback doesn't seem to
|
||||
// like multiple streams. See bug 1259465.
|
||||
test.setMediaConstraints([{audio: true}],
|
||||
[{audio: true}]);
|
||||
test.run();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,66 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
createHTML({
|
||||
bug: "906986",
|
||||
title: "Renegotiation: restart ice, local rollback, then renegotiation without ICE restart"
|
||||
});
|
||||
|
||||
var test;
|
||||
runNetworkTest(function (options) {
|
||||
test = new PeerConnectionTest(options);
|
||||
|
||||
addRenegotiation(test.chain,
|
||||
[
|
||||
// causes a full, normal ice restart
|
||||
function PC_LOCAL_SET_OFFER_OPTION(test) {
|
||||
test.setOfferOptions({ iceRestart: true });
|
||||
},
|
||||
// causes an ice restart and then rolls it back
|
||||
// (does not result in sending an offer)
|
||||
function PC_LOCAL_SETUP_ICE_HANDLER(test) {
|
||||
test.pcLocal.setupIceCandidateHandler(test);
|
||||
if (test.testOptions.steeplechase) {
|
||||
test.pcLocal.endOfTrickleIce.then(() => {
|
||||
send_message({"type": "end_of_trickle_ice"});
|
||||
});
|
||||
}
|
||||
},
|
||||
function PC_LOCAL_CREATE_AND_SET_OFFER(test) {
|
||||
return test.createOffer(test.pcLocal).then(offer => {
|
||||
return test.setLocalDescription(test.pcLocal,
|
||||
offer,
|
||||
HAVE_LOCAL_OFFER);
|
||||
});
|
||||
},
|
||||
function PC_LOCAL_ROLLBACK(test) {
|
||||
return test.setLocalDescription(test.pcLocal,
|
||||
{ type: "rollback", sdp: ""},
|
||||
STABLE);
|
||||
},
|
||||
// Rolling back should shut down gathering
|
||||
function PC_LOCAL_WAIT_FOR_END_OF_TRICKLE(test) {
|
||||
return test.pcLocal.endOfTrickleIce;
|
||||
},
|
||||
function PC_LOCAL_SET_OFFER_OPTION(test) {
|
||||
test.setOfferOptions({ iceRestart: false });
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
// for now, only use one stream, because rollback doesn't seem to
|
||||
// like multiple streams. See bug 1259465.
|
||||
test.setMediaConstraints([{audio: true}],
|
||||
[{audio: true}]);
|
||||
test.run();
|
||||
});
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -10,7 +10,6 @@ mtransport_lcppsrcs = [
|
|||
'nr_socket_prsock.cpp',
|
||||
'nr_timer.cpp',
|
||||
'nricectx.cpp',
|
||||
'nricectxhandler.cpp',
|
||||
'nricemediastream.cpp',
|
||||
'nriceresolver.cpp',
|
||||
'nriceresolverfake.cpp',
|
||||
|
|
|
@ -291,18 +291,68 @@ NrIceCtx::NrIceCtx(const std::string& name, Policy policy)
|
|||
nat_ (nullptr) {
|
||||
}
|
||||
|
||||
/* static */
|
||||
RefPtr<NrIceCtx>
|
||||
NrIceCtx::Create(const std::string& name,
|
||||
bool allow_loopback,
|
||||
bool tcp_enabled,
|
||||
bool allow_link_local,
|
||||
Policy policy)
|
||||
{
|
||||
// InitializeGlobals only executes once
|
||||
NrIceCtx::InitializeGlobals(allow_loopback, tcp_enabled, allow_link_local);
|
||||
|
||||
RefPtr<NrIceCtx> ctx = new NrIceCtx(name, policy);
|
||||
|
||||
if (!ctx->Initialize()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
RefPtr<NrIceMediaStream>
|
||||
NrIceCtx::CreateStream(const std::string& id,
|
||||
const std::string& name,
|
||||
int components)
|
||||
{
|
||||
if (streams_.count(id)) {
|
||||
MOZ_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<NrIceMediaStream> stream =
|
||||
new NrIceMediaStream(this, id, name, components);
|
||||
streams_[id] = stream;
|
||||
return stream;
|
||||
}
|
||||
|
||||
void
|
||||
NrIceCtx::DestroyStream(const std::string& id) {
|
||||
auto it = streams_.find(id);
|
||||
if (it != streams_.end()) {
|
||||
auto preexisting_stream = it->second;
|
||||
streams_.erase(it);
|
||||
preexisting_stream->Close();
|
||||
}
|
||||
}
|
||||
|
||||
// Handler callbacks
|
||||
int NrIceCtx::select_pair(void *obj,nr_ice_media_stream *stream,
|
||||
int component_id, nr_ice_cand_pair **potentials,
|
||||
int potential_ct) {
|
||||
MOZ_MTLOG(ML_DEBUG, "select pair called: potential_ct = "
|
||||
<< potential_ct);
|
||||
MOZ_ASSERT(stream->local_stream);
|
||||
MOZ_ASSERT(!stream->local_stream->obsolete);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NrIceCtx::stream_ready(void *obj, nr_ice_media_stream *stream) {
|
||||
MOZ_MTLOG(ML_DEBUG, "stream_ready called");
|
||||
MOZ_ASSERT(!stream->local_stream);
|
||||
MOZ_ASSERT(!stream->obsolete);
|
||||
|
||||
// Get the ICE ctx.
|
||||
NrIceCtx *ctx = static_cast<NrIceCtx *>(obj);
|
||||
|
@ -319,6 +369,8 @@ int NrIceCtx::stream_ready(void *obj, nr_ice_media_stream *stream) {
|
|||
|
||||
int NrIceCtx::stream_failed(void *obj, nr_ice_media_stream *stream) {
|
||||
MOZ_MTLOG(ML_DEBUG, "stream_failed called");
|
||||
MOZ_ASSERT(!stream->local_stream);
|
||||
MOZ_ASSERT(!stream->obsolete);
|
||||
|
||||
// Get the ICE ctx
|
||||
NrIceCtx *ctx = static_cast<NrIceCtx *>(obj);
|
||||
|
@ -328,7 +380,7 @@ int NrIceCtx::stream_failed(void *obj, nr_ice_media_stream *stream) {
|
|||
MOZ_ASSERT(s);
|
||||
|
||||
ctx->SetConnectionState(ICE_CTX_FAILED);
|
||||
s -> SignalFailed(s);
|
||||
s -> Failed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -387,6 +439,7 @@ void NrIceCtx::trickle_cb(void *arg, nr_ice_ctx *ice_ctx,
|
|||
nr_ice_media_stream *stream,
|
||||
int component_id,
|
||||
nr_ice_candidate *candidate) {
|
||||
MOZ_ASSERT(!stream->obsolete);
|
||||
// Get the ICE ctx
|
||||
NrIceCtx *ctx = static_cast<NrIceCtx *>(arg);
|
||||
RefPtr<NrIceMediaStream> s = ctx->FindStream(stream);
|
||||
|
@ -488,40 +541,6 @@ NrIceCtx::InitializeGlobals(bool allow_loopback,
|
|||
}
|
||||
}
|
||||
|
||||
std::string
|
||||
NrIceCtx::GetNewUfrag()
|
||||
{
|
||||
char* ufrag;
|
||||
int r;
|
||||
|
||||
if ((r=nr_ice_get_new_ice_ufrag(&ufrag))) {
|
||||
MOZ_CRASH("Unable to get new ice ufrag");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string ufragStr = ufrag;
|
||||
RFREE(ufrag);
|
||||
|
||||
return ufragStr;
|
||||
}
|
||||
|
||||
std::string
|
||||
NrIceCtx::GetNewPwd()
|
||||
{
|
||||
char* pwd;
|
||||
int r;
|
||||
|
||||
if ((r=nr_ice_get_new_ice_pwd(&pwd))) {
|
||||
MOZ_CRASH("Unable to get new ice pwd");
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string pwdStr = pwd;
|
||||
RFREE(pwd);
|
||||
|
||||
return pwdStr;
|
||||
}
|
||||
|
||||
#define MAXADDRS 100 // mirrors setting in ice_ctx.c
|
||||
|
||||
/* static */
|
||||
|
@ -570,22 +589,6 @@ NrIceCtx::SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs)
|
|||
bool
|
||||
NrIceCtx::Initialize()
|
||||
{
|
||||
std::string ufrag = GetNewUfrag();
|
||||
std::string pwd = GetNewPwd();
|
||||
|
||||
return Initialize(ufrag, pwd);
|
||||
}
|
||||
|
||||
bool
|
||||
NrIceCtx::Initialize(const std::string& ufrag,
|
||||
const std::string& pwd)
|
||||
{
|
||||
MOZ_ASSERT(!ufrag.empty());
|
||||
MOZ_ASSERT(!pwd.empty());
|
||||
if (ufrag.empty() || pwd.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the ICE context
|
||||
int r;
|
||||
|
||||
|
@ -601,13 +604,7 @@ NrIceCtx::Initialize(const std::string& ufrag,
|
|||
break;
|
||||
}
|
||||
|
||||
r = nr_ice_ctx_create_with_credentials(const_cast<char *>(name_.c_str()),
|
||||
flags,
|
||||
const_cast<char *>(ufrag.c_str()),
|
||||
const_cast<char *>(pwd.c_str()),
|
||||
&ctx_);
|
||||
MOZ_ASSERT(ufrag == ctx_->ufrag);
|
||||
MOZ_ASSERT(pwd == ctx_->pwd);
|
||||
r = nr_ice_ctx_create(const_cast<char *>(name_.c_str()), flags, &ctx_);
|
||||
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't create ICE ctx for '" << name_ << "'");
|
||||
|
@ -792,29 +789,6 @@ NrIceCtx::~NrIceCtx() {
|
|||
Destroy();
|
||||
}
|
||||
|
||||
void
|
||||
NrIceCtx::SetStream(const std::string& id, NrIceMediaStream* stream) {
|
||||
auto it = streams_.find(id);
|
||||
if (it != streams_.end()) {
|
||||
MOZ_ASSERT(!stream, "Transport ids should be unique, and set only once");
|
||||
auto preexisting_stream = it->second;
|
||||
streams_.erase(it);
|
||||
preexisting_stream->Close();
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
streams_[id] = stream;
|
||||
}
|
||||
}
|
||||
|
||||
std::string NrIceCtx::ufrag() const {
|
||||
return ctx_->ufrag;
|
||||
}
|
||||
|
||||
std::string NrIceCtx::pwd() const {
|
||||
return ctx_->pwd;
|
||||
}
|
||||
|
||||
void NrIceCtx::destroy_peer_ctx() {
|
||||
nr_ice_peer_ctx_destroy(&peer_);
|
||||
}
|
||||
|
@ -992,7 +966,7 @@ nsresult NrIceCtx::StartGathering(bool default_route_only, bool proxy_only) {
|
|||
|
||||
RefPtr<NrIceMediaStream> NrIceCtx::FindStream(nr_ice_media_stream *stream) {
|
||||
for (auto& idAndStream : streams_) {
|
||||
if (idAndStream.second->stream() == stream) {
|
||||
if (idAndStream.second->HasStream(stream)) {
|
||||
return idAndStream.second;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "m_cpp_utils.h"
|
||||
#include "nricestunaddr.h"
|
||||
#include "nricemediastream.h"
|
||||
|
||||
typedef struct nr_ice_ctx_ nr_ice_ctx;
|
||||
typedef struct nr_ice_peer_ctx_ nr_ice_peer_ctx;
|
||||
|
@ -204,7 +205,6 @@ class NrIceStats {
|
|||
};
|
||||
|
||||
class NrIceCtx {
|
||||
friend class NrIceCtxHandler;
|
||||
public:
|
||||
enum ConnectionState { ICE_CTX_INIT,
|
||||
ICE_CTX_CHECKING,
|
||||
|
@ -229,12 +229,22 @@ class NrIceCtx {
|
|||
ICE_POLICY_ALL
|
||||
};
|
||||
|
||||
static RefPtr<NrIceCtx> Create(const std::string& name,
|
||||
bool allow_loopback = false,
|
||||
bool tcp_enabled = true,
|
||||
bool allow_link_local = false,
|
||||
NrIceCtx::Policy policy =
|
||||
NrIceCtx::ICE_POLICY_ALL);
|
||||
|
||||
RefPtr<NrIceMediaStream> CreateStream(const std::string& id,
|
||||
const std::string& name,
|
||||
int components);
|
||||
void DestroyStream(const std::string& id);
|
||||
|
||||
// initialize ICE globals, crypto, and logging
|
||||
static void InitializeGlobals(bool allow_loopback = false,
|
||||
bool tcp_enabled = true,
|
||||
bool allow_link_local = false);
|
||||
static std::string GetNewUfrag();
|
||||
static std::string GetNewPwd();
|
||||
|
||||
// static GetStunAddrs for use in parent process to support
|
||||
// sandboxing restrictions
|
||||
|
@ -242,7 +252,6 @@ class NrIceCtx {
|
|||
void SetStunAddrs(const nsTArray<NrIceStunAddr>& addrs);
|
||||
|
||||
bool Initialize();
|
||||
bool Initialize(const std::string& ufrag, const std::string& pwd);
|
||||
|
||||
int SetNat(const RefPtr<TestNat>& aNat);
|
||||
|
||||
|
@ -258,8 +267,6 @@ class NrIceCtx {
|
|||
// Testing only.
|
||||
void destroy_peer_ctx();
|
||||
|
||||
void SetStream(const std::string& id, NrIceMediaStream* stream);
|
||||
|
||||
RefPtr<NrIceMediaStream> GetStream(const std::string& id) {
|
||||
auto it = streams_.find(id);
|
||||
if (it != streams_.end()) {
|
||||
|
@ -281,10 +288,6 @@ class NrIceCtx {
|
|||
// The name of the ctx
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
// Get ufrag and password.
|
||||
std::string ufrag() const;
|
||||
std::string pwd() const;
|
||||
|
||||
// Current state
|
||||
ConnectionState connection_state() const {
|
||||
return connection_state_;
|
||||
|
|
|
@ -1,188 +0,0 @@
|
|||
#include <sstream>
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
// nICEr includes
|
||||
extern "C" {
|
||||
#include "nr_api.h"
|
||||
#include "ice_ctx.h"
|
||||
}
|
||||
|
||||
// Local includes
|
||||
#include "nricectxhandler.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "nriceresolver.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
NrIceCtxHandler::NrIceCtxHandler(const std::string& name,
|
||||
NrIceCtx::Policy policy)
|
||||
: current_ctx(new NrIceCtx(name, policy)),
|
||||
old_ctx(nullptr),
|
||||
restart_count(0)
|
||||
{
|
||||
}
|
||||
|
||||
RefPtr<NrIceCtxHandler>
|
||||
NrIceCtxHandler::Create(const std::string& name,
|
||||
bool allow_loopback,
|
||||
bool tcp_enabled,
|
||||
bool allow_link_local,
|
||||
NrIceCtx::Policy policy)
|
||||
{
|
||||
// InitializeGlobals only executes once
|
||||
NrIceCtx::InitializeGlobals(allow_loopback, tcp_enabled, allow_link_local);
|
||||
|
||||
RefPtr<NrIceCtxHandler> ctx = new NrIceCtxHandler(name, policy);
|
||||
|
||||
if (ctx == nullptr ||
|
||||
ctx->current_ctx == nullptr ||
|
||||
!ctx->current_ctx->Initialize()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
RefPtr<NrIceMediaStream>
|
||||
NrIceCtxHandler::CreateStream(const std::string& name, int components)
|
||||
{
|
||||
// To make tracking NrIceMediaStreams easier during ICE restart
|
||||
// prepend an int to the name that increments with each ICE restart
|
||||
std::ostringstream os;
|
||||
os << restart_count << "-" << name;
|
||||
return NrIceMediaStream::Create(this->current_ctx, os.str(), components);
|
||||
}
|
||||
|
||||
|
||||
RefPtr<NrIceCtx>
|
||||
NrIceCtxHandler::CreateCtx() const
|
||||
{
|
||||
return CreateCtx(NrIceCtx::GetNewUfrag(), NrIceCtx::GetNewPwd());
|
||||
}
|
||||
|
||||
|
||||
RefPtr<NrIceCtx>
|
||||
NrIceCtxHandler::CreateCtx(const std::string& ufrag,
|
||||
const std::string& pwd) const
|
||||
{
|
||||
RefPtr<NrIceCtx> new_ctx = new NrIceCtx(this->current_ctx->name(),
|
||||
this->current_ctx->policy());
|
||||
if (new_ctx == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!new_ctx->Initialize(ufrag, pwd)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// copy the stun, and turn servers from the current context
|
||||
int r = nr_ice_ctx_set_stun_servers(new_ctx->ctx_,
|
||||
this->current_ctx->ctx_->stun_servers,
|
||||
this->current_ctx->ctx_->stun_server_ct);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Error while setting STUN servers in CreateCtx"
|
||||
<< " (likely ice restart related)");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
r = nr_ice_ctx_copy_turn_servers(new_ctx->ctx_,
|
||||
this->current_ctx->ctx_->turn_servers,
|
||||
this->current_ctx->ctx_->turn_server_ct);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Error while copying TURN servers in CreateCtx"
|
||||
<< " (likely ice restart related)");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// grab the NrIceResolver stashed in the nr_resolver and allocate another
|
||||
// for the new ctx. Note: there may not be an nr_resolver.
|
||||
if (this->current_ctx->ctx_->resolver) {
|
||||
NrIceResolver* resolver =
|
||||
static_cast<NrIceResolver*>(this->current_ctx->ctx_->resolver->obj);
|
||||
if (!resolver ||
|
||||
NS_FAILED(new_ctx->SetResolver(resolver->AllocateResolver()))) {
|
||||
MOZ_MTLOG(ML_ERROR, "Error while setting dns resolver in CreateCtx"
|
||||
<< " (likely ice restart related)");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return new_ctx;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
NrIceCtxHandler::BeginIceRestart(RefPtr<NrIceCtx> new_ctx)
|
||||
{
|
||||
MOZ_ASSERT(!old_ctx, "existing ice restart in progress");
|
||||
if (old_ctx) {
|
||||
MOZ_MTLOG(ML_ERROR, "Existing ice restart in progress");
|
||||
return false; // ice restart already in progress
|
||||
}
|
||||
|
||||
if (new_ctx == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
++restart_count;
|
||||
old_ctx = current_ctx;
|
||||
current_ctx = new_ctx;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NrIceCtxHandler::FinalizeIceRestart()
|
||||
{
|
||||
if (old_ctx) {
|
||||
// Fixup the telemetry by transferring old stats to current ctx.
|
||||
NrIceStats stats = old_ctx->Destroy();
|
||||
current_ctx->AccumulateStats(stats);
|
||||
}
|
||||
|
||||
// no harm calling this even if we're not in the middle of restarting
|
||||
old_ctx = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NrIceCtxHandler::RollbackIceRestart()
|
||||
{
|
||||
if (old_ctx == nullptr) {
|
||||
return;
|
||||
}
|
||||
current_ctx = old_ctx;
|
||||
old_ctx = nullptr;
|
||||
}
|
||||
|
||||
NrIceStats NrIceCtxHandler::Destroy()
|
||||
{
|
||||
NrIceStats stats;
|
||||
|
||||
// designed to be called more than once so if stats are desired, this can be
|
||||
// called just prior to the destructor
|
||||
if (old_ctx && current_ctx) {
|
||||
stats = old_ctx->Destroy();
|
||||
current_ctx->AccumulateStats(stats);
|
||||
}
|
||||
|
||||
if (current_ctx) {
|
||||
stats = current_ctx->Destroy();
|
||||
}
|
||||
|
||||
old_ctx = nullptr;
|
||||
current_ctx = nullptr;
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
NrIceCtxHandler::~NrIceCtxHandler()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
} // close namespace
|
|
@ -1,50 +0,0 @@
|
|||
#ifndef nricectxhandler_h__
|
||||
#define nricectxhandler_h__
|
||||
|
||||
#include "nricectx.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class NrIceCtxHandler {
|
||||
public:
|
||||
// TODO(ekr@rtfm.com): Too many bools here. Bug 1193437.
|
||||
static RefPtr<NrIceCtxHandler> Create(const std::string& name,
|
||||
bool allow_loopback = false,
|
||||
bool tcp_enabled = true,
|
||||
bool allow_link_local = false,
|
||||
NrIceCtx::Policy policy =
|
||||
NrIceCtx::ICE_POLICY_ALL);
|
||||
|
||||
RefPtr<NrIceMediaStream> CreateStream(const std::string& name,
|
||||
int components);
|
||||
// CreateCtx is necessary so we can create and initialize the context
|
||||
// on main thread, but begin the ice restart mechanics on STS thread
|
||||
RefPtr<NrIceCtx> CreateCtx() const; // for test
|
||||
RefPtr<NrIceCtx> CreateCtx(const std::string& ufrag,
|
||||
const std::string& pwd) const;
|
||||
|
||||
RefPtr<NrIceCtx> ctx() { return current_ctx; }
|
||||
|
||||
bool BeginIceRestart(RefPtr<NrIceCtx> new_ctx);
|
||||
bool IsRestarting() const { return (old_ctx != nullptr); }
|
||||
void FinalizeIceRestart();
|
||||
void RollbackIceRestart();
|
||||
|
||||
NrIceStats Destroy();
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceCtxHandler)
|
||||
|
||||
private:
|
||||
NrIceCtxHandler(const std::string& name, NrIceCtx::Policy policy);
|
||||
NrIceCtxHandler() = delete;
|
||||
~NrIceCtxHandler();
|
||||
DISALLOW_COPY_ASSIGN(NrIceCtxHandler);
|
||||
|
||||
RefPtr<NrIceCtx> current_ctx;
|
||||
RefPtr<NrIceCtx> old_ctx; // for while restart is in progress
|
||||
int restart_count; // used to differentiate streams between restarted ctx
|
||||
};
|
||||
|
||||
} // close namespace
|
||||
|
||||
#endif // nricectxhandler_h__
|
|
@ -183,28 +183,14 @@ static UniquePtr<NrIceCandidate> MakeNrIceCandidate(const nr_ice_candidate& cand
|
|||
return out;
|
||||
}
|
||||
|
||||
// NrIceMediaStream
|
||||
RefPtr<NrIceMediaStream>
|
||||
NrIceMediaStream::Create(NrIceCtx *ctx,
|
||||
const std::string& name,
|
||||
int components) {
|
||||
RefPtr<NrIceMediaStream> stream =
|
||||
new NrIceMediaStream(ctx, name, components);
|
||||
MOZ_ASSERT(stream->ctx_ == ctx->ctx());
|
||||
|
||||
int r = nr_ice_add_media_stream(ctx->ctx(),
|
||||
const_cast<char *>(name.c_str()),
|
||||
components, &stream->stream_);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't create ICE media stream for '"
|
||||
<< name << "'");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return stream;
|
||||
static bool Matches(const nr_ice_media_stream* stream,
|
||||
const std::string& ufrag,
|
||||
const std::string& pwd) {
|
||||
return stream && (stream->ufrag == ufrag) && (stream->pwd == pwd);
|
||||
}
|
||||
|
||||
NrIceMediaStream::NrIceMediaStream(NrIceCtx *ctx,
|
||||
const std::string& id,
|
||||
const std::string& name,
|
||||
size_t components) :
|
||||
state_(ICE_CONNECTING),
|
||||
|
@ -213,7 +199,8 @@ NrIceMediaStream::NrIceMediaStream(NrIceCtx *ctx,
|
|||
name_(name),
|
||||
components_(components),
|
||||
stream_(nullptr),
|
||||
has_parsed_attrs_(false)
|
||||
old_stream_(nullptr),
|
||||
id_(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -222,35 +209,84 @@ NrIceMediaStream::~NrIceMediaStream() {
|
|||
// are attached to the ice ctx.
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::ParseAttributes(std::vector<std::string>&
|
||||
attributes) {
|
||||
if (!stream_)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult NrIceMediaStream::ConnectToPeer(
|
||||
const std::string& ufrag,
|
||||
const std::string& pwd,
|
||||
const std::vector<std::string>& attributes) {
|
||||
MOZ_ASSERT(stream_);
|
||||
|
||||
std::vector<char *> attributes_in;
|
||||
attributes_in.reserve(attributes.size());
|
||||
for (auto& attribute : attributes) {
|
||||
attributes_in.push_back(const_cast<char *>(attribute.c_str()));
|
||||
if (Matches(old_stream_, ufrag, pwd)) {
|
||||
// Roll back to old stream, since we apparently aren't using the new one
|
||||
// (We swap before we close so we never have stream_ == nullptr)
|
||||
std::swap(stream_, old_stream_);
|
||||
CloseStream(&old_stream_);
|
||||
} else if (old_stream_) {
|
||||
// Right now we wait for ICE to complete before closing the old stream.
|
||||
// It might be worth it to close it sooner, but we don't want to close it
|
||||
// right away.
|
||||
nr_ice_media_stream_set_obsolete(old_stream_);
|
||||
}
|
||||
|
||||
// Still need to call nr_ice_ctx_parse_stream_attributes.
|
||||
int r = nr_ice_peer_ctx_parse_stream_attributes(ctx_peer_,
|
||||
stream_,
|
||||
attributes_in.empty() ?
|
||||
nullptr : &attributes_in[0],
|
||||
attributes_in.size());
|
||||
nr_ice_media_stream* peer_stream;
|
||||
if (nr_ice_peer_ctx_find_pstream(ctx_peer_, stream_, &peer_stream)) {
|
||||
// No peer yet
|
||||
std::vector<char *> attributes_in;
|
||||
attributes_in.reserve(attributes.size());
|
||||
for (auto& attribute : attributes) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Setting " << attribute << " on stream " << name_);
|
||||
attributes_in.push_back(const_cast<char *>(attribute.c_str()));
|
||||
}
|
||||
|
||||
// Still need to call nr_ice_ctx_parse_stream_attributes.
|
||||
int r = nr_ice_peer_ctx_parse_stream_attributes(ctx_peer_,
|
||||
stream_,
|
||||
attributes_in.empty() ?
|
||||
nullptr : &attributes_in[0],
|
||||
attributes_in.size());
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't parse attributes for stream "
|
||||
<< name_ << "'");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::SetIceCredentials(const std::string& ufrag,
|
||||
const std::string& pwd) {
|
||||
if (Matches(stream_, ufrag, pwd)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, "Setting ICE credentials for " << name_ << " - "
|
||||
<< ufrag << ":" << pwd);
|
||||
CloseStream(&old_stream_);
|
||||
old_stream_ = stream_;
|
||||
|
||||
std::string name(name_ + " - " + ufrag + ":" + pwd);
|
||||
|
||||
int r = nr_ice_add_media_stream(ctx_,
|
||||
name.c_str(),
|
||||
ufrag.c_str(),
|
||||
pwd.c_str(),
|
||||
components_, &stream_);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't parse attributes for stream "
|
||||
<< name_ << "'");
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't create ICE media stream for '"
|
||||
<< name_ << "': error=" << r);
|
||||
stream_ = old_stream_;
|
||||
old_stream_ = nullptr;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
has_parsed_attrs_ = true;
|
||||
state_ = ICE_CONNECTING;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Parse trickle ICE candidate
|
||||
nsresult NrIceMediaStream::ParseTrickleCandidate(const std::string& candidate) {
|
||||
// TODO(bug 1490658): This needs to take ufrag into account. For now, trickle
|
||||
// candidates will land on the most recently-created ICE stream.
|
||||
int r;
|
||||
|
||||
MOZ_MTLOG(ML_DEBUG, "NrIceCtx(" << ctx_->label << ")/STREAM(" <<
|
||||
|
@ -463,7 +499,7 @@ nsresult NrIceMediaStream::GetDefaultCandidate(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::string> NrIceMediaStream::GetCandidates() const {
|
||||
std::vector<std::string> NrIceMediaStream::GetAttributes() const {
|
||||
char **attrs = nullptr;
|
||||
int attrct;
|
||||
int r;
|
||||
|
@ -587,13 +623,19 @@ nsresult NrIceMediaStream::GetConsentStatus(int component_id, bool *can_send, st
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool NrIceMediaStream::HasStream(nr_ice_media_stream *stream) const {
|
||||
return (stream == stream_) || (stream == old_stream_);
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::SendPacket(int component_id,
|
||||
const unsigned char *data,
|
||||
size_t len) {
|
||||
if (!stream_)
|
||||
nr_ice_media_stream* stream = old_stream_ ? old_stream_ : stream_;
|
||||
if (!stream) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int r = nr_ice_media_stream_send(ctx_peer_, stream_,
|
||||
int r = nr_ice_media_stream_send(ctx_peer_, stream,
|
||||
component_id,
|
||||
const_cast<unsigned char *>(data), len);
|
||||
if (r) {
|
||||
|
@ -615,6 +657,7 @@ void NrIceMediaStream::Ready() {
|
|||
if (state_ != ICE_OPEN) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Marking stream ready '" << name_ << "'");
|
||||
state_ = ICE_OPEN;
|
||||
CloseStream(&old_stream_);
|
||||
SignalReady(this);
|
||||
}
|
||||
else {
|
||||
|
@ -622,16 +665,34 @@ void NrIceMediaStream::Ready() {
|
|||
}
|
||||
}
|
||||
|
||||
void NrIceMediaStream::Failed() {
|
||||
if (state_ != ICE_CLOSED) {
|
||||
MOZ_MTLOG(ML_DEBUG, "Marking stream failed '" << name_ << "'");
|
||||
state_ = ICE_CLOSED;
|
||||
// We don't need the old stream anymore.
|
||||
CloseStream(&old_stream_);
|
||||
SignalFailed(this);
|
||||
}
|
||||
}
|
||||
|
||||
void NrIceMediaStream::Close() {
|
||||
MOZ_MTLOG(ML_DEBUG, "Marking stream closed '" << name_ << "'");
|
||||
state_ = ICE_CLOSED;
|
||||
|
||||
if (stream_) {
|
||||
int r = nr_ice_remove_media_stream(ctx_, &stream_);
|
||||
CloseStream(&old_stream_);
|
||||
CloseStream(&stream_);
|
||||
}
|
||||
|
||||
void
|
||||
NrIceMediaStream::CloseStream(nr_ice_media_stream **stream)
|
||||
{
|
||||
if (*stream) {
|
||||
int r = nr_ice_remove_media_stream(ctx_, stream);
|
||||
if (r) {
|
||||
MOZ_ASSERT(false, "Failed to remove stream");
|
||||
MOZ_MTLOG(ML_ERROR, "Failed to remove stream, error=" << r);
|
||||
}
|
||||
*stream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,9 +137,15 @@ struct NrIceCandidatePair {
|
|||
|
||||
class NrIceMediaStream {
|
||||
public:
|
||||
static RefPtr<NrIceMediaStream> Create(NrIceCtx *ctx,
|
||||
const std::string& name,
|
||||
int components);
|
||||
NrIceMediaStream(NrIceCtx *ctx,
|
||||
const std::string& id,
|
||||
const std::string& name,
|
||||
size_t components);
|
||||
|
||||
nsresult SetIceCredentials(const std::string& ufrag, const std::string& pwd);
|
||||
nsresult ConnectToPeer(const std::string& ufrag,
|
||||
const std::string& pwd,
|
||||
const std::vector<std::string>& peer_attrs);
|
||||
enum State { ICE_CONNECTING, ICE_OPEN, ICE_CLOSED};
|
||||
|
||||
State state() const { return state_; }
|
||||
|
@ -147,8 +153,8 @@ class NrIceMediaStream {
|
|||
// The name of the stream
|
||||
const std::string& name() const { return name_; }
|
||||
|
||||
// Get all the candidates
|
||||
std::vector<std::string> GetCandidates() const;
|
||||
// Get all the ICE attributes; used for testing
|
||||
std::vector<std::string> GetAttributes() const;
|
||||
|
||||
nsresult GetLocalCandidates(std::vector<NrIceCandidate>* candidates) const;
|
||||
nsresult GetRemoteCandidates(std::vector<NrIceCandidate>* candidates) const;
|
||||
|
@ -159,10 +165,6 @@ class NrIceMediaStream {
|
|||
|
||||
nsresult GetDefaultCandidate(int component, NrIceCandidate* candidate) const;
|
||||
|
||||
// Parse remote attributes
|
||||
nsresult ParseAttributes(std::vector<std::string>& candidates);
|
||||
bool HasParsedAttributes() const { return has_parsed_attrs_; }
|
||||
|
||||
// Parse trickle ICE candidate
|
||||
nsresult ParseTrickleCandidate(const std::string& candidate);
|
||||
|
||||
|
@ -182,8 +184,7 @@ class NrIceMediaStream {
|
|||
// The number of components
|
||||
size_t components() const { return components_; }
|
||||
|
||||
// The underlying nICEr stream
|
||||
nr_ice_media_stream *stream() { return stream_; }
|
||||
bool HasStream(nr_ice_media_stream *stream) const;
|
||||
// Signals to indicate events. API users can (and should)
|
||||
// register for these.
|
||||
|
||||
|
@ -192,6 +193,7 @@ class NrIceMediaStream {
|
|||
|
||||
// Set your state to ready. Called by the NrIceCtx;
|
||||
void Ready();
|
||||
void Failed();
|
||||
|
||||
// Close the stream. Called by the NrIceCtx.
|
||||
// Different from the destructor because other people
|
||||
|
@ -201,8 +203,6 @@ class NrIceMediaStream {
|
|||
|
||||
// So the receiver of SignalCandidate can determine which transport
|
||||
// the candidate belongs to.
|
||||
void SetId(const std::string& id) { id_ = id; }
|
||||
|
||||
const std::string& GetId() const { return id_; }
|
||||
|
||||
sigslot::signal2<NrIceMediaStream *, const std::string& >
|
||||
|
@ -216,22 +216,20 @@ class NrIceMediaStream {
|
|||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NrIceMediaStream)
|
||||
|
||||
private:
|
||||
NrIceMediaStream(NrIceCtx *ctx,
|
||||
const std::string& name,
|
||||
size_t components);
|
||||
|
||||
~NrIceMediaStream();
|
||||
|
||||
DISALLOW_COPY_ASSIGN(NrIceMediaStream);
|
||||
|
||||
void CloseStream(nr_ice_media_stream **stream);
|
||||
|
||||
State state_;
|
||||
nr_ice_ctx *ctx_;
|
||||
nr_ice_peer_ctx *ctx_peer_;
|
||||
const std::string name_;
|
||||
const size_t components_;
|
||||
nr_ice_media_stream *stream_;
|
||||
std::string id_;
|
||||
bool has_parsed_attrs_;
|
||||
nr_ice_media_stream *old_stream_;
|
||||
const std::string id_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "nsIDNSService.h"
|
||||
#include "nsIDNSListener.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "nricectx.h"
|
||||
|
||||
typedef struct nr_resolver_ nr_resolver;
|
||||
typedef struct nr_resolver_vtbl_ nr_resolver_vtbl;
|
||||
|
|
|
@ -23,7 +23,20 @@
|
|||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
#include "nricectxhandler.h"
|
||||
extern "C" {
|
||||
#include "r_types.h"
|
||||
#include "async_wait.h"
|
||||
#include "async_timer.h"
|
||||
#include "r_data.h"
|
||||
#include "util.h"
|
||||
#include "r_time.h"
|
||||
}
|
||||
|
||||
#include "ice_ctx.h"
|
||||
#include "ice_peer_ctx.h"
|
||||
#include "ice_media_stream.h"
|
||||
|
||||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "nriceresolverfake.h"
|
||||
#include "nriceresolver.h"
|
||||
|
@ -38,17 +51,6 @@
|
|||
#include "stun_socket_filter.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
|
||||
#include "ice_ctx.h"
|
||||
#include "ice_peer_ctx.h"
|
||||
#include "ice_media_stream.h"
|
||||
|
||||
extern "C" {
|
||||
#include "async_timer.h"
|
||||
#include "r_data.h"
|
||||
#include "util.h"
|
||||
#include "r_time.h"
|
||||
}
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
#include "gtest/gtest.h"
|
||||
#include "gtest_utils.h"
|
||||
|
@ -380,9 +382,9 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
bool allow_link_local = false,
|
||||
NrIceCtx::Policy ice_policy = NrIceCtx::ICE_POLICY_ALL) :
|
||||
name_(name),
|
||||
ice_ctx_(NrIceCtxHandler::Create(name, allow_loopback,
|
||||
enable_tcp, allow_link_local,
|
||||
ice_policy)),
|
||||
ice_ctx_(NrIceCtx::Create(name, allow_loopback,
|
||||
enable_tcp, allow_link_local,
|
||||
ice_policy)),
|
||||
offerer_(offerer),
|
||||
candidates_(),
|
||||
stream_counter_(0),
|
||||
|
@ -405,16 +407,16 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
simulate_ice_lite_(false),
|
||||
nat_(new TestNat),
|
||||
test_utils_(utils) {
|
||||
ice_ctx_->ctx()->SignalGatheringStateChange.connect(
|
||||
ice_ctx_->SignalGatheringStateChange.connect(
|
||||
this,
|
||||
&IceTestPeer::GatheringStateChange);
|
||||
ice_ctx_->ctx()->SignalConnectionStateChange.connect(
|
||||
ice_ctx_->SignalConnectionStateChange.connect(
|
||||
this,
|
||||
&IceTestPeer::ConnectionStateChange);
|
||||
|
||||
consent_timestamp_.tv_sec = 0;
|
||||
consent_timestamp_.tv_usec = 0;
|
||||
int r = ice_ctx_->ctx()->SetNat(nat_);
|
||||
int r = ice_ctx_->SetNat(nat_);
|
||||
(void)r;
|
||||
MOZ_ASSERT(!r);
|
||||
}
|
||||
|
@ -435,13 +437,28 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
return id;
|
||||
}
|
||||
|
||||
void SetIceCredentials_s(NrIceMediaStream &stream) {
|
||||
static size_t counter = 0;
|
||||
std::ostringstream prefix;
|
||||
prefix << name_ << "-" << counter++;
|
||||
std::string ufrag = prefix.str() + "-ufrag";
|
||||
std::string pwd = prefix.str() + "-pwd";
|
||||
if (mIceCredentials.count(stream.GetId())) {
|
||||
mOldIceCredentials[stream.GetId()] = mIceCredentials[stream.GetId()];
|
||||
}
|
||||
mIceCredentials[stream.GetId()] = std::make_pair(ufrag, pwd);
|
||||
stream.SetIceCredentials(ufrag, pwd);
|
||||
}
|
||||
|
||||
void AddStream_s(int components) {
|
||||
std::string id = MakeTransportId(stream_counter_++);
|
||||
|
||||
RefPtr<NrIceMediaStream> stream = ice_ctx_->CreateStream(id, components);
|
||||
ice_ctx_->ctx()->SetStream(id, stream);
|
||||
RefPtr<NrIceMediaStream> stream =
|
||||
ice_ctx_->CreateStream(id, id, components);
|
||||
|
||||
ASSERT_TRUE(stream);
|
||||
SetIceCredentials_s(*stream);
|
||||
|
||||
stream->SignalCandidate.connect(this, &IceTestPeer::CandidateInitialized);
|
||||
stream->SignalReady.connect(this, &IceTestPeer::StreamReady);
|
||||
stream->SignalFailed.connect(this, &IceTestPeer::StreamFailed);
|
||||
|
@ -456,7 +473,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
void RemoveStream_s(size_t index) {
|
||||
ice_ctx_->ctx()->SetStream(MakeTransportId(index), nullptr);
|
||||
ice_ctx_->DestroyStream(MakeTransportId(index));
|
||||
}
|
||||
|
||||
void RemoveStream(size_t index) {
|
||||
|
@ -467,7 +484,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
RefPtr<NrIceMediaStream> GetStream_s(size_t index) {
|
||||
std::string id = MakeTransportId(index);
|
||||
return ice_ctx_->ctx()->GetStream(id);
|
||||
return ice_ctx_->GetStream(id);
|
||||
}
|
||||
|
||||
void SetStunServer(const std::string addr, uint16_t port,
|
||||
|
@ -485,7 +502,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
void SetStunServers(const std::vector<NrIceStunServer> &servers) {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetStunServers(servers)));
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(servers)));
|
||||
}
|
||||
|
||||
void UseTestStunServer() {
|
||||
|
@ -510,11 +527,11 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
UniquePtr<NrIceTurnServer> server(NrIceTurnServer::Create(
|
||||
addr, port, username, password, transport));
|
||||
turn_servers.push_back(*server);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetTurnServers(turn_servers)));
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetTurnServers(turn_servers)));
|
||||
}
|
||||
|
||||
void SetTurnServers(const std::vector<NrIceTurnServer> servers) {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetTurnServers(servers)));
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetTurnServers(servers)));
|
||||
}
|
||||
|
||||
void SetFakeResolver(const std::string& ip,
|
||||
|
@ -527,13 +544,13 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
ASSERT_EQ(PR_SUCCESS, status);
|
||||
fake_resolver_.SetAddr(fqdn, addr);
|
||||
}
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetResolver(
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver(
|
||||
fake_resolver_.AllocateResolver())));
|
||||
}
|
||||
|
||||
void SetDNSResolver() {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(dns_resolver_->Init()));
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetResolver(
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver(
|
||||
dns_resolver_->AllocateResolver())));
|
||||
}
|
||||
|
||||
|
@ -542,7 +559,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res,
|
||||
ice_ctx_->ctx(),
|
||||
ice_ctx_,
|
||||
&NrIceCtx::StartGathering,
|
||||
default_route_only,
|
||||
false),
|
||||
|
@ -556,7 +573,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
void SetTimerDivider(int div) {
|
||||
ice_ctx_->ctx()->internal_SetTimerAccelarator(div);
|
||||
ice_ctx_->internal_SetTimerAccelarator(div);
|
||||
}
|
||||
|
||||
void SetStunResponseDelay(uint32_t delay) {
|
||||
|
@ -584,19 +601,19 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
// Get various pieces of state
|
||||
std::vector<std::string> GetGlobalAttributes() {
|
||||
std::vector<std::string> attrs(ice_ctx_->ctx()->GetGlobalAttributes());
|
||||
std::vector<std::string> attrs(ice_ctx_->GetGlobalAttributes());
|
||||
if (simulate_ice_lite_) {
|
||||
attrs.push_back("ice-lite");
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetCandidates(size_t stream) {
|
||||
std::vector<std::string> GetAttributes(size_t stream) {
|
||||
std::vector<std::string> v;
|
||||
|
||||
RUN_ON_THREAD(
|
||||
test_utils_->sts_target(),
|
||||
WrapRunnableRet(&v, this, &IceTestPeer::GetCandidates_s, stream));
|
||||
WrapRunnableRet(&v, this, &IceTestPeer::GetAttributes_s, stream));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
@ -608,27 +625,31 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
return candidate;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetCandidates_s(size_t index) {
|
||||
std::vector<std::string> candidates;
|
||||
std::vector<std::string> GetAttributes_s(size_t index) {
|
||||
std::vector<std::string> attributes;
|
||||
|
||||
auto stream = GetStream_s(index);
|
||||
if (!stream) {
|
||||
EXPECT_TRUE(false) << "No such stream " << index;
|
||||
return candidates;
|
||||
return attributes;
|
||||
}
|
||||
|
||||
std::vector<std::string> candidates_in = stream->GetCandidates();
|
||||
std::vector<std::string> attributes_in = stream->GetAttributes();
|
||||
|
||||
for (const auto& a_candidate : candidates_in) {
|
||||
std::string candidate(FilterCandidate(a_candidate));
|
||||
if (!candidate.empty()) {
|
||||
std::cerr << name_ << " Returning candidate: "
|
||||
<< candidate << std::endl;
|
||||
candidates.push_back(candidate);
|
||||
for (const auto& attribute : attributes_in) {
|
||||
if (attribute.find("candidate:") != std::string::npos) {
|
||||
std::string candidate(FilterCandidate(attribute));
|
||||
if (!candidate.empty()) {
|
||||
std::cerr << name_ << " Returning candidate: "
|
||||
<< candidate << std::endl;
|
||||
attributes.push_back(candidate);
|
||||
}
|
||||
} else {
|
||||
attributes.push_back(attribute);
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
return attributes;
|
||||
}
|
||||
|
||||
void SetExpectedTypes(NrIceCandidate::Type local,
|
||||
|
@ -644,13 +665,13 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
int GetCandidatesPrivateIpv4Range(size_t stream) {
|
||||
std::vector<std::string> candidates = GetCandidates(stream);
|
||||
std::vector<std::string> attributes = GetAttributes(stream);
|
||||
|
||||
int host_net = 0;
|
||||
for (const auto& c : candidates) {
|
||||
if (c.find("typ host") != std::string::npos) {
|
||||
for (const auto& a : attributes) {
|
||||
if (a.find("typ host") != std::string::npos) {
|
||||
nr_transport_addr addr;
|
||||
std::vector<std::string> tokens = split(c, ' ');
|
||||
std::vector<std::string> tokens = split(a, ' ');
|
||||
int r = nr_str_port_to_transport_addr(tokens.at(4).c_str(), 0, IPPROTO_UDP, &addr);
|
||||
MOZ_ASSERT(!r);
|
||||
if (!r && (addr.ip_version == NR_IPV4)) {
|
||||
|
@ -697,23 +718,15 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
void RestartIce() {
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnable(this,
|
||||
&IceTestPeer::RestartIce_s,
|
||||
ice_ctx_->CreateCtx()),
|
||||
&IceTestPeer::RestartIce_s),
|
||||
NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
|
||||
void RestartIce_s(RefPtr<NrIceCtx> new_ctx) {
|
||||
ice_ctx_->BeginIceRestart(new_ctx);
|
||||
|
||||
// set signals for the newly restarted ctx
|
||||
ice_ctx_->ctx()->SignalGatheringStateChange.connect(
|
||||
this,
|
||||
&IceTestPeer::GatheringStateChange);
|
||||
ice_ctx_->ctx()->SignalConnectionStateChange.connect(
|
||||
this,
|
||||
&IceTestPeer::ConnectionStateChange);
|
||||
|
||||
void RestartIce_s() {
|
||||
for (auto& stream : ice_ctx_->GetStreams()) {
|
||||
SetIceCredentials_s(*stream);
|
||||
}
|
||||
// take care of some local bookkeeping
|
||||
ready_ct_ = 0;
|
||||
gathering_complete_ = false;
|
||||
|
@ -721,19 +734,6 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
ice_failed_ = false;
|
||||
ice_reached_checking_ = false;
|
||||
remote_ = nullptr;
|
||||
stream_counter_ = 0;
|
||||
}
|
||||
|
||||
|
||||
void FinalizeIceRestart() {
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnable(this, &IceTestPeer::FinalizeIceRestart_s),
|
||||
NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
|
||||
void FinalizeIceRestart_s() {
|
||||
ice_ctx_->FinalizeIceRestart();
|
||||
}
|
||||
|
||||
|
||||
|
@ -745,7 +745,9 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
|
||||
void RollbackIceRestart_s() {
|
||||
ice_ctx_->RollbackIceRestart();
|
||||
for (auto& stream : ice_ctx_->GetStreams()) {
|
||||
mIceCredentials[stream->GetId()] = mOldIceCredentials[stream->GetId()];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -760,44 +762,38 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
ice_connected_ = false;
|
||||
ice_failed_ = false;
|
||||
ice_reached_checking_ = false;
|
||||
res = ice_ctx_->ctx()->ParseGlobalAttributes(remote->GetGlobalAttributes());
|
||||
res = ice_ctx_->ParseGlobalAttributes(remote->GetGlobalAttributes());
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
|
||||
if (trickle_mode == TRICKLE_NONE ||
|
||||
trickle_mode == TRICKLE_REAL) {
|
||||
for (size_t i=0; i<stream_counter_; ++i) {
|
||||
auto aStream = GetStream_s(i);
|
||||
if (!aStream || aStream->HasParsedAttributes()) {
|
||||
continue;
|
||||
}
|
||||
std::vector<std::string> candidates =
|
||||
remote->GetCandidates(i);
|
||||
for (size_t i=0; i<stream_counter_; ++i) {
|
||||
auto aStream = GetStream_s(i);
|
||||
if (aStream) {
|
||||
std::vector<std::string> attributes = remote->GetAttributes(i);
|
||||
|
||||
for (const auto& candidate : candidates) {
|
||||
std::cerr << name_ << " Adding remote candidate: " + candidate << std::endl;
|
||||
for (auto it = attributes.begin(); it != attributes.end();) {
|
||||
if (trickle_mode == TRICKLE_SIMULATE &&
|
||||
it->find("candidate:") != std::string::npos) {
|
||||
std::cerr << name_ << " Deferring remote candidate: " << *it
|
||||
<< std::endl;
|
||||
attributes.erase(it);
|
||||
} else {
|
||||
std::cerr << name_ << " Adding remote attribute: " + *it
|
||||
<< std::endl;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
res = aStream->ParseAttributes(candidates);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
}
|
||||
} else {
|
||||
// Parse empty attributes and then trickle them out later
|
||||
for (size_t i=0; i<stream_counter_; ++i) {
|
||||
auto aStream = GetStream_s(i);
|
||||
if (!aStream || aStream->HasParsedAttributes()) {
|
||||
continue;
|
||||
}
|
||||
std::vector<std::string> empty_attrs;
|
||||
std::cout << "Calling ParseAttributes on stream " << i << std::endl;
|
||||
res = aStream->ParseAttributes(empty_attrs);
|
||||
auto credentials = mIceCredentials[aStream->GetId()];
|
||||
res = aStream->ConnectToPeer(
|
||||
credentials.first, credentials.second, attributes);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
}
|
||||
}
|
||||
|
||||
if (start) {
|
||||
ice_ctx_->ctx()->SetControlling(
|
||||
ice_ctx_->SetControlling(
|
||||
offerer_ ? NrIceCtx::ICE_CONTROLLING : NrIceCtx::ICE_CONTROLLED);
|
||||
// Now start checks
|
||||
res = ice_ctx_->ctx()->StartChecks(offerer_);
|
||||
res = ice_ctx_->StartChecks(offerer_);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
}
|
||||
}
|
||||
|
@ -829,13 +825,14 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
std::vector<SchedulableTrickleCandidate*>& ControlTrickle(size_t stream) {
|
||||
std::cerr << "Doing controlled trickle for stream " << stream << std::endl;
|
||||
|
||||
std::vector<std::string> candidates =
|
||||
remote_->GetCandidates(stream);
|
||||
std::vector<std::string> attributes = remote_->GetAttributes(stream);
|
||||
|
||||
for (const auto& candidate : candidates) {
|
||||
controlled_trickle_candidates_[stream].push_back(
|
||||
new SchedulableTrickleCandidate(
|
||||
this, stream, candidate, test_utils_));
|
||||
for (const auto& attribute : attributes) {
|
||||
if (attribute.find("candidate:") != std::string::npos) {
|
||||
controlled_trickle_candidates_[stream].push_back(
|
||||
new SchedulableTrickleCandidate(
|
||||
this, stream, attribute, test_utils_));
|
||||
}
|
||||
}
|
||||
|
||||
return controlled_trickle_candidates_[stream];
|
||||
|
@ -919,7 +916,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
void DumpAndCheckActiveCandidates_s() {
|
||||
std::cerr << name_ << " Active candidates:" << std::endl;
|
||||
for (const auto& stream : ice_ctx_->ctx()->GetStreams()) {
|
||||
for (const auto& stream : ice_ctx_->GetStreams()) {
|
||||
for (size_t j=0; j < stream->components(); ++j) {
|
||||
std::cerr << name_ << " Stream " << stream->GetId()
|
||||
<< " component " << j+1 << std::endl;
|
||||
|
@ -969,7 +966,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
void Close() {
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnable(ice_ctx_->ctx(), &NrIceCtx::destroy_peer_ctx),
|
||||
WrapRunnable(ice_ctx_, &NrIceCtx::destroy_peer_ctx),
|
||||
NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
|
@ -999,13 +996,13 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
nsresult res;
|
||||
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res, ice_ctx_->ctx(), &NrIceCtx::SetControlling,
|
||||
WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::SetControlling,
|
||||
offerer_ ?
|
||||
NrIceCtx::ICE_CONTROLLING : NrIceCtx::ICE_CONTROLLED),
|
||||
NS_DISPATCH_SYNC);
|
||||
// Now start checks
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res, ice_ctx_->ctx(), &NrIceCtx::StartChecks,
|
||||
WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::StartChecks,
|
||||
offerer_),
|
||||
NS_DISPATCH_SYNC);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
|
@ -1024,14 +1021,14 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
std::cerr << name_ << " Gathering complete" << std::endl;
|
||||
gathering_complete_ = true;
|
||||
|
||||
std::cerr << name_ << " CANDIDATES:" << std::endl;
|
||||
for (const auto& stream : ice_ctx_->ctx()->GetStreams()) {
|
||||
std::cerr << name_ << " ATTRIBUTES:" << std::endl;
|
||||
for (const auto& stream : ice_ctx_->GetStreams()) {
|
||||
std::cerr << "Stream " << stream->GetId() << std::endl;
|
||||
|
||||
std::vector<std::string> candidates = stream->GetCandidates();
|
||||
std::vector<std::string> attributes = stream->GetAttributes();
|
||||
|
||||
for(const auto& candidate : candidates) {
|
||||
std::cerr << candidate << std::endl;
|
||||
for(const auto& attribute : attributes) {
|
||||
std::cerr << attribute << std::endl;
|
||||
}
|
||||
}
|
||||
std::cerr << std::endl;
|
||||
|
@ -1116,7 +1113,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
void DumpCandidatePairs_s() {
|
||||
std::cerr << "Dumping candidate pairs for all streams [" << std::endl;
|
||||
for (const auto& stream : ice_ctx_->ctx()->GetStreams()) {
|
||||
for (const auto& stream : ice_ctx_->GetStreams()) {
|
||||
DumpCandidatePairs_s(stream.get());
|
||||
}
|
||||
std::cerr << "]" << std::endl;
|
||||
|
@ -1281,11 +1278,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
void ParseCandidate_s(size_t i, const std::string& candidate) {
|
||||
auto media_stream = GetStream_s(i);
|
||||
ASSERT_TRUE(media_stream.get()) << "No such stream " << i;
|
||||
|
||||
std::vector<std::string> attributes;
|
||||
|
||||
attributes.push_back(candidate);
|
||||
media_stream->ParseAttributes(attributes);
|
||||
media_stream->ParseTrickleCandidate(candidate);
|
||||
}
|
||||
|
||||
void ParseCandidate(size_t i, const std::string& candidate)
|
||||
|
@ -1355,7 +1348,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
void ChangeNetworkState_s(bool online) {
|
||||
ice_ctx_->ctx()->UpdateNetworkState(online);
|
||||
ice_ctx_->UpdateNetworkState(online);
|
||||
}
|
||||
|
||||
void ChangeNetworkStateToOffline() {
|
||||
|
@ -1377,7 +1370,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
void SetControlling(NrIceCtx::Controlling controlling) {
|
||||
nsresult res;
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res, ice_ctx_->ctx(),
|
||||
WrapRunnableRet(&res, ice_ctx_,
|
||||
&NrIceCtx::SetControlling,
|
||||
controlling),
|
||||
NS_DISPATCH_SYNC);
|
||||
|
@ -1385,7 +1378,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
NrIceCtx::Controlling GetControlling() {
|
||||
return ice_ctx_->ctx()->GetControlling();
|
||||
return ice_ctx_->GetControlling();
|
||||
}
|
||||
|
||||
void SetTiebreaker(uint64_t tiebreaker) {
|
||||
|
@ -1397,7 +1390,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
}
|
||||
|
||||
void SetTiebreaker_s(uint64_t tiebreaker) {
|
||||
ice_ctx_->ctx()->peer()->tiebreaker = tiebreaker;
|
||||
ice_ctx_->peer()->tiebreaker = tiebreaker;
|
||||
}
|
||||
|
||||
void SimulateIceLite() {
|
||||
|
@ -1423,12 +1416,14 @@ class IceTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
private:
|
||||
std::string name_;
|
||||
RefPtr<NrIceCtxHandler> ice_ctx_;
|
||||
RefPtr<NrIceCtx> ice_ctx_;
|
||||
bool offerer_;
|
||||
std::map<std::string, std::vector<std::string> > candidates_;
|
||||
// Maps from stream id to list of remote trickle candidates
|
||||
std::map<size_t, std::vector<SchedulableTrickleCandidate*> >
|
||||
controlled_trickle_candidates_;
|
||||
std::map<std::string, std::pair<std::string, std::string>> mIceCredentials;
|
||||
std::map<std::string, std::pair<std::string, std::string>> mOldIceCredentials;
|
||||
size_t stream_counter_;
|
||||
bool shutting_down_;
|
||||
bool gathering_complete_;
|
||||
|
@ -1598,11 +1593,11 @@ class WebRtcIceGatherTest : public StunTest {
|
|||
bool StreamHasMatchingCandidate(unsigned int stream,
|
||||
const std::string& match,
|
||||
const std::string& match2 = "") {
|
||||
std::vector<std::string> candidates = peer_->GetCandidates(stream);
|
||||
for (auto& candidate : candidates) {
|
||||
if (std::string::npos != candidate.find(match)) {
|
||||
std::vector<std::string> attributes = peer_->GetAttributes(stream);
|
||||
for (auto& attribute : attributes) {
|
||||
if (std::string::npos != attribute.find(match)) {
|
||||
if (!match2.length() ||
|
||||
std::string::npos != candidate.find(match2)) {
|
||||
std::string::npos != attribute.find(match2)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1610,14 +1605,14 @@ class WebRtcIceGatherTest : public StunTest {
|
|||
return false;
|
||||
}
|
||||
|
||||
void DumpCandidates(unsigned int stream) {
|
||||
std::vector<std::string> candidates = peer_->GetCandidates(stream);
|
||||
void DumpAttributes(unsigned int stream) {
|
||||
std::vector<std::string> attributes = peer_->GetAttributes(stream);
|
||||
|
||||
std::cerr << "Candidates for stream " << stream << "->"
|
||||
<< candidates.size() << std::endl;
|
||||
std::cerr << "Attributes for stream " << stream << "->"
|
||||
<< attributes.size() << std::endl;
|
||||
|
||||
for (const auto& c : candidates) {
|
||||
std::cerr << "Candidate: " << c << std::endl;
|
||||
for (const auto& a : attributes) {
|
||||
std::cerr << "Attribute: " << a << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1812,7 +1807,9 @@ class WebRtcIceConnectTest : public StunTest {
|
|||
ConnectCallerAndCallee(p1_.get(), p2_.get());
|
||||
}
|
||||
|
||||
void ConnectCallerAndCallee(IceTestPeer* caller, IceTestPeer* callee) {
|
||||
void ConnectCallerAndCallee(IceTestPeer* caller,
|
||||
IceTestPeer* callee,
|
||||
TrickleMode mode = TRICKLE_NONE) {
|
||||
ASSERT_TRUE(caller->ready_ct() == 0);
|
||||
ASSERT_TRUE(caller->ice_connected() == 0);
|
||||
ASSERT_TRUE(caller->ice_reached_checking() == 0);
|
||||
|
@ -1824,19 +1821,20 @@ class WebRtcIceConnectTest : public StunTest {
|
|||
// gives them to |this|, meaning that callee->Connect(caller, ...)
|
||||
// simulates caller sending an offer to callee. Order matters here
|
||||
// because it determines which peer is controlling.
|
||||
callee->Connect(caller, TRICKLE_NONE);
|
||||
caller->Connect(callee, TRICKLE_NONE);
|
||||
callee->Connect(caller, mode);
|
||||
caller->Connect(callee, mode);
|
||||
|
||||
ASSERT_TRUE_WAIT(caller->ready_ct() == 1 && callee->ready_ct() == 1,
|
||||
kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(caller->ice_connected() && callee->ice_connected(),
|
||||
kDefaultTimeout);
|
||||
if (mode != TRICKLE_SIMULATE) {
|
||||
ASSERT_TRUE_WAIT(caller->ready_ct() == 1 && callee->ready_ct() == 1,
|
||||
kDefaultTimeout);
|
||||
ASSERT_TRUE_WAIT(caller->ice_connected() && callee->ice_connected(),
|
||||
kDefaultTimeout);
|
||||
ASSERT_TRUE(caller->ice_reached_checking());
|
||||
ASSERT_TRUE(callee->ice_reached_checking());
|
||||
|
||||
ASSERT_TRUE(caller->ice_reached_checking());
|
||||
ASSERT_TRUE(callee->ice_reached_checking());
|
||||
|
||||
caller->DumpAndCheckActiveCandidates();
|
||||
callee->DumpAndCheckActiveCandidates();
|
||||
caller->DumpAndCheckActiveCandidates();
|
||||
callee->DumpAndCheckActiveCandidates();
|
||||
}
|
||||
}
|
||||
|
||||
void SetExpectedTypes(NrIceCandidate::Type local, NrIceCandidate::Type remote,
|
||||
|
@ -1941,15 +1939,18 @@ class WebRtcIceConnectTest : public StunTest {
|
|||
size_t previousSent = p1->sent();
|
||||
size_t previousReceived = p2->received();
|
||||
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnable(p1,
|
||||
&IceTestPeer::SendPacket, 0, 1,
|
||||
reinterpret_cast<const unsigned char *>("TEST"), 4),
|
||||
NS_DISPATCH_SYNC);
|
||||
|
||||
if (expect_tx_failure) {
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnable(p1, &IceTestPeer::SendFailure, 0, 1),
|
||||
NS_DISPATCH_SYNC);
|
||||
ASSERT_EQ(previousSent, p1->sent());
|
||||
} else {
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnable(p1,
|
||||
&IceTestPeer::SendPacket, 0, 1,
|
||||
reinterpret_cast<const unsigned char *>("TEST"), 4),
|
||||
NS_DISPATCH_SYNC);
|
||||
ASSERT_EQ(previousSent+1, p1->sent());
|
||||
}
|
||||
if (expect_rx_failure) {
|
||||
|
@ -2036,7 +2037,7 @@ class WebRtcIcePacketFilterTest : public StunTest {
|
|||
StunTest::SetUp();
|
||||
|
||||
// Set up enough of the ICE ctx to allow the packet filter to work
|
||||
ice_ctx_ = NrIceCtxHandler::Create("test", true);
|
||||
ice_ctx_ = NrIceCtx::Create("test", true);
|
||||
|
||||
nsCOMPtr<nsISocketFilterHandler> udp_handler =
|
||||
do_GetService(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID);
|
||||
|
@ -2148,7 +2149,7 @@ class WebRtcIcePacketFilterTest : public StunTest {
|
|||
|
||||
nsCOMPtr<nsISocketFilter> udp_filter_;
|
||||
nsCOMPtr<nsISocketFilter> tcp_filter_;
|
||||
RefPtr<NrIceCtxHandler> ice_ctx_;
|
||||
RefPtr<NrIceCtx> ice_ctx_;
|
||||
};
|
||||
} // end namespace
|
||||
|
||||
|
@ -2363,12 +2364,13 @@ TEST_F(WebRtcIceGatherTest, TestGatherDisableComponent) {
|
|||
peer_->AddStream(2);
|
||||
peer_->DisableComponent(1, 2);
|
||||
Gather();
|
||||
std::vector<std::string> candidates =
|
||||
peer_->GetCandidates(1);
|
||||
std::vector<std::string> attributes = peer_->GetAttributes(1);
|
||||
|
||||
for (auto& candidate : candidates) {
|
||||
size_t sp1 = candidate.find(' ');
|
||||
ASSERT_EQ(0, candidate.compare(sp1+1, 1, "1", 1));
|
||||
for (auto& attribute : attributes) {
|
||||
if (attribute.find("candidate:") != std::string::npos) {
|
||||
size_t sp1 = attribute.find(' ');
|
||||
ASSERT_EQ(0, attribute.compare(sp1+1, 1, "1", 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2494,7 +2496,7 @@ TEST_F(WebRtcIceGatherTest, TestFakeStunServerNatedNoHost) {
|
|||
UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
|
||||
Gather(0);
|
||||
WaitForGather();
|
||||
DumpCandidates(0);
|
||||
DumpAttributes(0);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
|
||||
NrIceCandidate default_candidate;
|
||||
|
@ -2511,7 +2513,7 @@ TEST_F(WebRtcIceGatherTest, TestFakeStunServerNoNatNoHost) {
|
|||
UseTestStunServer();
|
||||
Gather(0);
|
||||
WaitForGather();
|
||||
DumpCandidates(0);
|
||||
DumpAttributes(0);
|
||||
ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
|
||||
ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
|
||||
}
|
||||
|
@ -2601,17 +2603,15 @@ TEST_F(WebRtcIceConnectTest, TestConnectRestartIce) {
|
|||
InitPeer(p3_.get());
|
||||
p3_->AddStream(1);
|
||||
|
||||
p2_->AddStream(1);
|
||||
ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
|
||||
std::cout << "-------------------------------------------------" << std::endl;
|
||||
ConnectCallerAndCallee(p3_.get(), p2_.get());
|
||||
SendReceive(p1_.get(), p2_.get()); // p1 and p2 still connected
|
||||
SendReceive(p3_.get(), p2_.get()); // p3 and p2 are now connected
|
||||
|
||||
p2_->FinalizeIceRestart();
|
||||
SendReceive(p3_.get(), p2_.get()); // p3 and p2 are still connected
|
||||
|
||||
ConnectCallerAndCallee(p3_.get(), p2_.get(), TRICKLE_SIMULATE);
|
||||
SendReceive(p1_.get(), p2_.get()); // p1 and p2 are still connected
|
||||
SendReceive(p3_.get(), p2_.get(), true, true); // p3 and p2 not yet connected
|
||||
p2_->SimulateTrickle(0);
|
||||
p3_->SimulateTrickle(0);
|
||||
SendReceive(p1_.get(), p2_.get(), false, true); // p1 and p2 not connected
|
||||
SendReceive(p3_.get(), p2_.get()); // p3 and p2 are now connected
|
||||
|
||||
p3_ = nullptr;
|
||||
}
|
||||
|
@ -2633,22 +2633,15 @@ TEST_F(WebRtcIceConnectTest, TestConnectRestartIceThenAbort) {
|
|||
InitPeer(p3_.get());
|
||||
p3_->AddStream(1);
|
||||
|
||||
p2_->AddStream(1);
|
||||
ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
|
||||
std::cout << "-------------------------------------------------" << std::endl;
|
||||
ConnectCallerAndCallee(p3_.get(), p2_.get());
|
||||
SendReceive(p1_.get(), p2_.get()); // p1 and p2 still connected
|
||||
SendReceive(p3_.get(), p2_.get()); // p3 and p2 are now connected
|
||||
|
||||
p2_->RollbackIceRestart();
|
||||
SendReceive(p1_.get(), p2_.get()); // p1 and p2 are still connected
|
||||
|
||||
SendReceive(p3_.get(), p2_.get(), false, true); // p3 and p2 not connected
|
||||
|
||||
p2_->Connect(p1_.get(), TRICKLE_NONE);
|
||||
SendReceive(p1_.get(), p2_.get());
|
||||
p3_ = nullptr;
|
||||
}
|
||||
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectSetControllingAfterIceRestart) {
|
||||
TEST_F(WebRtcIceConnectTest, TestConnectIceRestartRoleConflict) {
|
||||
AddStream(1);
|
||||
ASSERT_TRUE(Gather());
|
||||
// Just for fun lets do this with switched rolls
|
||||
|
@ -2662,35 +2655,31 @@ TEST_F(WebRtcIceConnectTest, TestConnectSetControllingAfterIceRestart) {
|
|||
|
||||
p2_->RestartIce();
|
||||
ASSERT_FALSE(p2_->gathering_complete());
|
||||
// ICE restart should allow us to set control role again
|
||||
p2_->SetControlling(NrIceCtx::ICE_CONTROLLED);
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
|
||||
// But still only allowed to set control role once
|
||||
p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p2_->GetControlling()) <<
|
||||
"ICE restart should not allow role to change, unless ice-lite happens";
|
||||
|
||||
mozilla::UniquePtr<IceTestPeer> p3_;
|
||||
p3_ = MakeUnique<IceTestPeer>("P3", test_utils_, true, false, false, false);
|
||||
InitPeer(p3_.get());
|
||||
p3_->AddStream(1);
|
||||
// Set control role for p3 accordingly (w/o role conflict)
|
||||
// Set control role for p3 accordingly (with role conflict)
|
||||
p3_->SetControlling(NrIceCtx::ICE_CONTROLLING);
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p3_->GetControlling());
|
||||
|
||||
p2_->AddStream(1);
|
||||
ASSERT_TRUE(GatherCallerAndCallee(p2_.get(), p3_.get()));
|
||||
std::cout << "-------------------------------------------------" << std::endl;
|
||||
ConnectCallerAndCallee(p3_.get(), p2_.get());
|
||||
// Again connecting should not result in role switch
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p3_->GetControlling());
|
||||
auto p2role = p2_->GetControlling();
|
||||
ASSERT_NE(p2role, p3_->GetControlling()) << "Conflict should be resolved";
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p1_->GetControlling())
|
||||
<< "P1 should be unaffected by role conflict";
|
||||
|
||||
p2_->FinalizeIceRestart();
|
||||
// And again we are not allowed to switch roles at this point any more
|
||||
p2_->SetControlling(NrIceCtx::ICE_CONTROLLING);
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p2_->GetControlling());
|
||||
p3_->SetControlling(NrIceCtx::ICE_CONTROLLED);
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLING, p3_->GetControlling());
|
||||
p1_->SetControlling(NrIceCtx::ICE_CONTROLLING);
|
||||
ASSERT_EQ(NrIceCtx::ICE_CONTROLLED, p1_->GetControlling());
|
||||
p3_->SetControlling(p2role);
|
||||
ASSERT_NE(p2role, p3_->GetControlling());
|
||||
|
||||
p3_ = nullptr;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ extern "C" {
|
|||
|
||||
#include "stunserver.h"
|
||||
|
||||
#include "nricectxhandler.h"
|
||||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
|
||||
#define GTEST_HAS_RTTI 0
|
||||
|
@ -47,7 +47,7 @@ class MultiTcpSocketTest : public MtransportTest {
|
|||
void SetUp() {
|
||||
MtransportTest::SetUp();
|
||||
|
||||
ice_ctx_ = NrIceCtxHandler::Create("stun", true);
|
||||
ice_ctx_ = NrIceCtx::Create("stun", true);
|
||||
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
|
||||
|
@ -108,7 +108,7 @@ class MultiTcpSocketTest : public MtransportTest {
|
|||
stun_server_addr, stun_server_port, kNrIceTransportTcp));
|
||||
stun_servers.push_back(*server);
|
||||
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetStunServers(stun_servers)));
|
||||
ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(stun_servers)));
|
||||
}
|
||||
|
||||
r = 1;
|
||||
|
@ -117,7 +117,7 @@ class MultiTcpSocketTest : public MtransportTest {
|
|||
(char *)"127.0.0.1", EnsureEphemeral(port_s++), IPPROTO_TCP, &local);
|
||||
ASSERT_EQ(0, r);
|
||||
|
||||
r = nr_socket_multi_tcp_create(ice_ctx_->ctx()->ctx(),
|
||||
r = nr_socket_multi_tcp_create(ice_ctx_->ctx(),
|
||||
&local, tcp_type, 1, 2048, sock);
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ class MultiTcpSocketTest : public MtransportTest {
|
|||
}
|
||||
std::vector<nr_socket *> socks;
|
||||
Atomic<bool> readable;
|
||||
RefPtr<NrIceCtxHandler> ice_ctx_;
|
||||
RefPtr<NrIceCtx> ice_ctx_;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,10 @@ public:
|
|||
|
||||
nr_ice_add_media_stream(ice_ctx_,
|
||||
const_cast<char *>(name_.c_str()),
|
||||
"ufrag",
|
||||
"pass",
|
||||
2, &ice_media_stream_);
|
||||
EXPECT_EQ(2UL, GetStreamAttributes().size());
|
||||
|
||||
nr_ice_media_stream_initialize(ice_ctx_, ice_media_stream_);
|
||||
}
|
||||
|
@ -144,30 +147,46 @@ public:
|
|||
ASSERT_TRUE(r == 0 || r == R_WOULDBLOCK);
|
||||
}
|
||||
|
||||
std::vector<std::string> GetLocalCandidates() const {
|
||||
char attr[256];
|
||||
std::vector<std::string> candidates;
|
||||
nr_ice_component* comp = STAILQ_FIRST(&ice_media_stream_->components);
|
||||
while(comp){
|
||||
if (comp->state != NR_ICE_COMPONENT_DISABLED) {
|
||||
nr_ice_candidate *cand = TAILQ_FIRST(&comp->candidates);
|
||||
while(cand){
|
||||
int r = nr_ice_format_candidate_attribute(cand, attr, 255);
|
||||
if (r == 0) {
|
||||
candidates.push_back(attr);
|
||||
}
|
||||
std::vector<std::string> GetStreamAttributes() {
|
||||
std::vector<std::string> attributes;
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&attributes,
|
||||
this,
|
||||
&IcePeer::GetStreamAttributes_s),
|
||||
NS_DISPATCH_SYNC);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
cand = TAILQ_NEXT(cand, entry_comp);
|
||||
}
|
||||
}
|
||||
std::vector<std::string> GetStreamAttributes_s() {
|
||||
|
||||
comp = STAILQ_NEXT(comp, entry);
|
||||
char **attrs = nullptr;
|
||||
int attrct;
|
||||
std::vector<std::string> ret;
|
||||
|
||||
int r =
|
||||
nr_ice_media_stream_get_attributes(ice_media_stream_, &attrs, &attrct);
|
||||
EXPECT_EQ(0, r);
|
||||
|
||||
for (int i=0; i<attrct; i++) {
|
||||
ret.push_back(std::string(attrs[i]));
|
||||
RFREE(attrs[i]);
|
||||
}
|
||||
RFREE(attrs);
|
||||
|
||||
return candidates;
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetGlobalAttributes() {
|
||||
std::vector<std::string> attributes;
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&attributes,
|
||||
this,
|
||||
&IcePeer::GetGlobalAttributes_s),
|
||||
NS_DISPATCH_SYNC);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
std::vector<std::string> GetGlobalAttributes_s() {
|
||||
|
||||
char **attrs = nullptr;
|
||||
int attrct;
|
||||
|
@ -203,6 +222,14 @@ public:
|
|||
}
|
||||
|
||||
void SetRemoteAttributes(std::vector<std::string> attributes) {
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnable(this,
|
||||
&IcePeer::SetRemoteAttributes_s,
|
||||
attributes),
|
||||
NS_DISPATCH_SYNC);
|
||||
}
|
||||
|
||||
void SetRemoteAttributes_s(std::vector<std::string> attributes) {
|
||||
int r;
|
||||
|
||||
std::vector<char*> attrs;
|
||||
|
@ -329,11 +356,11 @@ TEST_F(TestNrSocketIceUnitTest, TestIcePeer) {
|
|||
ASSERT_NE(peer.ice_ctx_, nullptr);
|
||||
ASSERT_NE(peer.peer_ctx_, nullptr);
|
||||
ASSERT_NE(peer.ice_media_stream_, nullptr);
|
||||
ASSERT_EQ(2UL, peer.GetStreamAttributes().size())
|
||||
<< "Should have ice-ufrag and ice-pwd";
|
||||
peer.Gather();
|
||||
std::vector<std::string> attrs = peer.GetGlobalAttributes();
|
||||
ASSERT_NE(attrs.size(), 0UL);
|
||||
std::vector<std::string> candidates = peer.GetLocalCandidates();
|
||||
ASSERT_NE(candidates.size(), 0UL);
|
||||
ASSERT_LT(2UL, peer.GetStreamAttributes().size())
|
||||
<< "Should have ice-ufrag, ice-pwd, and at least one candidate.";
|
||||
}
|
||||
|
||||
TEST_F(TestNrSocketIceUnitTest, TestIcePeersNoNAT) {
|
||||
|
@ -348,13 +375,13 @@ TEST_F(TestNrSocketIceUnitTest, TestIcePeersNoNAT) {
|
|||
peer2.Gather();
|
||||
std::vector<std::string> attrs = peer.GetGlobalAttributes();
|
||||
peer2.ParseGlobalAttributes(attrs);
|
||||
std::vector<std::string> candidates = peer.GetLocalCandidates();
|
||||
peer2.SetRemoteAttributes(candidates);
|
||||
std::vector<std::string> attributes = peer.GetStreamAttributes();
|
||||
peer2.SetRemoteAttributes(attributes);
|
||||
|
||||
attrs = peer2.GetGlobalAttributes();
|
||||
peer.ParseGlobalAttributes(attrs);
|
||||
candidates = peer2.GetLocalCandidates();
|
||||
peer.SetRemoteAttributes(candidates);
|
||||
attributes = peer2.GetStreamAttributes();
|
||||
peer.SetRemoteAttributes(attributes);
|
||||
peer2.StartChecks();
|
||||
peer.StartChecks();
|
||||
|
||||
|
@ -406,13 +433,13 @@ TEST_F(TestNrSocketIceUnitTest, TestIcePeersPacketLoss) {
|
|||
peer2.Gather();
|
||||
std::vector<std::string> attrs = peer.GetGlobalAttributes();
|
||||
peer2.ParseGlobalAttributes(attrs);
|
||||
std::vector<std::string> candidates = peer.GetLocalCandidates();
|
||||
peer2.SetRemoteAttributes(candidates);
|
||||
std::vector<std::string> attributes = peer.GetStreamAttributes();
|
||||
peer2.SetRemoteAttributes(attributes);
|
||||
|
||||
attrs = peer2.GetGlobalAttributes();
|
||||
peer.ParseGlobalAttributes(attrs);
|
||||
candidates = peer2.GetLocalCandidates();
|
||||
peer.SetRemoteAttributes(candidates);
|
||||
attributes = peer2.GetStreamAttributes();
|
||||
peer.SetRemoteAttributes(attributes);
|
||||
peer2.StartChecks();
|
||||
peer.StartChecks();
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
#include "mediapacket.h"
|
||||
#include "dtlsidentity.h"
|
||||
#include "nricectxhandler.h"
|
||||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "transportflow.h"
|
||||
#include "transportlayer.h"
|
||||
|
@ -443,8 +443,8 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
lossy_(new TransportLayerLossy()),
|
||||
dtls_(new TransportLayerDtls()),
|
||||
identity_(DtlsIdentity::Generate()),
|
||||
ice_ctx_(NrIceCtxHandler::Create(name)),
|
||||
streams_(), candidates_(),
|
||||
ice_ctx_(NrIceCtx::Create(name)),
|
||||
streams_(),
|
||||
peer_(nullptr),
|
||||
gathering_complete_(false),
|
||||
enabled_cipersuites_(),
|
||||
|
@ -454,7 +454,7 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
UniquePtr<NrIceStunServer> server(NrIceStunServer::Create(
|
||||
std::string((char *)"stun.services.mozilla.com"), 3478));
|
||||
stun_servers.push_back(*server);
|
||||
EXPECT_TRUE(NS_SUCCEEDED(ice_ctx_->ctx()->SetStunServers(stun_servers)));
|
||||
EXPECT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(stun_servers)));
|
||||
|
||||
dtls_->SetIdentity(identity_);
|
||||
dtls_->SetRole(offerer_ ?
|
||||
|
@ -610,7 +610,7 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
nsresult res;
|
||||
|
||||
// Attach our slots
|
||||
ice_ctx_->ctx()->SignalGatheringStateChange.
|
||||
ice_ctx_->SignalGatheringStateChange.
|
||||
connect(this, &TransportTestPeer::GatheringStateChange);
|
||||
|
||||
char name[100];
|
||||
|
@ -618,11 +618,10 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
(int)streams_.size());
|
||||
|
||||
// Create the media stream
|
||||
RefPtr<NrIceMediaStream> stream =
|
||||
ice_ctx_->CreateStream(static_cast<char *>(name), 1);
|
||||
RefPtr<NrIceMediaStream> stream = ice_ctx_->CreateStream(name, name, 1);
|
||||
|
||||
ASSERT_TRUE(stream != nullptr);
|
||||
ice_ctx_->ctx()->SetStream(name, stream);
|
||||
stream->SetIceCredentials("ufrag", "pass");
|
||||
streams_.push_back(stream);
|
||||
|
||||
// Listen for candidates
|
||||
|
@ -646,7 +645,7 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
// Start gathering
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res,
|
||||
ice_ctx_->ctx(),
|
||||
ice_ctx_,
|
||||
&NrIceCtx::StartGathering,
|
||||
false,
|
||||
false),
|
||||
|
@ -665,7 +664,6 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
// New candidate
|
||||
void GotCandidate(NrIceMediaStream *stream, const std::string &candidate) {
|
||||
std::cerr << "Got candidate " << candidate << std::endl;
|
||||
candidates_[stream->name()].push_back(candidate);
|
||||
}
|
||||
|
||||
void GatheringStateChange(NrIceCtx* ctx,
|
||||
|
@ -689,23 +687,23 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
|
||||
// First send attributes
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res, peer_->ice_ctx_->ctx(),
|
||||
WrapRunnableRet(&res, peer_->ice_ctx_,
|
||||
&NrIceCtx::ParseGlobalAttributes,
|
||||
ice_ctx_->ctx()->GetGlobalAttributes()),
|
||||
ice_ctx_->GetGlobalAttributes()),
|
||||
NS_DISPATCH_SYNC);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
|
||||
for (size_t i=0; i<streams_.size(); ++i) {
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res, peer_->streams_[i], &NrIceMediaStream::ParseAttributes,
|
||||
candidates_[streams_[i]->name()]), NS_DISPATCH_SYNC);
|
||||
WrapRunnableRet(&res, peer_->streams_[i], &NrIceMediaStream::ConnectToPeer,
|
||||
"ufrag", "pass", streams_[i]->GetAttributes()), NS_DISPATCH_SYNC);
|
||||
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
}
|
||||
|
||||
// Start checks on the other peer.
|
||||
test_utils_->sts_target()->Dispatch(
|
||||
WrapRunnableRet(&res, peer_->ice_ctx_->ctx(), &NrIceCtx::StartChecks,
|
||||
WrapRunnableRet(&res, peer_->ice_ctx_, &NrIceCtx::StartChecks,
|
||||
offerer_),
|
||||
NS_DISPATCH_SYNC);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
|
@ -831,9 +829,8 @@ class TransportTestPeer : public sigslot::has_slots<> {
|
|||
TransportLayerDtls *dtls_;
|
||||
TransportLayerIce *ice_;
|
||||
RefPtr<DtlsIdentity> identity_;
|
||||
RefPtr<NrIceCtxHandler> ice_ctx_;
|
||||
RefPtr<NrIceCtx> ice_ctx_;
|
||||
std::vector<RefPtr<NrIceMediaStream> > streams_;
|
||||
std::map<std::string, std::vector<std::string> > candidates_;
|
||||
TransportTestPeer *peer_;
|
||||
bool gathering_complete_;
|
||||
unsigned char fingerprint_[TransportLayerDtls::kMaxDigestLength];
|
||||
|
|
|
@ -74,8 +74,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include "nricemediastream.h"
|
||||
#include "nricectxhandler.h"
|
||||
|
||||
#include "nricectx.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
|
|
@ -306,11 +306,7 @@ int nr_ice_candidate_destroy(nr_ice_candidate **candp)
|
|||
|
||||
cand=*candp;
|
||||
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZING) {
|
||||
/* Make sure the ICE ctx isn't still waiting around for this candidate
|
||||
* to init. */
|
||||
nr_ice_candidate_mark_done(cand, NR_ICE_CAND_STATE_FAILED);
|
||||
}
|
||||
nr_ice_candidate_stop_gathering(cand);
|
||||
|
||||
switch(cand->type){
|
||||
case HOST:
|
||||
|
@ -350,12 +346,6 @@ int nr_ice_candidate_destroy(nr_ice_candidate **candp)
|
|||
break;
|
||||
}
|
||||
|
||||
NR_async_timer_cancel(cand->delay_timer);
|
||||
NR_async_timer_cancel(cand->ready_cb_timer);
|
||||
if(cand->resolver_handle){
|
||||
nr_resolver_cancel(cand->ctx->resolver,cand->resolver_handle);
|
||||
}
|
||||
|
||||
RFREE(cand->foundation);
|
||||
RFREE(cand->label);
|
||||
RFREE(cand);
|
||||
|
@ -363,6 +353,25 @@ int nr_ice_candidate_destroy(nr_ice_candidate **candp)
|
|||
return(0);
|
||||
}
|
||||
|
||||
void nr_ice_candidate_stop_gathering(nr_ice_candidate *cand)
|
||||
{
|
||||
if (cand->state == NR_ICE_CAND_STATE_INITIALIZING) {
|
||||
/* Make sure the ICE ctx isn't still waiting around for this candidate
|
||||
* to init. */
|
||||
nr_ice_candidate_mark_done(cand, NR_ICE_CAND_STATE_FAILED);
|
||||
}
|
||||
|
||||
NR_async_timer_cancel(cand->delay_timer);
|
||||
cand->delay_timer=0;
|
||||
NR_async_timer_cancel(cand->ready_cb_timer);
|
||||
cand->ready_cb_timer=0;
|
||||
|
||||
if(cand->resolver_handle){
|
||||
nr_resolver_cancel(cand->ctx->resolver,cand->resolver_handle);
|
||||
cand->resolver_handle=0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This algorithm is not super-fast, but I don't think we need a hash
|
||||
table just yet and it produces a small foundation string */
|
||||
static int nr_ice_get_foundation(nr_ice_ctx *ctx,nr_ice_candidate *cand)
|
||||
|
|
|
@ -110,6 +110,7 @@ int nr_ice_candidate_initialize(nr_ice_candidate *cand, NR_async_cb ready_cb, vo
|
|||
void nr_ice_candidate_compute_codeword(nr_ice_candidate *cand);
|
||||
int nr_ice_candidate_process_stun(nr_ice_candidate *cand, UCHAR *msg, int len, nr_transport_addr *faddr);
|
||||
int nr_ice_candidate_destroy(nr_ice_candidate **candp);
|
||||
void nr_ice_candidate_stop_gathering(nr_ice_candidate *cand);
|
||||
int nr_ice_format_candidate_attribute(nr_ice_candidate *cand, char *attr, int maxlen);
|
||||
int nr_ice_peer_candidate_from_attribute(nr_ice_ctx *ctx,char *attr,nr_ice_media_stream *stream,nr_ice_candidate **candp);
|
||||
int nr_ice_peer_peer_rflx_candidate_create(nr_ice_ctx *ctx,char *label, nr_ice_component *comp,nr_transport_addr *addr, nr_ice_candidate **candp);
|
||||
|
|
|
@ -497,7 +497,7 @@ int nr_ice_candidate_pair_do_triggered_check(nr_ice_peer_ctx *pctx, nr_ice_cand_
|
|||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_candidate_pair_cancel(nr_ice_peer_ctx *pctx,nr_ice_cand_pair *pair, int move_to_wait_state)
|
||||
void nr_ice_candidate_pair_cancel(nr_ice_peer_ctx *pctx,nr_ice_cand_pair *pair, int move_to_wait_state)
|
||||
{
|
||||
if(pair->state != NR_ICE_PAIR_STATE_FAILED){
|
||||
/* If it's already running we need to terminate the stun */
|
||||
|
@ -510,8 +510,6 @@ int nr_ice_candidate_pair_cancel(nr_ice_peer_ctx *pctx,nr_ice_cand_pair *pair, i
|
|||
}
|
||||
nr_ice_candidate_pair_set_state(pctx,pair,NR_ICE_PAIR_STATE_CANCELLED);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_ice_candidate_pair_select(nr_ice_cand_pair *pair)
|
||||
|
@ -545,10 +543,8 @@ int nr_ice_candidate_pair_select(nr_ice_cand_pair *pair)
|
|||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state)
|
||||
void nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state)
|
||||
{
|
||||
int r,_status;
|
||||
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/CAND-PAIR(%s): setting pair to state %s: %s",
|
||||
pctx->label,pair->codeword,nr_ice_cand_pair_states[state],pair->as_string);
|
||||
|
||||
|
@ -580,13 +576,8 @@ int nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pai
|
|||
|
||||
if(pair->state==NR_ICE_PAIR_STATE_FAILED ||
|
||||
pair->state==NR_ICE_PAIR_STATE_CANCELLED){
|
||||
if(r=nr_ice_component_failed_pair(pair->remote->component, pair))
|
||||
ABORT(r);
|
||||
nr_ice_component_failed_pair(pair->remote->component, pair);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_candidate_pair_dump_state(nr_ice_cand_pair *pair, FILE *out)
|
||||
|
|
|
@ -83,9 +83,9 @@ struct nr_ice_cand_pair_ {
|
|||
int nr_ice_candidate_pair_create(nr_ice_peer_ctx *pctx, nr_ice_candidate *lcand,nr_ice_candidate *rcand,nr_ice_cand_pair **pairp);
|
||||
int nr_ice_candidate_pair_unfreeze(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair);
|
||||
int nr_ice_candidate_pair_start(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair);
|
||||
int nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state);
|
||||
void nr_ice_candidate_pair_set_state(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair, int state);
|
||||
int nr_ice_candidate_pair_dump_state(nr_ice_cand_pair *pair, FILE *out);
|
||||
int nr_ice_candidate_pair_cancel(nr_ice_peer_ctx *pctx,nr_ice_cand_pair *pair, int move_to_wait_state);
|
||||
void nr_ice_candidate_pair_cancel(nr_ice_peer_ctx *pctx,nr_ice_cand_pair *pair, int move_to_wait_state);
|
||||
int nr_ice_candidate_pair_select(nr_ice_cand_pair *pair);
|
||||
int nr_ice_candidate_pair_do_triggered_check(nr_ice_peer_ctx *pctx, nr_ice_cand_pair *pair);
|
||||
int nr_ice_candidate_pair_insert(nr_ice_cand_pair_head *head,nr_ice_cand_pair *pair);
|
||||
|
|
|
@ -657,11 +657,11 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
|||
|
||||
/* Note: we need to recompute these because
|
||||
we have not yet computed the values in the peer media stream.*/
|
||||
lufrag=component->stream->ufrag ? component->stream->ufrag : ctx->ufrag;
|
||||
lufrag=component->stream->ufrag;
|
||||
assert(lufrag);
|
||||
if (!lufrag)
|
||||
ABORT(R_INTERNAL);
|
||||
lpwd=component->stream->pwd ? component->stream->pwd :ctx->pwd;
|
||||
lpwd=component->stream->pwd;
|
||||
assert(lpwd);
|
||||
if (!lpwd)
|
||||
ABORT(R_INTERNAL);
|
||||
|
@ -699,6 +699,14 @@ int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *compon
|
|||
return(_status);
|
||||
}
|
||||
|
||||
void nr_ice_component_stop_gathering(nr_ice_component *component)
|
||||
{
|
||||
nr_ice_candidate *c1,*c2;
|
||||
TAILQ_FOREACH_SAFE(c1, &component->candidates, entry_comp, c2){
|
||||
nr_ice_candidate_stop_gathering(c1);
|
||||
}
|
||||
}
|
||||
|
||||
static int nr_ice_any_peer_paired(nr_ice_candidate* cand) {
|
||||
nr_ice_peer_ctx* pctx=STAILQ_FIRST(&cand->ctx->peers);
|
||||
while(pctx && pctx->state == NR_ICE_PEER_STATE_UNPAIRED){
|
||||
|
@ -1254,9 +1262,7 @@ static void nr_ice_component_consent_failed(nr_ice_component *comp)
|
|||
}
|
||||
/* We are turning the consent failure into a ICE component failure to
|
||||
* alert the browser via ICE connection state change about this event. */
|
||||
if (nr_ice_media_stream_component_failed(comp->stream, comp))
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s)/STREAM(%s)/COMP(%d): failed to mark component as failed",
|
||||
comp->ctx->label, comp->stream->label, comp->component_id);
|
||||
nr_ice_media_stream_component_failed(comp->stream, comp);
|
||||
}
|
||||
|
||||
static void nr_ice_component_consent_timeout_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||
|
@ -1515,8 +1521,7 @@ int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pa
|
|||
p2->state == NR_ICE_PAIR_STATE_CANCELLED);
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/STREAM(%s)/COMP(%d)/CAND-PAIR(%s): cancelling FROZEN/WAITING pair %s in trigger check queue because CAND-PAIR(%s) was nominated.",comp->stream->pctx->label,comp->stream->label,comp->component_id,p2->codeword,p2->as_string,pair->codeword);
|
||||
|
||||
if(r=nr_ice_candidate_pair_cancel(pair->pctx,p2,0))
|
||||
ABORT(r);
|
||||
nr_ice_candidate_pair_cancel(pair->pctx,p2,0);
|
||||
}
|
||||
|
||||
p2=TAILQ_NEXT(p2,triggered_check_queue_entry);
|
||||
|
@ -1529,8 +1534,7 @@ int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pa
|
|||
(p2->state == NR_ICE_PAIR_STATE_WAITING))) {
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/STREAM(%s)/COMP(%d)/CAND-PAIR(%s): cancelling FROZEN/WAITING pair %s because CAND-PAIR(%s) was nominated.",comp->stream->pctx->label,comp->stream->label,comp->component_id,p2->codeword,p2->as_string,pair->codeword);
|
||||
|
||||
if(r=nr_ice_candidate_pair_cancel(pair->pctx,p2,0))
|
||||
ABORT(r);
|
||||
nr_ice_candidate_pair_cancel(pair->pctx,p2,0);
|
||||
}
|
||||
|
||||
p2=TAILQ_NEXT(p2,check_queue_entry);
|
||||
|
@ -1540,8 +1544,7 @@ int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pa
|
|||
if(r=nr_ice_component_setup_consent(comp))
|
||||
ABORT(r);
|
||||
|
||||
if(r=nr_ice_media_stream_component_nominated(comp->stream,comp))
|
||||
ABORT(r);
|
||||
nr_ice_media_stream_component_nominated(comp->stream,comp);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
|
@ -1577,12 +1580,12 @@ static int nr_ice_component_have_all_pairs_failed(nr_ice_component *comp)
|
|||
return(1);
|
||||
}
|
||||
|
||||
int nr_ice_component_failed_pair(nr_ice_component *comp, nr_ice_cand_pair *pair)
|
||||
void nr_ice_component_failed_pair(nr_ice_component *comp, nr_ice_cand_pair *pair)
|
||||
{
|
||||
return nr_ice_component_check_if_failed(comp);
|
||||
nr_ice_component_check_if_failed(comp);
|
||||
}
|
||||
|
||||
int nr_ice_component_check_if_failed(nr_ice_component *comp)
|
||||
void nr_ice_component_check_if_failed(nr_ice_component *comp)
|
||||
{
|
||||
if (comp->state == NR_ICE_COMPONENT_RUNNING) {
|
||||
/* Don't do anything to streams that aren't currently running */
|
||||
|
@ -1591,11 +1594,9 @@ int nr_ice_component_check_if_failed(nr_ice_component *comp)
|
|||
if (!comp->stream->pctx->trickle_grace_period_timer &&
|
||||
nr_ice_component_have_all_pairs_failed(comp)) {
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/STREAM(%s)/COMP(%d): All pairs are failed, and grace period has elapsed. Marking component as failed.",comp->stream->pctx->label,comp->stream->label,comp->component_id);
|
||||
return nr_ice_media_stream_component_failed(comp->stream,comp);
|
||||
nr_ice_media_stream_component_failed(comp->stream,comp);
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_ice_component_select_pair(nr_ice_peer_ctx *pctx, nr_ice_component *comp)
|
||||
|
|
|
@ -86,13 +86,14 @@ typedef STAILQ_HEAD(nr_ice_component_head_,nr_ice_component_) nr_ice_component_h
|
|||
int nr_ice_component_create(struct nr_ice_media_stream_ *stream, int component_id, nr_ice_component **componentp);
|
||||
int nr_ice_component_destroy(nr_ice_component **componentp);
|
||||
int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *component);
|
||||
void nr_ice_component_stop_gathering(nr_ice_component *component);
|
||||
int nr_ice_component_maybe_prune_candidate(nr_ice_ctx *ctx, nr_ice_component *comp, nr_ice_candidate *c1, int *was_pruned);
|
||||
int nr_ice_component_pair_candidate(nr_ice_peer_ctx *pctx, nr_ice_component *pcomp, nr_ice_candidate *lcand, int pair_all_remote);
|
||||
int nr_ice_component_pair_candidates(nr_ice_peer_ctx *pctx, nr_ice_component *lcomp, nr_ice_component *pcomp);
|
||||
int nr_ice_component_service_pre_answer_requests(nr_ice_peer_ctx *pctx, nr_ice_component *pcomp, char *username, int *serviced);
|
||||
int nr_ice_component_nominated_pair(nr_ice_component *comp, nr_ice_cand_pair *pair);
|
||||
int nr_ice_component_failed_pair(nr_ice_component *comp, nr_ice_cand_pair *pair);
|
||||
int nr_ice_component_check_if_failed(nr_ice_component *comp);
|
||||
void nr_ice_component_failed_pair(nr_ice_component *comp, nr_ice_cand_pair *pair);
|
||||
void nr_ice_component_check_if_failed(nr_ice_component *comp);
|
||||
int nr_ice_component_select_pair(nr_ice_peer_ctx *pctx, nr_ice_component *comp);
|
||||
int nr_ice_component_set_failed(nr_ice_component *comp);
|
||||
int nr_ice_component_finalize(nr_ice_component *lcomp, nr_ice_component *rcomp);
|
||||
|
|
|
@ -338,28 +338,6 @@ int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
|
|||
|
||||
#define MAXADDRS 100 /* Ridiculously high */
|
||||
int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
|
||||
{
|
||||
int r,_status;
|
||||
char *ufrag = 0;
|
||||
char *pwd = 0;
|
||||
|
||||
if (r=nr_ice_get_new_ice_ufrag(&ufrag))
|
||||
ABORT(r);
|
||||
if (r=nr_ice_get_new_ice_pwd(&pwd))
|
||||
ABORT(r);
|
||||
|
||||
if (r=nr_ice_ctx_create_with_credentials(label, flags, ufrag, pwd, ctxp))
|
||||
ABORT(r);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
RFREE(ufrag);
|
||||
RFREE(pwd);
|
||||
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_create_with_credentials(char *label, UINT4 flags, char *ufrag, char *pwd, nr_ice_ctx **ctxp)
|
||||
{
|
||||
nr_ice_ctx *ctx=0;
|
||||
int r,_status;
|
||||
|
@ -375,11 +353,6 @@ int nr_ice_ctx_create_with_credentials(char *label, UINT4 flags, char *ufrag, ch
|
|||
if(!(ctx->label=r_strdup(label)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if(!(ctx->ufrag=r_strdup(ufrag)))
|
||||
ABORT(r);
|
||||
if(!(ctx->pwd=r_strdup(pwd)))
|
||||
ABORT(r);
|
||||
|
||||
/* Get the STUN servers */
|
||||
if(r=NR_reg_get_child_count(NR_ICE_REG_STUN_SRV_PRFX,
|
||||
(unsigned int *)&ctx->stun_server_ct)||ctx->stun_server_ct==0) {
|
||||
|
@ -494,8 +467,6 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
|||
RFREE(f1);
|
||||
f1=f2;
|
||||
}
|
||||
RFREE(ctx->pwd);
|
||||
RFREE(ctx->ufrag);
|
||||
|
||||
STAILQ_FOREACH_SAFE(id1, &ctx->ids, entry, id2){
|
||||
STAILQ_REMOVE(&ctx->ids,id1,nr_ice_stun_id_,entry);
|
||||
|
@ -832,11 +803,11 @@ int nr_ice_gather(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
|
|||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp)
|
||||
int nr_ice_add_media_stream(nr_ice_ctx *ctx,const char *label,const char *ufrag,const char *pwd,int components, nr_ice_media_stream **streamp)
|
||||
{
|
||||
int r,_status;
|
||||
|
||||
if(r=nr_ice_media_stream_create(ctx,label,components,streamp))
|
||||
if(r=nr_ice_media_stream_create(ctx,label,ufrag,pwd,components,streamp))
|
||||
ABORT(r);
|
||||
|
||||
STAILQ_INSERT_TAIL(&ctx->streams,*streamp,entry);
|
||||
|
@ -875,36 +846,9 @@ int nr_ice_remove_media_stream(nr_ice_ctx *ctx,nr_ice_media_stream **streamp)
|
|||
|
||||
int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp)
|
||||
{
|
||||
char **attrs=0;
|
||||
int _status;
|
||||
char *tmp=0;
|
||||
|
||||
if(!(attrs=RCALLOC(sizeof(char *)*2)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if(!(tmp=RMALLOC(100)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
snprintf(tmp,100,"ice-ufrag:%s",ctx->ufrag);
|
||||
attrs[0]=tmp;
|
||||
|
||||
if(!(tmp=RMALLOC(100)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
snprintf(tmp,100,"ice-pwd:%s",ctx->pwd);
|
||||
attrs[1]=tmp;
|
||||
|
||||
*attrctp=2;
|
||||
*attrsp=attrs;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
if (_status){
|
||||
if (attrs){
|
||||
RFREE(attrs[0]);
|
||||
RFREE(attrs[1]);
|
||||
}
|
||||
RFREE(attrs);
|
||||
}
|
||||
return(_status);
|
||||
*attrctp=0;
|
||||
*attrsp=0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int nr_ice_random_string(char *str, int len)
|
||||
|
|
|
@ -123,9 +123,6 @@ struct nr_ice_ctx_ {
|
|||
UINT4 flags;
|
||||
char *label;
|
||||
|
||||
char *ufrag;
|
||||
char *pwd;
|
||||
|
||||
UINT4 Ta;
|
||||
|
||||
nr_ice_stun_server *stun_servers; /* The list of stun servers */
|
||||
|
@ -181,7 +178,7 @@ int nr_ice_set_local_addresses(nr_ice_ctx *ctx, nr_local_addr* stun_addrs, int s
|
|||
int nr_ice_gather(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg);
|
||||
int nr_ice_add_candidate(nr_ice_ctx *ctx, nr_ice_candidate *cand);
|
||||
void nr_ice_gather_finished_cb(NR_SOCKET s, int h, void *cb_arg);
|
||||
int nr_ice_add_media_stream(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp);
|
||||
int nr_ice_add_media_stream(nr_ice_ctx *ctx,const char *label,const char *ufrag,const char *pwd,int components, nr_ice_media_stream **streamp);
|
||||
int nr_ice_remove_media_stream(nr_ice_ctx *ctx,nr_ice_media_stream **streamp);
|
||||
int nr_ice_get_global_attributes(nr_ice_ctx *ctx,char ***attrsp, int *attrctp);
|
||||
int nr_ice_ctx_deliver_packet(nr_ice_ctx *ctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len);
|
||||
|
|
|
@ -44,7 +44,7 @@ static char *nr_ice_media_stream_states[]={"INVALID",
|
|||
|
||||
int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state);
|
||||
|
||||
int nr_ice_media_stream_create(nr_ice_ctx *ctx,char *label,int components, nr_ice_media_stream **streamp)
|
||||
int nr_ice_media_stream_create(nr_ice_ctx *ctx,const char *label,const char *ufrag,const char *pwd,int components, nr_ice_media_stream **streamp)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_media_stream *stream=0;
|
||||
|
@ -57,6 +57,12 @@ int nr_ice_media_stream_create(nr_ice_ctx *ctx,char *label,int components, nr_ic
|
|||
if(!(stream->label=r_strdup(label)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if(!(stream->ufrag=r_strdup(ufrag)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
if(!(stream->pwd=r_strdup(pwd)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
stream->ctx=ctx;
|
||||
|
||||
STAILQ_INIT(&stream->components);
|
||||
|
@ -73,6 +79,9 @@ int nr_ice_media_stream_create(nr_ice_ctx *ctx,char *label,int components, nr_ic
|
|||
stream->disconnected = 0;
|
||||
stream->component_ct=components;
|
||||
stream->ice_state = NR_ICE_MEDIA_STREAM_UNPAIRED;
|
||||
stream->obsolete = 0;
|
||||
stream->r2l_user = 0;
|
||||
stream->l2r_user = 0;
|
||||
*streamp=stream;
|
||||
|
||||
_status=0;
|
||||
|
@ -143,12 +152,13 @@ int nr_ice_media_stream_initialize(nr_ice_ctx *ctx, nr_ice_media_stream *stream)
|
|||
|
||||
int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attrsp, int *attrctp)
|
||||
{
|
||||
int attrct=0;
|
||||
int attrct=2;
|
||||
nr_ice_component *comp;
|
||||
char **attrs=0;
|
||||
int index=0;
|
||||
nr_ice_candidate *cand;
|
||||
int r,_status;
|
||||
char *tmp=0;
|
||||
|
||||
*attrctp=0;
|
||||
|
||||
|
@ -168,11 +178,6 @@ int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attr
|
|||
comp=STAILQ_NEXT(comp,entry);
|
||||
}
|
||||
|
||||
if(attrct < 1){
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE-STREAM(%s): Failed to find any components for stream",stream->label);
|
||||
ABORT(R_FAILED);
|
||||
}
|
||||
|
||||
/* Make the array we'll need */
|
||||
if(!(attrs=RCALLOC(sizeof(char *)*attrct)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
@ -208,6 +213,17 @@ int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attr
|
|||
comp=STAILQ_NEXT(comp,entry);
|
||||
}
|
||||
|
||||
/* Now, ufrag and pwd */
|
||||
if(!(tmp=RMALLOC(100)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
snprintf(tmp,100,"ice-ufrag:%s",stream->ufrag);
|
||||
attrs[index++]=tmp;
|
||||
|
||||
if(!(tmp=RMALLOC(100)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
snprintf(tmp,100,"ice-pwd:%s",stream->pwd);
|
||||
attrs[index++]=tmp;
|
||||
|
||||
*attrsp=attrs;
|
||||
*attrctp=attrct;
|
||||
|
||||
|
@ -392,6 +408,11 @@ int nr_ice_media_stream_start_checks(nr_ice_peer_ctx *pctx, nr_ice_media_stream
|
|||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
if (stream->local_stream->obsolete) {
|
||||
assert(0);
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
/* Even if the stream is completed already remote can still create a new
|
||||
* triggered check request which needs to fire, but not change our stream
|
||||
* state. */
|
||||
|
@ -587,6 +608,42 @@ int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state)
|
|||
return(0);
|
||||
}
|
||||
|
||||
void nr_ice_media_stream_stop_checking(nr_ice_media_stream *str)
|
||||
{
|
||||
nr_ice_cand_pair *p;
|
||||
nr_ice_component *comp;
|
||||
|
||||
/* Cancel candidate pairs */
|
||||
p=TAILQ_FIRST(&str->check_list);
|
||||
while(p){
|
||||
nr_ice_candidate_pair_cancel(p->pctx,p,0);
|
||||
p=TAILQ_NEXT(p,check_queue_entry);
|
||||
}
|
||||
|
||||
if(str->timer) {
|
||||
NR_async_timer_cancel(str->timer);
|
||||
str->timer = 0;
|
||||
}
|
||||
|
||||
/* Cancel consent timers in case it is running already */
|
||||
comp=STAILQ_FIRST(&str->components);
|
||||
while(comp){
|
||||
nr_ice_component_consent_destroy(comp);
|
||||
comp=STAILQ_NEXT(comp,entry);
|
||||
}
|
||||
}
|
||||
|
||||
void nr_ice_media_stream_set_obsolete(nr_ice_media_stream *str)
|
||||
{
|
||||
nr_ice_component *c1,*c2;
|
||||
str->obsolete = 1;
|
||||
|
||||
STAILQ_FOREACH_SAFE(c1, &str->components, entry, c2){
|
||||
nr_ice_component_stop_gathering(c1);
|
||||
}
|
||||
|
||||
nr_ice_media_stream_stop_checking(str);
|
||||
}
|
||||
|
||||
void nr_ice_media_stream_refresh_consent_all(nr_ice_media_stream *stream)
|
||||
{
|
||||
|
@ -626,7 +683,9 @@ void nr_ice_media_stream_set_disconnected(nr_ice_media_stream *stream, int disco
|
|||
stream->disconnected = disconnected;
|
||||
|
||||
if (disconnected == NR_ICE_MEDIA_STREAM_DISCONNECTED) {
|
||||
nr_ice_peer_ctx_disconnected(stream->pctx);
|
||||
if (!stream->local_stream->obsolete) {
|
||||
nr_ice_peer_ctx_disconnected(stream->pctx);
|
||||
}
|
||||
} else {
|
||||
nr_ice_peer_ctx_check_if_connected(stream->pctx);
|
||||
}
|
||||
|
@ -658,9 +717,8 @@ int nr_ice_media_stream_check_if_connected(nr_ice_media_stream *stream)
|
|||
|
||||
/* S OK, this component has a nominated. If every component has a nominated,
|
||||
the stream is ready */
|
||||
int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_component *component)
|
||||
void nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_component *component)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_component *comp;
|
||||
|
||||
comp=STAILQ_FIRST(&stream->components);
|
||||
|
@ -675,7 +733,7 @@ int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_c
|
|||
|
||||
/* At least one un-nominated component */
|
||||
if(comp)
|
||||
goto done;
|
||||
return;
|
||||
|
||||
/* All done... */
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/ICE-STREAM(%s): all active components have nominated candidate pairs",stream->pctx->label,stream->label);
|
||||
|
@ -687,25 +745,16 @@ int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_c
|
|||
stream->timer=0;
|
||||
}
|
||||
|
||||
if (stream->pctx->handler) {
|
||||
if (stream->pctx->handler && !stream->local_stream->obsolete) {
|
||||
stream->pctx->handler->vtbl->stream_ready(stream->pctx->handler->obj,stream->local_stream);
|
||||
}
|
||||
|
||||
/* Now tell the peer_ctx that we're connected */
|
||||
if(r=nr_ice_peer_ctx_check_if_connected(stream->pctx))
|
||||
ABORT(r);
|
||||
|
||||
done:
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
nr_ice_peer_ctx_check_if_connected(stream->pctx);
|
||||
}
|
||||
|
||||
int nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component)
|
||||
void nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_cand_pair *p2;
|
||||
|
||||
component->state=NR_ICE_COMPONENT_FAILED;
|
||||
|
||||
/* at least one component failed in this media stream, so the entire
|
||||
|
@ -713,35 +762,14 @@ int nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_comp
|
|||
|
||||
nr_ice_media_stream_set_state(stream,NR_ICE_MEDIA_STREAM_CHECKS_FAILED);
|
||||
|
||||
/* OK, we need to cancel off everything on this component */
|
||||
p2=TAILQ_FIRST(&stream->check_list);
|
||||
while(p2){
|
||||
if(r=nr_ice_candidate_pair_cancel(p2->pctx,p2,0))
|
||||
ABORT(r);
|
||||
nr_ice_media_stream_stop_checking(stream);
|
||||
|
||||
p2=TAILQ_NEXT(p2,check_queue_entry);
|
||||
}
|
||||
|
||||
/* Cancel our timer */
|
||||
if(stream->timer){
|
||||
NR_async_timer_cancel(stream->timer);
|
||||
stream->timer=0;
|
||||
}
|
||||
|
||||
/* Cancel consent timers in case it is running already */
|
||||
nr_ice_component_consent_destroy(component);
|
||||
|
||||
if (stream->pctx->handler) {
|
||||
if (stream->pctx->handler && !stream->local_stream->obsolete) {
|
||||
stream->pctx->handler->vtbl->stream_failed(stream->pctx->handler->obj,stream->local_stream);
|
||||
}
|
||||
|
||||
/* Now tell the peer_ctx that we're connected */
|
||||
if(r=nr_ice_peer_ctx_check_if_connected(stream->pctx))
|
||||
ABORT(r);
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
/* Now tell the peer_ctx that we've failed */
|
||||
nr_ice_peer_ctx_check_if_connected(stream->pctx);
|
||||
}
|
||||
|
||||
int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int component, nr_ice_candidate **candp)
|
||||
|
|
|
@ -55,6 +55,10 @@ struct nr_ice_media_stream_ {
|
|||
Data r2l_pass; /* The password for incoming requests */
|
||||
Data l2r_pass; /* The password for outcoming requests */
|
||||
int ice_state;
|
||||
/* The stream is being replaced by another, so it will not continue any ICE
|
||||
* processing. If this stream is connected already, traffic can continue to
|
||||
* flow for a limited time while the new stream gets ready. */
|
||||
int obsolete;
|
||||
|
||||
#define NR_ICE_MEDIA_STREAM_UNPAIRED 1
|
||||
#define NR_ICE_MEDIA_STREAM_CHECKS_FROZEN 2
|
||||
|
@ -78,7 +82,7 @@ struct nr_ice_media_stream_ {
|
|||
|
||||
typedef STAILQ_HEAD(nr_ice_media_stream_head_,nr_ice_media_stream_) nr_ice_media_stream_head;
|
||||
|
||||
int nr_ice_media_stream_create(struct nr_ice_ctx_ *ctx,char *label, int components, nr_ice_media_stream **streamp);
|
||||
int nr_ice_media_stream_create(struct nr_ice_ctx_ *ctx,const char *label,const char *ufrag,const char *pwd,int components, nr_ice_media_stream **streamp);
|
||||
int nr_ice_media_stream_destroy(nr_ice_media_stream **streamp);
|
||||
int nr_ice_media_stream_finalize(nr_ice_media_stream *lstr,nr_ice_media_stream *rstr);
|
||||
int nr_ice_media_stream_initialize(struct nr_ice_ctx_ *ctx, nr_ice_media_stream *stream);
|
||||
|
@ -90,13 +94,15 @@ int nr_ice_media_stream_service_pre_answer_requests(nr_ice_peer_ctx *pctx,nr_ice
|
|||
int nr_ice_media_stream_unfreeze_pairs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream);
|
||||
int nr_ice_media_stream_unfreeze_pairs_foundation(nr_ice_media_stream *stream, char *foundation);
|
||||
int nr_ice_media_stream_dump_state(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream,FILE *out);
|
||||
int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_component *component);
|
||||
int nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component);
|
||||
void nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_component *component);
|
||||
void nr_ice_media_stream_component_failed(nr_ice_media_stream *stream,nr_ice_component *component);
|
||||
void nr_ice_media_stream_refresh_consent_all(nr_ice_media_stream *stream);
|
||||
void nr_ice_media_stream_disconnect_all_components(nr_ice_media_stream *stream);
|
||||
void nr_ice_media_stream_set_disconnected(nr_ice_media_stream *stream, int disconnected);
|
||||
int nr_ice_media_stream_check_if_connected(nr_ice_media_stream *stream);
|
||||
int nr_ice_media_stream_set_state(nr_ice_media_stream *str, int state);
|
||||
void nr_ice_media_stream_stop_checking(nr_ice_media_stream *str);
|
||||
void nr_ice_media_stream_set_obsolete(nr_ice_media_stream *str);
|
||||
int nr_ice_media_stream_get_best_candidate(nr_ice_media_stream *str, int component, nr_ice_candidate **candp);
|
||||
int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, UCHAR *data, int len);
|
||||
int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_ice_candidate **local, nr_ice_candidate **remote);
|
||||
|
|
|
@ -380,6 +380,7 @@ nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media
|
|||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
RFREE(stream->ufrag);
|
||||
if ((r=grab_token(&str, &stream->ufrag)))
|
||||
ABORT(r);
|
||||
}
|
||||
|
@ -392,6 +393,7 @@ nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media
|
|||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
RFREE(stream->pwd);
|
||||
if ((r=grab_token(&str, &stream->pwd)))
|
||||
ABORT(r);
|
||||
}
|
||||
|
@ -490,6 +492,7 @@ nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int
|
|||
}
|
||||
else if (!strncasecmp(str, "ice-lite", 8)) {
|
||||
pctx->peer_lite = 1;
|
||||
pctx->controlling = 0;
|
||||
|
||||
fast_forward(&str, 8);
|
||||
}
|
||||
|
@ -506,11 +509,6 @@ nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int
|
|||
skip_whitespace(&str);
|
||||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
RFREE(pctx->peer_ufrag);
|
||||
pctx->peer_ufrag = 0;
|
||||
if ((r=grab_token(&str, &pctx->peer_ufrag)))
|
||||
ABORT(r);
|
||||
}
|
||||
else if (!strncasecmp(str, "ice-pwd:", 8)) {
|
||||
fast_forward(&str, 8);
|
||||
|
@ -520,11 +518,6 @@ nr_ice_peer_ctx_parse_global_attributes(nr_ice_peer_ctx *pctx, char **attrs, int
|
|||
skip_whitespace(&str);
|
||||
if (*str == '\0')
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
RFREE(pctx->peer_pwd);
|
||||
pctx->peer_pwd = 0;
|
||||
if ((r=grab_token(&str, &pctx->peer_pwd)))
|
||||
ABORT(r);
|
||||
}
|
||||
else if (!strncasecmp(str, "ice-options:", 12)) {
|
||||
fast_forward(&str, 12);
|
||||
|
|
|
@ -99,7 +99,7 @@ int nr_ice_peer_ctx_parse_stream_attributes(nr_ice_peer_ctx *pctx, nr_ice_media_
|
|||
/*
|
||||
Note: use component_ct from our own stream since components other
|
||||
than this offered by the other side are unusable */
|
||||
if(r=nr_ice_media_stream_create(pctx->ctx,stream->label,stream->component_ct,&pstream))
|
||||
if(r=nr_ice_media_stream_create(pctx->ctx,stream->label,"","",stream->component_ct,&pstream))
|
||||
ABORT(r);
|
||||
|
||||
/* Match up the local and remote components */
|
||||
|
@ -120,12 +120,12 @@ int nr_ice_peer_ctx_parse_stream_attributes(nr_ice_peer_ctx *pctx, nr_ice_media_
|
|||
|
||||
/* Now that we have the ufrag and password, compute all the username/password
|
||||
pairs */
|
||||
lufrag=stream->ufrag?stream->ufrag:pctx->ctx->ufrag;
|
||||
lpwd=stream->pwd?stream->pwd:pctx->ctx->pwd;
|
||||
lufrag=stream->ufrag;
|
||||
lpwd=stream->pwd;
|
||||
assert(lufrag);
|
||||
assert(lpwd);
|
||||
rufrag=pstream->ufrag?pstream->ufrag:pctx->peer_ufrag;
|
||||
rpwd=pstream->pwd?pstream->pwd:pctx->peer_pwd;
|
||||
rufrag=pstream->ufrag;
|
||||
rpwd=pstream->pwd;
|
||||
if (!rufrag || !rpwd)
|
||||
ABORT(R_BAD_DATA);
|
||||
|
||||
|
@ -470,8 +470,6 @@ static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
|||
|
||||
NR_async_timer_cancel(pctx->connected_cb_timer);
|
||||
RFREE(pctx->label);
|
||||
RFREE(pctx->peer_ufrag);
|
||||
RFREE(pctx->peer_pwd);
|
||||
|
||||
STAILQ_FOREACH_SAFE(str1, &pctx->peer_streams, entry, str2){
|
||||
STAILQ_REMOVE(&pctx->peer_streams,str1,nr_ice_media_stream_,entry);
|
||||
|
@ -534,10 +532,7 @@ int nr_ice_peer_ctx_start_checks2(nr_ice_peer_ctx *pctx, int allow_non_first)
|
|||
pctx->connected_cb_timer = 0;
|
||||
pctx->checks_started = 0;
|
||||
|
||||
if((r=nr_ice_peer_ctx_check_if_connected(pctx))) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) initial connected check failed",pctx->ctx->label,pctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
nr_ice_peer_ctx_check_if_connected(pctx);
|
||||
|
||||
if (pctx->reported_connected) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) in %s all streams were done",pctx->ctx->label,pctx->label,__FUNCTION__);
|
||||
|
@ -717,29 +712,30 @@ static void nr_ice_peer_ctx_fire_connected(NR_SOCKET s, int how, void *cb_arg)
|
|||
|
||||
/* Examine all the streams to see if we're
|
||||
maybe miraculously connected */
|
||||
int nr_ice_peer_ctx_check_if_connected(nr_ice_peer_ctx *pctx)
|
||||
void nr_ice_peer_ctx_check_if_connected(nr_ice_peer_ctx *pctx)
|
||||
{
|
||||
int _status;
|
||||
nr_ice_media_stream *str;
|
||||
int failed=0;
|
||||
int succeeded=0;
|
||||
|
||||
str=STAILQ_FIRST(&pctx->peer_streams);
|
||||
while(str){
|
||||
if(str->ice_state==NR_ICE_MEDIA_STREAM_CHECKS_CONNECTED){
|
||||
succeeded++;
|
||||
}
|
||||
else if(str->ice_state==NR_ICE_MEDIA_STREAM_CHECKS_FAILED){
|
||||
failed++;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
if (!str->local_stream->obsolete){
|
||||
if(str->ice_state==NR_ICE_MEDIA_STREAM_CHECKS_CONNECTED){
|
||||
succeeded++;
|
||||
}
|
||||
else if(str->ice_state==NR_ICE_MEDIA_STREAM_CHECKS_FAILED){
|
||||
failed++;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
str=STAILQ_NEXT(str,entry);
|
||||
}
|
||||
|
||||
if(str)
|
||||
goto done; /* Something isn't done */
|
||||
return; /* Something isn't done */
|
||||
|
||||
/* OK, we're finished, one way or another */
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s): all checks completed success=%d fail=%d",pctx->label,succeeded,failed);
|
||||
|
@ -752,10 +748,6 @@ int nr_ice_peer_ctx_check_if_connected(nr_ice_peer_ctx *pctx)
|
|||
assert(!pctx->connected_cb_timer);
|
||||
NR_ASYNC_TIMER_SET(0,nr_ice_peer_ctx_fire_connected,pctx,&pctx->connected_cb_timer);
|
||||
}
|
||||
|
||||
done:
|
||||
_status=0;
|
||||
return(_status);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -52,8 +52,6 @@ struct nr_ice_peer_ctx_ {
|
|||
UCHAR controlling_conflict_resolved;
|
||||
UINT8 tiebreaker;
|
||||
|
||||
char *peer_ufrag;
|
||||
char *peer_pwd;
|
||||
int peer_lite;
|
||||
int peer_ice_mismatch;
|
||||
|
||||
|
@ -89,7 +87,7 @@ void nr_ice_peer_ctx_disconnected(nr_ice_peer_ctx *pctx);
|
|||
void nr_ice_peer_ctx_connected(nr_ice_peer_ctx *pctx);
|
||||
int nr_ice_peer_ctx_dump_state(nr_ice_peer_ctx *pctx,FILE *out);
|
||||
int nr_ice_peer_ctx_log_state(nr_ice_peer_ctx *pctx);
|
||||
int nr_ice_peer_ctx_check_if_connected(nr_ice_peer_ctx *pctx);
|
||||
void nr_ice_peer_ctx_check_if_connected(nr_ice_peer_ctx *pctx);
|
||||
int nr_ice_peer_ctx_find_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component_id, nr_ice_component **compp);
|
||||
int nr_ice_peer_ctx_deliver_packet_maybe(nr_ice_peer_ctx *pctx, nr_ice_component *comp, nr_transport_addr *source_addr, UCHAR *data, int len);
|
||||
int nr_ice_peer_ctx_disable_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *lstream, int component_id);
|
||||
|
|
|
@ -85,8 +85,7 @@ namespace mozilla {
|
|||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
TransportLayerIce::TransportLayerIce()
|
||||
: stream_(nullptr), component_(0),
|
||||
old_stream_(nullptr)
|
||||
: stream_(nullptr), component_(0)
|
||||
{
|
||||
// setup happens later
|
||||
}
|
||||
|
@ -108,17 +107,6 @@ void TransportLayerIce::SetParameters(RefPtr<NrIceMediaStream> stream,
|
|||
return;
|
||||
}
|
||||
|
||||
// If SetParameters is called and we already have a stream_, this means
|
||||
// we're handling an ICE restart. We need to hold the old stream until
|
||||
// we know the new stream is working.
|
||||
if (stream_ && !old_stream_ && (stream_ != stream)) {
|
||||
// Here we leave the old stream's signals connected until we don't need
|
||||
// it anymore. They will be disconnected if ice restart is successful.
|
||||
old_stream_ = stream_;
|
||||
MOZ_MTLOG(ML_INFO, LAYER_INFO << "SetParameters save old stream("
|
||||
<< old_stream_->name() << ")");
|
||||
}
|
||||
|
||||
stream_ = stream;
|
||||
component_ = component;
|
||||
|
||||
|
@ -135,48 +123,11 @@ void TransportLayerIce::PostSetup() {
|
|||
}
|
||||
}
|
||||
|
||||
void TransportLayerIce::ResetOldStream() {
|
||||
if (old_stream_ == nullptr) {
|
||||
return; // no work to do
|
||||
}
|
||||
// ICE restart successful on the new stream, we can forget the old stream now
|
||||
MOZ_MTLOG(ML_INFO, LAYER_INFO << "ResetOldStream(" << old_stream_->name()
|
||||
<< ")");
|
||||
old_stream_->SignalReady.disconnect(this);
|
||||
old_stream_->SignalFailed.disconnect(this);
|
||||
old_stream_->SignalPacketReceived.disconnect(this);
|
||||
old_stream_ = nullptr;
|
||||
}
|
||||
|
||||
void TransportLayerIce::RestoreOldStream() {
|
||||
if (old_stream_ == nullptr) {
|
||||
return; // no work to do
|
||||
}
|
||||
// ICE restart rollback, we need to restore the old stream
|
||||
MOZ_MTLOG(ML_INFO, LAYER_INFO << "RestoreOldStream(" << old_stream_->name()
|
||||
<< ")");
|
||||
stream_->SignalReady.disconnect(this);
|
||||
stream_->SignalFailed.disconnect(this);
|
||||
stream_->SignalPacketReceived.disconnect(this);
|
||||
stream_ = old_stream_;
|
||||
old_stream_ = nullptr;
|
||||
|
||||
if (stream_->state() == NrIceMediaStream::ICE_OPEN) {
|
||||
IceReady(stream_);
|
||||
} else if (stream_->state() == NrIceMediaStream::ICE_CLOSED) {
|
||||
IceFailed(stream_);
|
||||
}
|
||||
// No events are fired when the stream is ICE_CONNECTING. If the
|
||||
// restored stream is ICE_CONNECTING, IceReady/IceFailed will fire
|
||||
// later.
|
||||
}
|
||||
|
||||
TransportResult TransportLayerIce::SendPacket(MediaPacket& packet) {
|
||||
CheckThread();
|
||||
// use old_stream_ until stream_ is ready
|
||||
nsresult res = (old_stream_?old_stream_:stream_)->SendPacket(component_,
|
||||
packet.data(),
|
||||
packet.len());
|
||||
nsresult res = stream_->SendPacket(component_,
|
||||
packet.data(),
|
||||
packet.len());
|
||||
|
||||
if (!NS_SUCCEEDED(res)) {
|
||||
return (res == NS_BASE_STREAM_WOULD_BLOCK) ?
|
||||
|
|
|
@ -58,9 +58,6 @@ class TransportLayerIce : public TransportLayer {
|
|||
|
||||
RefPtr<NrIceMediaStream> stream_;
|
||||
int component_;
|
||||
|
||||
// used to hold the old stream
|
||||
RefPtr<NrIceMediaStream> old_stream_;
|
||||
};
|
||||
|
||||
} // close namespace
|
||||
|
|
|
@ -81,32 +81,9 @@ public:
|
|||
}
|
||||
protected:
|
||||
struct TransportData {
|
||||
std::string mIceUfrag;
|
||||
std::string mIcePwd;
|
||||
int iceCredentialSerial;
|
||||
std::map<std::string, std::vector<uint8_t> > mFingerprints;
|
||||
};
|
||||
|
||||
void
|
||||
GenerateNewIceCredentials(const JsepSessionImpl& session,
|
||||
TransportData& tdata)
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << session.GetName() << "-" << ++tdata.iceCredentialSerial;
|
||||
|
||||
// Values here semi-borrowed from JSEP draft.
|
||||
tdata.mIceUfrag = ostr.str() + "-ufrag";
|
||||
tdata.mIcePwd = ostr.str() + "-1234567890";
|
||||
}
|
||||
|
||||
void
|
||||
ModifyOffererIceCredentials()
|
||||
{
|
||||
GenerateNewIceCredentials(*mSessionOff, *mOffererTransport);
|
||||
mSessionOff->SetIceCredentials(mOffererTransport->mIceUfrag,
|
||||
mOffererTransport->mIcePwd);
|
||||
}
|
||||
|
||||
void
|
||||
AddDtlsFingerprint(const std::string& alg, JsepSessionImpl& session,
|
||||
TransportData& tdata)
|
||||
|
@ -121,9 +98,6 @@ protected:
|
|||
void
|
||||
AddTransportData(JsepSessionImpl& session, TransportData& tdata)
|
||||
{
|
||||
tdata.iceCredentialSerial = 0;
|
||||
GenerateNewIceCredentials(session, tdata);
|
||||
session.SetIceCredentials(tdata.mIceUfrag, tdata.mIcePwd);
|
||||
AddDtlsFingerprint("sha-1", session, tdata);
|
||||
AddDtlsFingerprint("sha-256", session, tdata);
|
||||
}
|
||||
|
@ -816,13 +790,6 @@ protected:
|
|||
JsepAnswerOptions options;
|
||||
std::string answer;
|
||||
|
||||
// detect ice restart and generate new ice credentials (like
|
||||
// PeerConnectionImpl does).
|
||||
if (mSessionAns->RemoteIceIsRestarting()) {
|
||||
GenerateNewIceCredentials(*mSessionAns, *mAnswererTransport);
|
||||
mSessionAns->SetIceCredentials(mAnswererTransport->mIceUfrag,
|
||||
mAnswererTransport->mIcePwd);
|
||||
}
|
||||
nsresult rv = mSessionAns->CreateAnswer(options, &answer);
|
||||
EXPECT_EQ(NS_OK, rv);
|
||||
|
||||
|
@ -1342,9 +1309,10 @@ protected:
|
|||
const char* replaceStr) const
|
||||
{
|
||||
if (searchStr[0] == '\0') return;
|
||||
size_t pos;
|
||||
while ((pos = sdp->find(searchStr)) != std::string::npos) {
|
||||
size_t pos = 0;
|
||||
while ((pos = sdp->find(searchStr, pos)) != std::string::npos) {
|
||||
sdp->replace(pos, strlen(searchStr), replaceStr);
|
||||
pos += strlen(replaceStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1533,8 +1501,8 @@ private:
|
|||
if (!mSdpHelper.IsBundleSlave(*sdp, i)) {
|
||||
const SdpAttributeList& attrs = msection.GetAttributeList();
|
||||
|
||||
ASSERT_EQ(source.mIceUfrag, attrs.GetIceUfrag());
|
||||
ASSERT_EQ(source.mIcePwd, attrs.GetIcePwd());
|
||||
ASSERT_FALSE(attrs.GetIceUfrag().empty());
|
||||
ASSERT_FALSE(attrs.GetIcePwd().empty());
|
||||
const SdpFingerprintAttributeList& fps = attrs.GetFingerprint();
|
||||
for (auto fp = fps.mFingerprints.begin(); fp != fps.mFingerprints.end();
|
||||
++fp) {
|
||||
|
@ -4286,7 +4254,6 @@ TEST_F(JsepSessionTest, TestIceRestart)
|
|||
|
||||
JsepOfferOptions options;
|
||||
options.mIceRestart = Some(true);
|
||||
ModifyOffererIceCredentials();
|
||||
|
||||
std::string reoffer = CreateOffer(Some(options));
|
||||
SetLocalOffer(reoffer, CHECK_SUCCESS);
|
||||
|
@ -4333,6 +4300,26 @@ TEST_F(JsepSessionTest, TestIceRestart)
|
|||
reanswerMediaAttrs.GetIcePwd().c_str());
|
||||
ASSERT_NE(answerMediaAttrs.GetIceUfrag().c_str(),
|
||||
reanswerMediaAttrs.GetIceUfrag().c_str());
|
||||
|
||||
auto offererTransceivers = mSessionOff->GetTransceivers();
|
||||
auto answererTransceivers = mSessionAns->GetTransceivers();
|
||||
ASSERT_EQ(reofferMediaAttrs.GetIceUfrag(),
|
||||
offererTransceivers[0]->mTransport.mLocalUfrag);
|
||||
ASSERT_EQ(reofferMediaAttrs.GetIceUfrag(),
|
||||
answererTransceivers[0]->mTransport.mIce->GetUfrag());
|
||||
ASSERT_EQ(reofferMediaAttrs.GetIcePwd(),
|
||||
offererTransceivers[0]->mTransport.mLocalPwd);
|
||||
ASSERT_EQ(reofferMediaAttrs.GetIcePwd(),
|
||||
answererTransceivers[0]->mTransport.mIce->GetPassword());
|
||||
|
||||
ASSERT_EQ(reanswerMediaAttrs.GetIceUfrag(),
|
||||
answererTransceivers[0]->mTransport.mLocalUfrag);
|
||||
ASSERT_EQ(reanswerMediaAttrs.GetIceUfrag(),
|
||||
offererTransceivers[0]->mTransport.mIce->GetUfrag());
|
||||
ASSERT_EQ(reanswerMediaAttrs.GetIcePwd(),
|
||||
answererTransceivers[0]->mTransport.mLocalPwd);
|
||||
ASSERT_EQ(reanswerMediaAttrs.GetIcePwd(),
|
||||
offererTransceivers[0]->mTransport.mIce->GetPassword());
|
||||
}
|
||||
|
||||
TEST_F(JsepSessionTest, TestAnswererIndicatingIceRestart)
|
||||
|
@ -4354,7 +4341,8 @@ TEST_F(JsepSessionTest, TestAnswererIndicatingIceRestart)
|
|||
std::string reanswer = CreateAnswer();
|
||||
|
||||
// change the ice pwd and ufrag
|
||||
ReplaceInSdp(&reanswer, "Answerer-1-", "bad-2-");
|
||||
ReplaceInSdp(&reanswer, "a=ice-ufrag:", "a=ice-ufrag:bad-");
|
||||
ReplaceInSdp(&reanswer, "a=ice-pwd:", "a=ice-pwd:bad-");
|
||||
SetLocalAnswer(reanswer, CHECK_SUCCESS);
|
||||
nsresult rv = mSessionOff->SetRemoteDescription(kJsepSdpAnswer, reanswer);
|
||||
ASSERT_NE(NS_OK, rv); // NS_ERROR_INVALID_ARG
|
||||
|
|
|
@ -99,13 +99,8 @@ public:
|
|||
}
|
||||
|
||||
// Set up the ICE And DTLS data.
|
||||
virtual nsresult SetIceCredentials(const std::string& ufrag,
|
||||
const std::string& pwd) = 0;
|
||||
virtual const std::string& GetUfrag() const = 0;
|
||||
virtual const std::string& GetPwd() const = 0;
|
||||
virtual nsresult SetBundlePolicy(JsepBundlePolicy policy) = 0;
|
||||
virtual bool RemoteIsIceLite() const = 0;
|
||||
virtual bool RemoteIceIsRestarting() const = 0;
|
||||
virtual std::vector<std::string> GetIceOptions() const = 0;
|
||||
|
||||
virtual nsresult AddDtlsFingerprint(const std::string& algorithm,
|
||||
|
@ -185,6 +180,7 @@ public:
|
|||
// ICE controlling or controlled
|
||||
virtual bool IsIceControlling() const = 0;
|
||||
virtual bool IsOfferer() const = 0;
|
||||
virtual bool IsIceRestarting() const = 0;
|
||||
|
||||
virtual const std::string
|
||||
GetLastError() const
|
||||
|
|
|
@ -55,6 +55,21 @@ static std::bitset<128> GetForbiddenSdpPayloadTypes() {
|
|||
return forbidden;
|
||||
}
|
||||
|
||||
static std::string GetRandomHex()
|
||||
{
|
||||
uint32_t rand;
|
||||
SECStatus rv =
|
||||
PK11_GenerateRandom(reinterpret_cast<unsigned char*>(&rand), sizeof(rand));
|
||||
if (rv != SECSuccess) {
|
||||
MOZ_CRASH();
|
||||
return "";
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
os << std::hex << std::setfill('0') << std::setw(8) << rand;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::Init()
|
||||
{
|
||||
|
@ -73,6 +88,8 @@ JsepSessionImpl::Init()
|
|||
mRunSdpComparer = Preferences::GetBool("media.peerconnection.sdp.rust.compare",
|
||||
false);
|
||||
|
||||
mIceUfrag = GetRandomHex();
|
||||
mIcePwd = GetRandomHex();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -112,17 +129,6 @@ JsepSessionImpl::AddTransceiver(RefPtr<JsepTransceiver> transceiver)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::SetIceCredentials(const std::string& ufrag,
|
||||
const std::string& pwd)
|
||||
{
|
||||
mLastError.clear();
|
||||
mIceUfrag = ufrag;
|
||||
mIcePwd = pwd;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::SetBundlePolicy(JsepBundlePolicy policy)
|
||||
{
|
||||
|
@ -420,13 +426,15 @@ JsepSessionImpl::CreateOffer(const JsepOfferOptions& options,
|
|||
std::string* offer)
|
||||
{
|
||||
mLastError.clear();
|
||||
mLocalIceIsRestarting = options.mIceRestart.isSome() && *(options.mIceRestart);
|
||||
|
||||
if (mState != kJsepStateStable) {
|
||||
JSEP_SET_ERROR("Cannot create offer in state " << GetStateStr(mState));
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// This is one of those places where CreateOffer sets some state.
|
||||
SetIceRestarting(options.mIceRestart.isSome() && *(options.mIceRestart));
|
||||
|
||||
UniquePtr<Sdp> sdp;
|
||||
|
||||
// Make the basic SDP that is common to offer/answer.
|
||||
|
@ -976,7 +984,7 @@ JsepSessionImpl::SetRemoteDescription(JsepSdpType type, const std::string& sdp)
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
mRemoteIsIceLite = iceLite;
|
||||
mIceOptions = iceOptions;
|
||||
mRemoteIceIsRestarting = iceRestarting;
|
||||
SetIceRestarting(iceRestarting);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
@ -986,6 +994,10 @@ nsresult
|
|||
JsepSessionImpl::HandleNegotiatedSession(const UniquePtr<Sdp>& local,
|
||||
const UniquePtr<Sdp>& remote)
|
||||
{
|
||||
// local ufrag/pwd has been negotiated; we will never go back to the old ones
|
||||
mOldIceUfrag.clear();
|
||||
mOldIcePwd.clear();
|
||||
|
||||
bool remoteIceLite =
|
||||
remote->GetAttributeList().HasAttribute(SdpAttribute::kIceLiteAttribute);
|
||||
|
||||
|
@ -1136,13 +1148,14 @@ JsepSessionImpl::EnsureHasOwnTransport(const SdpMediaSection& msection,
|
|||
{
|
||||
JsepTransport& transport = transceiver->mTransport;
|
||||
|
||||
// TODO: Detect ICE restart on a per-msection basis.
|
||||
if (mLocalIceIsRestarting || mRemoteIceIsRestarting ||
|
||||
!transceiver->HasOwnTransport()) {
|
||||
if (!transceiver->HasOwnTransport()) {
|
||||
// Transceiver didn't own this transport last time, it won't now either
|
||||
transport.Close();
|
||||
}
|
||||
|
||||
transport.mLocalUfrag = msection.GetAttributeList().GetIceUfrag();
|
||||
transport.mLocalPwd = msection.GetAttributeList().GetIcePwd();
|
||||
|
||||
transceiver->ClearBundleLevel();
|
||||
|
||||
if (mSdpHelper.HasRtcp(msection.GetProtocol())) {
|
||||
|
@ -1169,7 +1182,9 @@ JsepSessionImpl::FinalizeTransport(const SdpAttributeList& remote,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!transport->mIce) {
|
||||
if (!transport->mIce ||
|
||||
transport->mIce->mUfrag != remote.GetIceUfrag() ||
|
||||
transport->mIce->mPwd != remote.GetIcePwd()) {
|
||||
UniquePtr<JsepIceTransport> ice = MakeUnique<JsepIceTransport>();
|
||||
|
||||
// We do sanity-checking for these in ParseSdp
|
||||
|
@ -1254,8 +1269,7 @@ JsepSessionImpl::CopyPreviousTransportParams(const Sdp& oldAnswer,
|
|||
mSdpHelper.AreOldTransportParamsValid(oldAnswer,
|
||||
offerersPreviousSdp,
|
||||
newOffer,
|
||||
i) &&
|
||||
!mRemoteIceIsRestarting
|
||||
i)
|
||||
) {
|
||||
// If newLocal is an offer, this will be the number of components we used
|
||||
// last time, and if it is an answer, this will be the number of
|
||||
|
@ -1798,8 +1812,7 @@ JsepSessionImpl::ValidateRemoteDescription(const Sdp& description)
|
|||
|
||||
bool differ = mSdpHelper.IceCredentialsDiffer(newMsection, oldMsection);
|
||||
|
||||
// Detect bad answer ICE restart when offer doesn't request ICE restart
|
||||
if (mIsOfferer && differ && !mLocalIceIsRestarting) {
|
||||
if (mIsOfferer && differ && !IsIceRestarting()) {
|
||||
JSEP_SET_ERROR("Remote description indicates ICE restart but offer did not "
|
||||
"request ICE restart (new remote description changes either "
|
||||
"the ice-ufrag or ice-pwd)");
|
||||
|
@ -2366,6 +2379,28 @@ JsepSessionImpl::GetAnswer() const
|
|||
: mCurrentLocalDescription.get();
|
||||
}
|
||||
|
||||
void
|
||||
JsepSessionImpl::SetIceRestarting(bool restarting)
|
||||
{
|
||||
if (restarting) {
|
||||
// not restarting -> restarting
|
||||
if (!IsIceRestarting()) {
|
||||
// We don't set this more than once, so the old ufrag/pwd is preserved
|
||||
// even if we CreateOffer({iceRestart:true}) multiple times in a row.
|
||||
mOldIceUfrag = mIceUfrag;
|
||||
mOldIcePwd = mIcePwd;
|
||||
}
|
||||
mIceUfrag = GetRandomHex();
|
||||
mIcePwd = GetRandomHex();
|
||||
} else if (IsIceRestarting()) {
|
||||
// restarting -> not restarting, restore old ufrag/pwd
|
||||
mIceUfrag = mOldIceUfrag;
|
||||
mIcePwd = mOldIcePwd;
|
||||
mOldIceUfrag.clear();
|
||||
mOldIcePwd.clear();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
JsepSessionImpl::Close()
|
||||
{
|
||||
|
|
|
@ -36,9 +36,7 @@ public:
|
|||
mIsOfferer(false),
|
||||
mWasOffererLastTime(false),
|
||||
mIceControlling(false),
|
||||
mLocalIceIsRestarting(false),
|
||||
mRemoteIsIceLite(false),
|
||||
mRemoteIceIsRestarting(false),
|
||||
mBundlePolicy(kBundleBalanced),
|
||||
mSessionId(0),
|
||||
mSessionVersion(0),
|
||||
|
@ -54,10 +52,6 @@ public:
|
|||
// Implement JsepSession methods.
|
||||
virtual nsresult Init() override;
|
||||
|
||||
virtual nsresult SetIceCredentials(const std::string& ufrag,
|
||||
const std::string& pwd) override;
|
||||
virtual const std::string& GetUfrag() const override { return mIceUfrag; }
|
||||
virtual const std::string& GetPwd() const override { return mIcePwd; }
|
||||
nsresult SetBundlePolicy(JsepBundlePolicy policy) override;
|
||||
|
||||
virtual bool
|
||||
|
@ -66,12 +60,6 @@ public:
|
|||
return mRemoteIsIceLite;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
RemoteIceIsRestarting() const override
|
||||
{
|
||||
return mRemoteIceIsRestarting;
|
||||
}
|
||||
|
||||
virtual std::vector<std::string>
|
||||
GetIceOptions() const override
|
||||
{
|
||||
|
@ -160,6 +148,12 @@ public:
|
|||
return mIsOfferer;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
IsIceRestarting() const override
|
||||
{
|
||||
return !mOldIceUfrag.empty();
|
||||
}
|
||||
|
||||
virtual const std::vector<RefPtr<JsepTransceiver>>&
|
||||
GetTransceivers() const override {
|
||||
return mTransceivers;
|
||||
|
@ -262,6 +256,7 @@ private:
|
|||
mozilla::Sdp* GetParsedRemoteDescription(JsepDescriptionPendingOrCurrent type)
|
||||
const;
|
||||
const Sdp* GetAnswer() const;
|
||||
void SetIceRestarting(bool restarting);
|
||||
|
||||
// !!!NOT INDEXED BY LEVEL!!! These are in the order they were created in. The
|
||||
// level mapping is done with JsepTransceiver::mLevel.
|
||||
|
@ -274,9 +269,9 @@ private:
|
|||
bool mIceControlling;
|
||||
std::string mIceUfrag;
|
||||
std::string mIcePwd;
|
||||
bool mLocalIceIsRestarting;
|
||||
std::string mOldIceUfrag;
|
||||
std::string mOldIcePwd;
|
||||
bool mRemoteIsIceLite;
|
||||
bool mRemoteIceIsRestarting;
|
||||
std::vector<std::string> mIceOptions;
|
||||
JsepBundlePolicy mBundlePolicy;
|
||||
std::vector<JsepDtlsFingerprint> mDtlsFingerprints;
|
||||
|
|
|
@ -101,6 +101,8 @@ public:
|
|||
mDtls.reset(orig.mDtls ? new JsepDtlsTransport(*orig.mDtls) : nullptr);
|
||||
mTransportId = orig.mTransportId;
|
||||
mComponents = orig.mComponents;
|
||||
mLocalUfrag = orig.mLocalUfrag;
|
||||
mLocalPwd = orig.mLocalPwd;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
@ -111,6 +113,8 @@ public:
|
|||
mTransportId.clear();
|
||||
mIce.reset();
|
||||
mDtls.reset();
|
||||
mLocalUfrag.clear();
|
||||
mLocalPwd.clear();
|
||||
}
|
||||
|
||||
// Unique identifier for this transport within this call. Group?
|
||||
|
@ -122,6 +126,8 @@ public:
|
|||
|
||||
// Number of required components.
|
||||
size_t mComponents;
|
||||
std::string mLocalUfrag;
|
||||
std::string mLocalPwd;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -692,15 +692,6 @@ PeerConnectionImpl::Initialize(PeerConnectionObserver& aObserver,
|
|||
return res;
|
||||
}
|
||||
|
||||
res = mJsepSession->SetIceCredentials(mMedia->ice_ctx()->ufrag(),
|
||||
mMedia->ice_ctx()->pwd());
|
||||
if (NS_FAILED(res)) {
|
||||
CSFLogError(LOGTAG, "%s: Couldn't set ICE credentials, res=%u",
|
||||
__FUNCTION__,
|
||||
static_cast<unsigned>(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
res = mJsepSession->SetBundlePolicy(aConfiguration.getBundlePolicy());
|
||||
if (NS_FAILED(res)) {
|
||||
CSFLogError(LOGTAG, "%s: Couldn't set bundle policy, res=%u, error=%s",
|
||||
|
@ -1481,13 +1472,6 @@ NS_IMETHODIMP
|
|||
PeerConnectionImpl::CreateOffer(const JsepOfferOptions& aOptions)
|
||||
{
|
||||
PC_AUTO_ENTER_API_CALL(true);
|
||||
bool restartIce = aOptions.mIceRestart.isSome() && *(aOptions.mIceRestart);
|
||||
if (!restartIce &&
|
||||
mMedia->GetIceRestartState() ==
|
||||
PeerConnectionMedia::ICE_RESTART_PROVISIONAL) {
|
||||
RollbackIceRestart();
|
||||
}
|
||||
|
||||
RefPtr<PeerConnectionObserver> pco = do_QueryObjectReferent(mPCObserver);
|
||||
if (!pco) {
|
||||
return NS_OK;
|
||||
|
@ -1503,36 +1487,7 @@ PeerConnectionImpl::CreateOffer(const JsepOfferOptions& aOptions)
|
|||
|
||||
CSFLogDebug(LOGTAG, "CreateOffer()");
|
||||
|
||||
bool iceRestartPrimed = false;
|
||||
nsresult nrv;
|
||||
if (restartIce &&
|
||||
!mJsepSession->GetLocalDescription(kJsepDescriptionCurrent).empty()) {
|
||||
// If restart is requested and a restart is already in progress, we
|
||||
// need to make room for the restart request so we either rollback
|
||||
// or finalize to "clear" the previous restart.
|
||||
if (mMedia->GetIceRestartState() ==
|
||||
PeerConnectionMedia::ICE_RESTART_PROVISIONAL) {
|
||||
// we're mid-restart and can rollback
|
||||
RollbackIceRestart();
|
||||
} else if (mMedia->GetIceRestartState() ==
|
||||
PeerConnectionMedia::ICE_RESTART_COMMITTED) {
|
||||
// we're mid-restart and can't rollback, finalize restart even
|
||||
// though we're not really ready yet
|
||||
FinalizeIceRestart();
|
||||
}
|
||||
|
||||
CSFLogInfo(LOGTAG, "Offerer restarting ice");
|
||||
nrv = SetupIceRestartCredentials();
|
||||
if (NS_FAILED(nrv)) {
|
||||
CSFLogError(LOGTAG, "%s: SetupIceRestart failed, res=%u",
|
||||
__FUNCTION__,
|
||||
static_cast<unsigned>(nrv));
|
||||
return nrv;
|
||||
}
|
||||
iceRestartPrimed = true;
|
||||
}
|
||||
|
||||
nrv = ConfigureJsepSessionCodecs();
|
||||
nsresult nrv = ConfigureJsepSessionCodecs();
|
||||
if (NS_FAILED(nrv)) {
|
||||
CSFLogError(LOGTAG, "Failed to configure codecs");
|
||||
return nrv;
|
||||
|
@ -1558,19 +1513,8 @@ PeerConnectionImpl::CreateOffer(const JsepOfferOptions& aOptions)
|
|||
CSFLogError(LOGTAG, "%s: pc = %s, error = %s",
|
||||
__FUNCTION__, mHandle.c_str(), errorString.c_str());
|
||||
|
||||
if (iceRestartPrimed) {
|
||||
// reset the ice credentials because CreateOffer failed
|
||||
ResetIceCredentials();
|
||||
}
|
||||
|
||||
pco->OnCreateOfferError(error, ObString(errorString.c_str()), rv);
|
||||
} else {
|
||||
// wait until we know CreateOffer succeeds before we actually start
|
||||
// the ice restart gears turning.
|
||||
if (iceRestartPrimed) {
|
||||
BeginIceRestart();
|
||||
}
|
||||
|
||||
UpdateSignalingState();
|
||||
pco->OnCreateOfferSuccess(ObString(offer.c_str()), rv);
|
||||
}
|
||||
|
@ -1590,32 +1534,13 @@ PeerConnectionImpl::CreateAnswer()
|
|||
|
||||
CSFLogDebug(LOGTAG, "CreateAnswer()");
|
||||
|
||||
bool iceRestartPrimed = false;
|
||||
nsresult nrv;
|
||||
if (mJsepSession->RemoteIceIsRestarting()) {
|
||||
if (mMedia->GetIceRestartState() ==
|
||||
PeerConnectionMedia::ICE_RESTART_COMMITTED) {
|
||||
FinalizeIceRestart();
|
||||
} else if (!mMedia->IsIceRestarting()) {
|
||||
CSFLogInfo(LOGTAG, "Answerer restarting ice");
|
||||
nrv = SetupIceRestartCredentials();
|
||||
if (NS_FAILED(nrv)) {
|
||||
CSFLogError(LOGTAG, "%s: SetupIceRestart failed, res=%u",
|
||||
__FUNCTION__,
|
||||
static_cast<unsigned>(nrv));
|
||||
return nrv;
|
||||
}
|
||||
iceRestartPrimed = true;
|
||||
}
|
||||
}
|
||||
|
||||
STAMP_TIMECARD(mTimeCard, "Create Answer");
|
||||
// TODO(bug 1098015): Once RTCAnswerOptions is standardized, we'll need to
|
||||
// add it as a param to CreateAnswer, and convert it here.
|
||||
JsepAnswerOptions options;
|
||||
std::string answer;
|
||||
|
||||
nrv = mJsepSession->CreateAnswer(options, &answer);
|
||||
nsresult nrv = mJsepSession->CreateAnswer(options, &answer);
|
||||
JSErrorResult rv;
|
||||
if (NS_FAILED(nrv)) {
|
||||
Error error;
|
||||
|
@ -1631,19 +1556,8 @@ PeerConnectionImpl::CreateAnswer()
|
|||
CSFLogError(LOGTAG, "%s: pc = %s, error = %s",
|
||||
__FUNCTION__, mHandle.c_str(), errorString.c_str());
|
||||
|
||||
if (iceRestartPrimed) {
|
||||
// reset the ice credentials because CreateAnswer failed
|
||||
ResetIceCredentials();
|
||||
}
|
||||
|
||||
pco->OnCreateAnswerError(error, ObString(errorString.c_str()), rv);
|
||||
} else {
|
||||
// wait until we know CreateAnswer succeeds before we actually start
|
||||
// the ice restart gears turning.
|
||||
if (iceRestartPrimed) {
|
||||
BeginIceRestart();
|
||||
}
|
||||
|
||||
UpdateSignalingState();
|
||||
pco->OnCreateAnswerSuccess(ObString(answer.c_str()), rv);
|
||||
}
|
||||
|
@ -1651,82 +1565,6 @@ PeerConnectionImpl::CreateAnswer()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::SetupIceRestartCredentials()
|
||||
{
|
||||
if (mMedia->IsIceRestarting()) {
|
||||
CSFLogError(LOGTAG, "%s: ICE already restarting",
|
||||
__FUNCTION__);
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
std::string ufrag = mMedia->ice_ctx()->GetNewUfrag();
|
||||
std::string pwd = mMedia->ice_ctx()->GetNewPwd();
|
||||
if (ufrag.empty() || pwd.empty()) {
|
||||
CSFLogError(LOGTAG, "%s: Bad ICE credentials (ufrag:'%s'/pwd:'%s')",
|
||||
__FUNCTION__,
|
||||
ufrag.c_str(), pwd.c_str());
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
// hold on to the current ice creds in case of rollback
|
||||
mPreviousIceUfrag = mJsepSession->GetUfrag();
|
||||
mPreviousIcePwd = mJsepSession->GetPwd();
|
||||
|
||||
nsresult nrv = mJsepSession->SetIceCredentials(ufrag, pwd);
|
||||
if (NS_FAILED(nrv)) {
|
||||
CSFLogError(LOGTAG, "%s: Couldn't set ICE credentials, res=%u",
|
||||
__FUNCTION__,
|
||||
static_cast<unsigned>(nrv));
|
||||
return nrv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionImpl::BeginIceRestart()
|
||||
{
|
||||
mMedia->BeginIceRestart(mJsepSession->GetUfrag(), mJsepSession->GetPwd());
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::ResetIceCredentials()
|
||||
{
|
||||
nsresult nrv = mJsepSession->SetIceCredentials(mPreviousIceUfrag, mPreviousIcePwd);
|
||||
mPreviousIceUfrag = "";
|
||||
mPreviousIcePwd = "";
|
||||
|
||||
if (NS_FAILED(nrv)) {
|
||||
CSFLogError(LOGTAG, "%s: Couldn't reset ICE credentials, res=%u",
|
||||
__FUNCTION__,
|
||||
static_cast<unsigned>(nrv));
|
||||
return nrv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionImpl::RollbackIceRestart()
|
||||
{
|
||||
mMedia->RollbackIceRestart();
|
||||
++mIceRollbackCount;
|
||||
|
||||
// put back the previous ice creds
|
||||
return ResetIceCredentials();
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionImpl::FinalizeIceRestart()
|
||||
{
|
||||
mMedia->FinalizeIceRestart();
|
||||
// clear the previous ice creds since they are no longer needed
|
||||
mPreviousIceUfrag = "";
|
||||
mPreviousIcePwd = "";
|
||||
++mIceRestartCount;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
|
||||
{
|
||||
|
@ -1750,6 +1588,7 @@ PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
|
|||
|
||||
mLocalRequestedSDP = aSDP;
|
||||
|
||||
bool wasRestartingIce = mJsepSession->IsIceRestarting();
|
||||
JsepSdpType sdpType;
|
||||
switch (aAction) {
|
||||
case IPeerConnection::kActionOffer:
|
||||
|
@ -1789,6 +1628,9 @@ PeerConnectionImpl::SetLocalDescription(int32_t aAction, const char* aSDP)
|
|||
__FUNCTION__, mHandle.c_str(), errorString.c_str());
|
||||
pco->OnSetLocalDescriptionError(error, ObString(errorString.c_str()), rv);
|
||||
} else {
|
||||
if (wasRestartingIce) {
|
||||
RecordIceRestartStatistics(sdpType);
|
||||
}
|
||||
UpdateSignalingState(sdpType == mozilla::kJsepSdpRollback);
|
||||
pco->OnSetLocalDescriptionSuccess(rv);
|
||||
}
|
||||
|
@ -1849,6 +1691,7 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
|
|||
STAMP_TIMECARD(mTimeCard, "Set Remote Description");
|
||||
|
||||
mRemoteRequestedSDP = aSDP;
|
||||
bool wasRestartingIce = mJsepSession->IsIceRestarting();
|
||||
JsepSdpType sdpType;
|
||||
switch (action) {
|
||||
case IPeerConnection::kActionOffer:
|
||||
|
@ -1934,6 +1777,9 @@ PeerConnectionImpl::SetRemoteDescription(int32_t action, const char* aSDP)
|
|||
}
|
||||
}
|
||||
|
||||
if (wasRestartingIce) {
|
||||
RecordIceRestartStatistics(sdpType);
|
||||
}
|
||||
UpdateSignalingState(sdpType == mozilla::kJsepSdpRollback);
|
||||
|
||||
pco->OnSetRemoteDescriptionSuccess(jrv);
|
||||
|
@ -2836,15 +2682,6 @@ PeerConnectionImpl::SetSignalingState_m(PCImplSignalingState aSignalingState,
|
|||
mSignalingState = aSignalingState;
|
||||
|
||||
if (mSignalingState == PCImplSignalingState::SignalingStable) {
|
||||
if (mMedia->GetIceRestartState() ==
|
||||
PeerConnectionMedia::ICE_RESTART_PROVISIONAL) {
|
||||
if (rollback) {
|
||||
RollbackIceRestart();
|
||||
} else {
|
||||
mMedia->CommitIceRestart();
|
||||
}
|
||||
}
|
||||
|
||||
// If we're rolling back a local offer, we might need to remove some
|
||||
// transports, and stomp some MediaPipeline setup, but nothing further
|
||||
// needs to be done.
|
||||
|
@ -3125,14 +2962,6 @@ void PeerConnectionImpl::IceConnectionStateChange(
|
|||
|
||||
mIceConnectionState = domState;
|
||||
|
||||
if (mIceConnectionState == PCImplIceConnectionState::Connected ||
|
||||
mIceConnectionState == PCImplIceConnectionState::Completed ||
|
||||
mIceConnectionState == PCImplIceConnectionState::Failed) {
|
||||
if (mMedia->IsIceRestarting()) {
|
||||
FinalizeIceRestart();
|
||||
}
|
||||
}
|
||||
|
||||
// Uncount this connection as active on the inner window upon close.
|
||||
if (mWindow && mActiveOnWindow && mIceConnectionState == PCImplIceConnectionState::Closed) {
|
||||
mWindow->RemovePeerConnection();
|
||||
|
@ -3726,6 +3555,22 @@ PeerConnectionImpl::RecordLongtermICEStatistics() {
|
|||
WebrtcGlobalInformation::StoreLongTermICEStatistics(*this);
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionImpl::RecordIceRestartStatistics(JsepSdpType type)
|
||||
{
|
||||
switch (type) {
|
||||
case mozilla::kJsepSdpOffer:
|
||||
case mozilla::kJsepSdpPranswer:
|
||||
break;
|
||||
case mozilla::kJsepSdpAnswer:
|
||||
++mIceRestartCount;
|
||||
break;
|
||||
case mozilla::kJsepSdpRollback:
|
||||
++mIceRollbackCount;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionImpl::IceStreamReady(NrIceMediaStream *aStream)
|
||||
{
|
||||
|
|
|
@ -687,12 +687,6 @@ private:
|
|||
dom::MediaStreamTrack* aSendTrack,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsresult SetupIceRestartCredentials();
|
||||
void BeginIceRestart();
|
||||
nsresult ResetIceCredentials();
|
||||
nsresult RollbackIceRestart();
|
||||
void FinalizeIceRestart();
|
||||
|
||||
static void GetStatsForPCObserver_s(
|
||||
const std::string& pcHandle,
|
||||
nsAutoPtr<RTCStatsQuery> query);
|
||||
|
@ -710,6 +704,8 @@ private:
|
|||
// or other things.
|
||||
void RecordLongtermICEStatistics();
|
||||
|
||||
void RecordIceRestartStatistics(JsepSdpType type);
|
||||
|
||||
// Timecard used to measure processing time. This should be the first class
|
||||
// attribute so that we accurately measure the time required to instantiate
|
||||
// any other attributes of this class.
|
||||
|
@ -773,8 +769,6 @@ private:
|
|||
// The JSEP negotiation session.
|
||||
mozilla::UniquePtr<PCUuidGenerator> mUuidGen;
|
||||
mozilla::UniquePtr<mozilla::JsepSession> mJsepSession;
|
||||
std::string mPreviousIceUfrag; // used during rollback of ice restart
|
||||
std::string mPreviousIcePwd; // used during rollback of ice restart
|
||||
unsigned long mIceRestartCount;
|
||||
unsigned long mIceRollbackCount;
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ PeerConnectionMedia::ProtocolProxyQueryHandler::SetProxyOnPcm(
|
|||
return;
|
||||
}
|
||||
|
||||
if (pcm_->mIceCtxHdlr.get()) {
|
||||
if (pcm_->mIceCtx.get()) {
|
||||
assert(httpsProxyPort >= 0 && httpsProxyPort < (1 << 16));
|
||||
// Note that this could check if PrivacyRequested() is set on the PC and
|
||||
// remove "webrtc" from the ALPN list. But that would only work if the PC
|
||||
|
@ -131,7 +131,7 @@ PeerConnectionMedia::StunAddrsHandler::OnStunAddrsAvailable(
|
|||
// If parent process returns 0 STUN addresses, change ICE connection
|
||||
// state to failed.
|
||||
if (!pcm_->mStunAddrs.Length()) {
|
||||
pcm_->SignalIceConnectionStateChange(pcm_->mIceCtxHdlr->ctx().get(),
|
||||
pcm_->SignalIceConnectionStateChange(pcm_->mIceCtx.get(),
|
||||
NrIceCtx::ICE_CTX_FAILED);
|
||||
}
|
||||
|
||||
|
@ -143,13 +143,12 @@ PeerConnectionMedia::PeerConnectionMedia(PeerConnectionImpl *parent)
|
|||
: mParent(parent),
|
||||
mParentHandle(parent->GetHandle()),
|
||||
mParentName(parent->GetName()),
|
||||
mIceCtxHdlr(nullptr),
|
||||
mIceCtx(nullptr),
|
||||
mDNSResolver(new NrIceResolver()),
|
||||
mUuidGen(MakeUnique<PCUuidGenerator>()),
|
||||
mMainThread(mParent->GetMainThread()),
|
||||
mSTSThread(mParent->GetSTSThread()),
|
||||
mProxyResolveCompleted(false),
|
||||
mIceRestartState(ICE_RESTART_NONE),
|
||||
mLocalAddrsCompleted(false) {
|
||||
}
|
||||
|
||||
|
@ -253,26 +252,26 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
|||
// setup the stun local addresses IPC async call
|
||||
InitLocalAddrs();
|
||||
|
||||
NrIceCtx::InitializeGlobals(mParent->GetAllowIceLoopback(),
|
||||
ice_tcp,
|
||||
mParent->GetAllowIceLinkLocal());
|
||||
|
||||
// TODO(ekr@rtfm.com): need some way to set not offerer later
|
||||
// Looks like a bug in the NrIceCtx API.
|
||||
mIceCtxHdlr = NrIceCtxHandler::Create("PC:" + mParentName,
|
||||
mParent->GetAllowIceLoopback(),
|
||||
ice_tcp,
|
||||
mParent->GetAllowIceLinkLocal(),
|
||||
policy);
|
||||
if(!mIceCtxHdlr) {
|
||||
mIceCtx = NrIceCtx::Create("PC:" + mParentName, policy);
|
||||
if(!mIceCtx) {
|
||||
CSFLogError(LOGTAG, "%s: Failed to create Ice Context", __FUNCTION__);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv = mIceCtxHdlr->ctx()->SetStunServers(stun_servers))) {
|
||||
if (NS_FAILED(rv = mIceCtx->SetStunServers(stun_servers))) {
|
||||
CSFLogError(LOGTAG, "%s: Failed to set stun servers", __FUNCTION__);
|
||||
return rv;
|
||||
}
|
||||
// Give us a way to globally turn off TURN support
|
||||
bool disabled = Preferences::GetBool("media.peerconnection.turn.disable", false);
|
||||
if (!disabled) {
|
||||
if (NS_FAILED(rv = mIceCtxHdlr->ctx()->SetTurnServers(turn_servers))) {
|
||||
if (NS_FAILED(rv = mIceCtx->SetTurnServers(turn_servers))) {
|
||||
CSFLogError(LOGTAG, "%s: Failed to set turn servers", __FUNCTION__);
|
||||
return rv;
|
||||
}
|
||||
|
@ -284,11 +283,11 @@ nsresult PeerConnectionMedia::Init(const std::vector<NrIceStunServer>& stun_serv
|
|||
return rv;
|
||||
}
|
||||
if (NS_FAILED(rv =
|
||||
mIceCtxHdlr->ctx()->SetResolver(mDNSResolver->AllocateResolver()))) {
|
||||
mIceCtx->SetResolver(mDNSResolver->AllocateResolver()))) {
|
||||
CSFLogError(LOGTAG, "%s: Failed to get dns resolver", __FUNCTION__);
|
||||
return rv;
|
||||
}
|
||||
ConnectSignals(mIceCtxHdlr->ctx().get());
|
||||
ConnectSignals(mIceCtx.get());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -303,6 +302,8 @@ PeerConnectionMedia::EnsureTransports(const JsepSession& aSession)
|
|||
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::EnsureTransport_s,
|
||||
transceiver->mTransport.mTransportId,
|
||||
transceiver->mTransport.mLocalUfrag,
|
||||
transceiver->mTransport.mLocalPwd,
|
||||
transceiver->mTransport.mComponents),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
@ -313,9 +314,11 @@ PeerConnectionMedia::EnsureTransports(const JsepSession& aSession)
|
|||
|
||||
void
|
||||
PeerConnectionMedia::EnsureTransport_s(const std::string& aTransportId,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPwd,
|
||||
size_t aComponentCount)
|
||||
{
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtxHdlr->ctx()->GetStream(aTransportId));
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtx->GetStream(aTransportId));
|
||||
if (!stream) {
|
||||
CSFLogDebug(LOGTAG, "%s: Creating ICE media stream=%s components=%u",
|
||||
mParentHandle.c_str(),
|
||||
|
@ -324,21 +327,21 @@ PeerConnectionMedia::EnsureTransport_s(const std::string& aTransportId,
|
|||
|
||||
std::ostringstream os;
|
||||
os << mParentName << " transport-id=" << aTransportId;
|
||||
RefPtr<NrIceMediaStream> stream =
|
||||
mIceCtxHdlr->CreateStream(os.str(),
|
||||
aComponentCount);
|
||||
stream = mIceCtx->CreateStream(aTransportId,
|
||||
os.str(),
|
||||
aComponentCount);
|
||||
|
||||
if (!stream) {
|
||||
CSFLogError(LOGTAG, "Failed to create ICE stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
stream->SetId(aTransportId);
|
||||
stream->SignalReady.connect(this, &PeerConnectionMedia::IceStreamReady_s);
|
||||
stream->SignalCandidate.connect(this,
|
||||
&PeerConnectionMedia::OnCandidateFound_s);
|
||||
mIceCtxHdlr->ctx()->SetStream(aTransportId, stream);
|
||||
}
|
||||
// This might begin an ICE restart
|
||||
stream->SetIceCredentials(aUfrag, aPwd);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -406,6 +409,8 @@ PeerConnectionMedia::UpdateTransport(const JsepTransceiver& aTransceiver,
|
|||
WrapRunnable(RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::ActivateTransport_s,
|
||||
transport.mTransportId,
|
||||
transport.mLocalUfrag,
|
||||
transport.mLocalPwd,
|
||||
components,
|
||||
ufrag,
|
||||
pwd,
|
||||
|
@ -418,6 +423,8 @@ PeerConnectionMedia::UpdateTransport(const JsepTransceiver& aTransceiver,
|
|||
void
|
||||
PeerConnectionMedia::ActivateTransport_s(
|
||||
const std::string& aTransportId,
|
||||
const std::string& aLocalUfrag,
|
||||
const std::string& aLocalPwd,
|
||||
size_t aComponentCount,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPassword,
|
||||
|
@ -425,36 +432,34 @@ PeerConnectionMedia::ActivateTransport_s(
|
|||
|
||||
MOZ_ASSERT(aComponentCount);
|
||||
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtxHdlr->ctx()->GetStream(aTransportId));
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtx->GetStream(aTransportId));
|
||||
if (!stream) {
|
||||
MOZ_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stream->HasParsedAttributes()) {
|
||||
CSFLogDebug(LOGTAG, "%s: Activating ICE media stream=%s components=%u",
|
||||
mParentHandle.c_str(),
|
||||
aTransportId.c_str(),
|
||||
static_cast<unsigned>(aComponentCount));
|
||||
CSFLogDebug(LOGTAG, "%s: Activating ICE media stream=%s components=%u",
|
||||
mParentHandle.c_str(),
|
||||
aTransportId.c_str(),
|
||||
static_cast<unsigned>(aComponentCount));
|
||||
|
||||
std::vector<std::string> attrs;
|
||||
attrs.reserve(aCandidateList.size() + 2 /* ufrag + pwd */);
|
||||
for (const auto& candidate : aCandidateList) {
|
||||
attrs.push_back("candidate:" + candidate);
|
||||
}
|
||||
attrs.push_back("ice-ufrag:" + aUfrag);
|
||||
attrs.push_back("ice-pwd:" + aPassword);
|
||||
std::vector<std::string> attrs;
|
||||
attrs.reserve(aCandidateList.size() + 2 /* ufrag + pwd */);
|
||||
for (const auto& candidate : aCandidateList) {
|
||||
attrs.push_back("candidate:" + candidate);
|
||||
}
|
||||
attrs.push_back("ice-ufrag:" + aUfrag);
|
||||
attrs.push_back("ice-pwd:" + aPassword);
|
||||
|
||||
nsresult rv = stream->ParseAttributes(attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(LOGTAG, "Couldn't parse ICE attributes, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
}
|
||||
nsresult rv = stream->ConnectToPeer(aLocalUfrag, aLocalPwd, attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(LOGTAG, "Couldn't parse ICE attributes, rv=%u",
|
||||
static_cast<unsigned>(rv));
|
||||
}
|
||||
|
||||
for (size_t c = aComponentCount; c < stream->components(); ++c) {
|
||||
// components are 1-indexed
|
||||
stream->DisableComponent(c + 1);
|
||||
}
|
||||
for (size_t c = aComponentCount; c < stream->components(); ++c) {
|
||||
// components are 1-indexed
|
||||
stream->DisableComponent(c + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,9 +467,9 @@ void
|
|||
PeerConnectionMedia::RemoveTransportsExcept_s(
|
||||
const std::set<std::string>& aIds)
|
||||
{
|
||||
for (const auto& stream : mIceCtxHdlr->ctx()->GetStreams()) {
|
||||
for (const auto& stream : mIceCtx->GetStreams()) {
|
||||
if (!aIds.count(stream->GetId())) {
|
||||
mIceCtxHdlr->ctx()->SetStream(stream->GetId(), nullptr);
|
||||
mIceCtx->DestroyStream(stream->GetId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -540,18 +545,6 @@ FinalizeTransportFlow_s(RefPtr<PeerConnectionMedia> aPCMedia,
|
|||
aFlow->PushLayer(aSrtpLayer);
|
||||
}
|
||||
|
||||
static void
|
||||
AddNewIceStreamForRestart_s(RefPtr<PeerConnectionMedia> aPCMedia,
|
||||
RefPtr<TransportFlow> aFlow,
|
||||
const std::string& aTransportId,
|
||||
bool aIsRtcp)
|
||||
{
|
||||
TransportLayerIce* ice =
|
||||
static_cast<TransportLayerIce*>(aFlow->GetLayer("ice"));
|
||||
ice->SetParameters(aPCMedia->ice_media_stream(aTransportId),
|
||||
aIsRtcp ? 2 : 1);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PeerConnectionMedia::UpdateTransportFlow(bool aIsRtcp,
|
||||
const JsepTransport& aTransport)
|
||||
|
@ -572,21 +565,6 @@ PeerConnectionMedia::UpdateTransportFlow(bool aIsRtcp,
|
|||
|
||||
RefPtr<TransportFlow> flow = GetTransportFlow(aTransport.mTransportId, aIsRtcp);
|
||||
if (flow) {
|
||||
if (IsIceRestarting()) {
|
||||
CSFLogInfo(LOGTAG, "Flow[%s]: detected ICE restart - id: %s rtcp: %d",
|
||||
flow->id().c_str(), aTransport.mTransportId.c_str(), aIsRtcp);
|
||||
|
||||
RefPtr<PeerConnectionMedia> pcMedia(this);
|
||||
rv = GetSTSThread()->Dispatch(
|
||||
WrapRunnableNM(AddNewIceStreamForRestart_s,
|
||||
pcMedia, flow, aTransport.mTransportId, aIsRtcp),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(LOGTAG, "Failed to dispatch AddNewIceStreamForRestart_s");
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -707,154 +685,16 @@ PeerConnectionMedia::StartIceChecks_s(
|
|||
}
|
||||
}
|
||||
|
||||
nsresult rv = mIceCtxHdlr->ctx()->ParseGlobalAttributes(attributes);
|
||||
nsresult rv = mIceCtx->ParseGlobalAttributes(attributes);
|
||||
if (NS_FAILED(rv)) {
|
||||
CSFLogError(LOGTAG, "%s: couldn't parse global parameters", __FUNCTION__ );
|
||||
}
|
||||
|
||||
mIceCtxHdlr->ctx()->SetControlling(aIsControlling ?
|
||||
mIceCtx->SetControlling(aIsControlling ?
|
||||
NrIceCtx::ICE_CONTROLLING :
|
||||
NrIceCtx::ICE_CONTROLLED);
|
||||
|
||||
mIceCtxHdlr->ctx()->StartChecks(aIsOfferer);
|
||||
}
|
||||
|
||||
bool
|
||||
PeerConnectionMedia::IsIceRestarting() const
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
return (mIceRestartState != ICE_RESTART_NONE);
|
||||
}
|
||||
|
||||
PeerConnectionMedia::IceRestartState
|
||||
PeerConnectionMedia::GetIceRestartState() const
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
|
||||
return mIceRestartState;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::BeginIceRestart(const std::string& ufrag,
|
||||
const std::string& pwd)
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
if (IsIceRestarting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<NrIceCtx> new_ctx = mIceCtxHdlr->CreateCtx(ufrag, pwd);
|
||||
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::BeginIceRestart_s,
|
||||
new_ctx),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
mIceRestartState = ICE_RESTART_PROVISIONAL;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::BeginIceRestart_s(RefPtr<NrIceCtx> new_ctx)
|
||||
{
|
||||
ASSERT_ON_THREAD(mSTSThread);
|
||||
|
||||
// hold the original context so we can disconnect signals if needed
|
||||
RefPtr<NrIceCtx> originalCtx = mIceCtxHdlr->ctx();
|
||||
|
||||
if (mIceCtxHdlr->BeginIceRestart(new_ctx)) {
|
||||
ConnectSignals(mIceCtxHdlr->ctx().get(), originalCtx.get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::CommitIceRestart()
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
if (mIceRestartState != ICE_RESTART_PROVISIONAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIceRestartState = ICE_RESTART_COMMITTED;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::FinalizeIceRestart()
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
if (!IsIceRestarting()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::FinalizeIceRestart_s),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
mIceRestartState = ICE_RESTART_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::FinalizeIceRestart_s()
|
||||
{
|
||||
ASSERT_ON_THREAD(mSTSThread);
|
||||
|
||||
// reset old streams since we don't need them anymore
|
||||
for (auto& transportFlow : mTransportFlows) {
|
||||
RefPtr<TransportFlow> aFlow = transportFlow.second;
|
||||
if (!aFlow) continue;
|
||||
TransportLayerIce* ice =
|
||||
static_cast<TransportLayerIce*>(aFlow->GetLayer(TransportLayerIce::ID()));
|
||||
ice->ResetOldStream();
|
||||
}
|
||||
|
||||
mIceCtxHdlr->FinalizeIceRestart();
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::RollbackIceRestart()
|
||||
{
|
||||
ASSERT_ON_THREAD(mMainThread);
|
||||
if (mIceRestartState != ICE_RESTART_PROVISIONAL) {
|
||||
return;
|
||||
}
|
||||
|
||||
RUN_ON_THREAD(GetSTSThread(),
|
||||
WrapRunnable(
|
||||
RefPtr<PeerConnectionMedia>(this),
|
||||
&PeerConnectionMedia::RollbackIceRestart_s),
|
||||
NS_DISPATCH_NORMAL);
|
||||
|
||||
mIceRestartState = ICE_RESTART_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
PeerConnectionMedia::RollbackIceRestart_s()
|
||||
{
|
||||
ASSERT_ON_THREAD(mSTSThread);
|
||||
|
||||
// hold the restart context so we can disconnect signals
|
||||
RefPtr<NrIceCtx> restartCtx = mIceCtxHdlr->ctx();
|
||||
|
||||
// restore old streams since we're rolling back
|
||||
for (auto& transportFlow : mTransportFlows) {
|
||||
RefPtr<TransportFlow> aFlow = transportFlow.second;
|
||||
if (!aFlow) continue;
|
||||
TransportLayerIce* ice =
|
||||
static_cast<TransportLayerIce*>(aFlow->GetLayer(TransportLayerIce::ID()));
|
||||
ice->RestoreOldStream();
|
||||
}
|
||||
|
||||
mIceCtxHdlr->RollbackIceRestart();
|
||||
ConnectSignals(mIceCtxHdlr->ctx().get(), restartCtx.get());
|
||||
|
||||
// Fixup the telemetry by transferring abandoned ctx stats to current ctx.
|
||||
NrIceStats stats = restartCtx->Destroy();
|
||||
restartCtx = nullptr;
|
||||
mIceCtxHdlr->ctx()->AccumulateStats(stats);
|
||||
mIceCtx->StartChecks(aIsOfferer);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -926,7 +766,7 @@ PeerConnectionMedia::AddIceCandidate(const std::string& candidate,
|
|||
void
|
||||
PeerConnectionMedia::AddIceCandidate_s(const std::string& aCandidate,
|
||||
const std::string& aTransportId) {
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtxHdlr->ctx()->GetStream(aTransportId));
|
||||
RefPtr<NrIceMediaStream> stream(mIceCtx->GetStream(aTransportId));
|
||||
if (!stream) {
|
||||
CSFLogError(LOGTAG, "No ICE stream for candidate with transport id %s: %s",
|
||||
aTransportId.c_str(), aCandidate.c_str());
|
||||
|
@ -954,7 +794,7 @@ PeerConnectionMedia::UpdateNetworkState(bool online) {
|
|||
|
||||
void
|
||||
PeerConnectionMedia::UpdateNetworkState_s(bool online) {
|
||||
mIceCtxHdlr->ctx()->UpdateNetworkState(online);
|
||||
mIceCtx->UpdateNetworkState(online);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -999,9 +839,9 @@ void
|
|||
PeerConnectionMedia::EnsureIceGathering_s(bool aDefaultRouteOnly,
|
||||
bool aProxyOnly) {
|
||||
if (mProxyServer) {
|
||||
mIceCtxHdlr->ctx()->SetProxyServer(*mProxyServer);
|
||||
mIceCtx->SetProxyServer(*mProxyServer);
|
||||
} else if (aProxyOnly) {
|
||||
IceGatheringStateChange_s(mIceCtxHdlr->ctx().get(),
|
||||
IceGatheringStateChange_s(mIceCtx.get(),
|
||||
NrIceCtx::ICE_CTX_GATHER_COMPLETE);
|
||||
return;
|
||||
}
|
||||
|
@ -1022,15 +862,15 @@ PeerConnectionMedia::EnsureIceGathering_s(bool aDefaultRouteOnly,
|
|||
// needs to have the proper flags set on ice ctx. For non-e10s,
|
||||
// setting those flags happens in StartGathering. We could probably
|
||||
// just set them here, and only do it here.
|
||||
mIceCtxHdlr->ctx()->SetCtxFlags(aDefaultRouteOnly, aProxyOnly);
|
||||
mIceCtx->SetCtxFlags(aDefaultRouteOnly, aProxyOnly);
|
||||
|
||||
if (mStunAddrs.Length()) {
|
||||
mIceCtxHdlr->ctx()->SetStunAddrs(mStunAddrs);
|
||||
mIceCtx->SetStunAddrs(mStunAddrs);
|
||||
}
|
||||
|
||||
// Start gathering, but only if there are streams
|
||||
if (!mIceCtxHdlr->ctx()->GetStreams().empty()) {
|
||||
mIceCtxHdlr->ctx()->StartGathering(aDefaultRouteOnly, aProxyOnly);
|
||||
if (!mIceCtx->GetStreams().empty()) {
|
||||
mIceCtx->StartGathering(aDefaultRouteOnly, aProxyOnly);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1040,7 +880,7 @@ PeerConnectionMedia::EnsureIceGathering_s(bool aDefaultRouteOnly,
|
|||
// If there are no streams, we're probably in a situation where we've rolled
|
||||
// back while still waiting for our proxy configuration to come back. Make
|
||||
// sure content knows that the rollback has stuck wrt gathering.
|
||||
IceGatheringStateChange_s(mIceCtxHdlr->ctx().get(),
|
||||
IceGatheringStateChange_s(mIceCtx.get(),
|
||||
NrIceCtx::ICE_CTX_GATHER_COMPLETE);
|
||||
}
|
||||
|
||||
|
@ -1103,7 +943,7 @@ PeerConnectionMedia::ShutdownMediaTransport_s()
|
|||
mTransportFlows.clear();
|
||||
|
||||
#if !defined(MOZILLA_EXTERNAL_LINKAGE)
|
||||
NrIceStats stats = mIceCtxHdlr->Destroy();
|
||||
NrIceStats stats = mIceCtx->Destroy();
|
||||
|
||||
CSFLogDebug(LOGTAG, "Ice Telemetry: stun (retransmits: %d)"
|
||||
" turn (401s: %d 403s: %d 438s: %d)",
|
||||
|
@ -1120,7 +960,7 @@ PeerConnectionMedia::ShutdownMediaTransport_s()
|
|||
stats.turn_438s);
|
||||
#endif
|
||||
|
||||
mIceCtxHdlr = nullptr;
|
||||
mIceCtx = nullptr;
|
||||
|
||||
// we're holding a ref to 'this' that's released by SelfDestruct_m
|
||||
mMainThread->Dispatch(WrapRunnable(this, &PeerConnectionMedia::SelfDestruct_m),
|
||||
|
@ -1293,7 +1133,7 @@ PeerConnectionMedia::OnCandidateFound_s(NrIceMediaStream *aStream,
|
|||
ASSERT_ON_THREAD(mSTSThread);
|
||||
MOZ_ASSERT(aStream);
|
||||
MOZ_ASSERT(!aStream->GetId().empty());
|
||||
MOZ_RELEASE_ASSERT(mIceCtxHdlr);
|
||||
MOZ_RELEASE_ASSERT(mIceCtx);
|
||||
|
||||
CSFLogDebug(LOGTAG, "%s: %s", __FUNCTION__, aStream->name().c_str());
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ class MediaStreamTrack;
|
|||
}
|
||||
}
|
||||
|
||||
#include "nricectxhandler.h"
|
||||
#include "nriceresolver.h"
|
||||
#include "nricemediastream.h"
|
||||
|
||||
|
@ -50,11 +49,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
public:
|
||||
explicit PeerConnectionMedia(PeerConnectionImpl *parent);
|
||||
|
||||
enum IceRestartState { ICE_RESTART_NONE,
|
||||
ICE_RESTART_PROVISIONAL,
|
||||
ICE_RESTART_COMMITTED
|
||||
};
|
||||
|
||||
PeerConnectionImpl* GetPC() { return mParent; }
|
||||
nsresult Init(const std::vector<NrIceStunServer>& stun_servers,
|
||||
const std::vector<NrIceTurnServer>& turn_servers,
|
||||
|
@ -62,12 +56,11 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
// WARNING: This destroys the object!
|
||||
void SelfDestruct();
|
||||
|
||||
RefPtr<NrIceCtxHandler> ice_ctx_hdlr() const { return mIceCtxHdlr; }
|
||||
RefPtr<NrIceCtx> ice_ctx() const { return mIceCtxHdlr->ctx(); }
|
||||
RefPtr<NrIceCtx> ice_ctx() const { return mIceCtx; }
|
||||
|
||||
RefPtr<NrIceMediaStream> ice_media_stream(
|
||||
const std::string& aTransportId) const {
|
||||
return mIceCtxHdlr->ctx()->GetStream(aTransportId);
|
||||
return mIceCtx->GetStream(aTransportId);
|
||||
}
|
||||
|
||||
// Ensure ICE transports exist that we might need when offer/answer concludes
|
||||
|
@ -81,19 +74,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
// Start ICE checks.
|
||||
void StartIceChecks(const JsepSession& session);
|
||||
|
||||
bool IsIceRestarting() const;
|
||||
IceRestartState GetIceRestartState() const;
|
||||
|
||||
// Begin ICE restart
|
||||
void BeginIceRestart(const std::string& ufrag,
|
||||
const std::string& pwd);
|
||||
// Commit ICE Restart - offer/answer complete, no rollback possible
|
||||
void CommitIceRestart();
|
||||
// Finalize ICE restart
|
||||
void FinalizeIceRestart();
|
||||
// Abort ICE restart
|
||||
void RollbackIceRestart();
|
||||
|
||||
// Process a trickle ICE candidate.
|
||||
void AddIceCandidate(const std::string& candidate,
|
||||
const std::string& aTransportId);
|
||||
|
@ -240,8 +220,12 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
bool aForceIceTcp);
|
||||
|
||||
void EnsureTransport_s(const std::string& aTransportId,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPwd,
|
||||
size_t aComponentCount);
|
||||
void ActivateTransport_s(const std::string& aTransportId,
|
||||
const std::string& aLocalUfrag,
|
||||
const std::string& aLocalPwd,
|
||||
size_t aComponentCount,
|
||||
const std::string& aUfrag,
|
||||
const std::string& aPassword,
|
||||
|
@ -260,9 +244,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
bool aIsIceLite,
|
||||
const std::vector<std::string>& aIceOptionsList);
|
||||
|
||||
void BeginIceRestart_s(RefPtr<NrIceCtx> new_ctx);
|
||||
void FinalizeIceRestart_s();
|
||||
void RollbackIceRestart_s();
|
||||
bool GetPrefDefaultAddressOnly() const;
|
||||
bool GetPrefProxyOnly() const;
|
||||
|
||||
|
@ -319,7 +300,7 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
std::vector<RefPtr<TransceiverImpl>> mTransceivers;
|
||||
|
||||
// ICE objects
|
||||
RefPtr<NrIceCtxHandler> mIceCtxHdlr;
|
||||
RefPtr<NrIceCtx> mIceCtx;
|
||||
|
||||
// DNS
|
||||
RefPtr<NrIceResolver> mDNSResolver;
|
||||
|
@ -354,9 +335,6 @@ class PeerConnectionMedia : public sigslot::has_slots<> {
|
|||
// Used to store the result of the request.
|
||||
UniquePtr<NrIceProxyServer> mProxyServer;
|
||||
|
||||
// Used to track the state of ice restart
|
||||
IceRestartState mIceRestartState;
|
||||
|
||||
// Used to cancel incoming stun addrs response
|
||||
RefPtr<net::StunAddrsRequestChild> mStunAddrsRequest;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче