mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 909179 - Add ability to disable ICE components r=abr
This commit is contained in:
parent
1073f298a1
commit
a4d6a811cc
@ -197,6 +197,7 @@ nsresult NrIceMediaStream::ParseTrickleCandidate(const std::string& candidate) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Returns NS_ERROR_NOT_AVAILABLE if component is unpaired or disabled.
|
||||
nsresult NrIceMediaStream::GetActivePair(int component,
|
||||
NrIceCandidate **localp,
|
||||
NrIceCandidate **remotep) {
|
||||
@ -208,6 +209,10 @@ nsresult NrIceMediaStream::GetActivePair(int component,
|
||||
stream_,
|
||||
component,
|
||||
&local_int, &remote_int);
|
||||
// If result is R_REJECTED then component is unpaired or disabled.
|
||||
if (r == R_REJECTED)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
if (r)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
@ -304,6 +309,21 @@ std::vector<std::string> NrIceMediaStream::GetCandidates() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::DisableComponent(int component_id) {
|
||||
if (!stream_)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
int r = nr_ice_media_stream_disable_component(stream_,
|
||||
component_id);
|
||||
if (r) {
|
||||
MOZ_MTLOG(ML_ERROR, "Couldn't disable '" << name_ << "':" <<
|
||||
component_id);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NrIceMediaStream::SendPacket(int component_id,
|
||||
const unsigned char *data,
|
||||
size_t len) {
|
||||
|
@ -104,6 +104,9 @@ class NrIceMediaStream {
|
||||
// Parse trickle ICE candidate
|
||||
nsresult ParseTrickleCandidate(const std::string& candidate);
|
||||
|
||||
// Disable a component
|
||||
nsresult DisableComponent(int component);
|
||||
|
||||
// Get the candidate pair currently active. It's the
|
||||
// caller's responsibility to free these.
|
||||
nsresult GetActivePair(int component,
|
||||
|
@ -168,10 +168,16 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
return ice_ctx_->GetGlobalAttributes();
|
||||
}
|
||||
|
||||
std::vector<std::string> GetCandidates(const std::string &name) {
|
||||
std::vector<std::string> candidates_in = candidates_[name];
|
||||
std::vector<std::string> GetCandidates(size_t stream) {
|
||||
std::vector<std::string> candidates;
|
||||
|
||||
if (stream >= streams_.size())
|
||||
return candidates;
|
||||
|
||||
std::vector<std::string> candidates_in =
|
||||
streams_[stream]->GetCandidates();
|
||||
|
||||
|
||||
for (size_t i=0; i < candidates_in.size(); i++) {
|
||||
if ((!candidate_filter_) || candidate_filter_(candidates_in[i])) {
|
||||
std::cerr << "Returning candidate: " << candidates_in[i] << std::endl;
|
||||
@ -213,7 +219,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
for (size_t i=0; i<streams_.size(); ++i) {
|
||||
test_utils->sts_target()->Dispatch(
|
||||
WrapRunnableRet(streams_[i], &NrIceMediaStream::ParseAttributes,
|
||||
remote->GetCandidates(remote->streams_[i]->name()),
|
||||
remote->GetCandidates(i),
|
||||
&res), NS_DISPATCH_SYNC);
|
||||
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
@ -249,7 +255,7 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
ASSERT_GT(remote_->streams_.size(), stream);
|
||||
|
||||
std::vector<std::string> candidates =
|
||||
remote_->GetCandidates(remote_->streams_[stream]->name());
|
||||
remote_->GetCandidates(stream);
|
||||
|
||||
for (size_t j=0; j<candidates.size(); j++) {
|
||||
test_utils->sts_target()->Dispatch(
|
||||
@ -302,13 +308,17 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
NrIceCandidate *remote;
|
||||
|
||||
nsresult res = streams_[i]->GetActivePair(j+1, &local, &remote);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
DumpCandidate("Local ", *local);
|
||||
ASSERT_EQ(expected_local_type_, local->type);
|
||||
DumpCandidate("Remote ", *remote);
|
||||
ASSERT_EQ(expected_remote_type_, remote->type);
|
||||
delete local;
|
||||
delete remote;
|
||||
if (res == NS_ERROR_NOT_AVAILABLE) {
|
||||
std::cerr << "Component unpaired or disabled." << std::endl;
|
||||
} else {
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
DumpCandidate("Local ", *local);
|
||||
ASSERT_EQ(expected_local_type_, local->type);
|
||||
DumpCandidate("Remote ", *remote);
|
||||
ASSERT_EQ(expected_remote_type_, remote->type);
|
||||
delete local;
|
||||
delete remote;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -379,6 +389,12 @@ class IceTestPeer : public sigslot::has_slots<> {
|
||||
streams_[i]->ParseAttributes(attributes);
|
||||
}
|
||||
|
||||
void DisableComponent(int stream, int component_id) {
|
||||
ASSERT_LT(stream, streams_.size());
|
||||
nsresult res = streams_[stream]->DisableComponent(component_id);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(res));
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
nsRefPtr<NrIceCtx> ice_ctx_;
|
||||
@ -661,6 +677,21 @@ TEST_F(IceGatherTest, TestGatherTurn) {
|
||||
Gather();
|
||||
}
|
||||
|
||||
TEST_F(IceGatherTest, TestGatherDisableComponent) {
|
||||
peer_->SetStunServer(kDefaultStunServerHostname, kDefaultStunServerPort);
|
||||
peer_->AddStream(2);
|
||||
peer_->DisableComponent(1, 2);
|
||||
Gather();
|
||||
std::vector<std::string> candidates =
|
||||
peer_->GetCandidates(1);
|
||||
|
||||
for (size_t i=0; i<candidates.size(); ++i) {
|
||||
size_t sp1 = candidates[i].find(' ');
|
||||
ASSERT_EQ(0, candidates[i].compare(sp1+1, 1, "1", 1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Verify that a bogus candidate doesn't cause crashes on the
|
||||
// main thread. See bug 856433.
|
||||
TEST_F(IceGatherTest, TestBogusCandidate) {
|
||||
@ -686,6 +717,21 @@ TEST_F(IceConnectTest, TestConnect) {
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTwoComponents) {
|
||||
AddStream("first", 2);
|
||||
ASSERT_TRUE(Gather(true));
|
||||
Connect();
|
||||
}
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectTwoComponentsDisableSecond) {
|
||||
AddStream("first", 2);
|
||||
ASSERT_TRUE(Gather(true));
|
||||
p1_->DisableComponent(0, 2);
|
||||
p2_->DisableComponent(0, 2);
|
||||
Connect();
|
||||
}
|
||||
|
||||
|
||||
TEST_F(IceConnectTest, TestConnectP2ThenP1) {
|
||||
AddStream("first", 1);
|
||||
ASSERT_TRUE(Gather(true));
|
||||
|
@ -415,6 +415,9 @@ static int nr_ice_component_process_incoming_check(nr_ice_component *comp, nr_tr
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE-PEER(%s)/STREAM(%s)(%d): received request from %s",comp->stream->pctx->label,comp->stream->label,comp->component_id,req->src_addr.as_string);
|
||||
|
||||
if (comp->state == NR_ICE_COMPONENT_DISABLED)
|
||||
ABORT(R_REJECTED);
|
||||
|
||||
/* Check for role conficts (7.2.1.1) */
|
||||
if(comp->stream->pctx->controlling){
|
||||
if(nr_stun_message_has_attribute(sreq,NR_STUN_ATTR_ICE_CONTROLLING,&attr)){
|
||||
|
@ -55,6 +55,7 @@ struct nr_ice_component_ {
|
||||
#define NR_ICE_COMPONENT_RUNNING 1
|
||||
#define NR_ICE_COMPONENT_NOMINATED 2
|
||||
#define NR_ICE_COMPONENT_FAILED 3
|
||||
#define NR_ICE_COMPONENT_DISABLED 4
|
||||
struct nr_ice_ctx_ *ctx;
|
||||
struct nr_ice_media_stream_ *stream;
|
||||
nr_ice_component *local_component;
|
||||
|
@ -155,10 +155,12 @@ int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attr
|
||||
/* First find out how many attributes we need */
|
||||
comp=STAILQ_FIRST(&stream->components);
|
||||
while(comp){
|
||||
if(r=nr_ice_component_prune_candidates(stream->ctx,comp))
|
||||
ABORT(r);
|
||||
if (comp->state != NR_ICE_COMPONENT_DISABLED) {
|
||||
if(r=nr_ice_component_prune_candidates(stream->ctx,comp))
|
||||
ABORT(r);
|
||||
|
||||
attrct+=comp->candidate_ct;
|
||||
attrct+=comp->candidate_ct;
|
||||
}
|
||||
|
||||
comp=STAILQ_NEXT(comp,entry);
|
||||
}
|
||||
@ -180,18 +182,20 @@ int nr_ice_media_stream_get_attributes(nr_ice_media_stream *stream, char ***attr
|
||||
/* Now format the attributes */
|
||||
comp=STAILQ_FIRST(&stream->components);
|
||||
while(comp){
|
||||
nr_ice_candidate *cand;
|
||||
if (comp->state != NR_ICE_COMPONENT_DISABLED) {
|
||||
nr_ice_candidate *cand;
|
||||
|
||||
cand=TAILQ_FIRST(&comp->candidates);
|
||||
while(cand){
|
||||
assert(index < attrct);
|
||||
cand=TAILQ_FIRST(&comp->candidates);
|
||||
while(cand){
|
||||
assert(index < attrct);
|
||||
|
||||
if(r=nr_ice_format_candidate_attribute(cand, attrs[index],MAX_ATTRIBUTE_SIZE))
|
||||
ABORT(r);
|
||||
if(r=nr_ice_format_candidate_attribute(cand, attrs[index],MAX_ATTRIBUTE_SIZE))
|
||||
ABORT(r);
|
||||
|
||||
index++;
|
||||
index++;
|
||||
|
||||
cand=TAILQ_NEXT(cand,entry_comp);
|
||||
cand=TAILQ_NEXT(cand,entry_comp);
|
||||
}
|
||||
}
|
||||
comp=STAILQ_NEXT(comp,entry);
|
||||
}
|
||||
@ -274,8 +278,11 @@ int nr_ice_media_stream_pair_candidates(nr_ice_peer_ctx *pctx,nr_ice_media_strea
|
||||
pcomp=STAILQ_FIRST(&pstream->components);
|
||||
lcomp=STAILQ_FIRST(&lstream->components);
|
||||
while(pcomp){
|
||||
if(r=nr_ice_component_pair_candidates(pctx,lcomp,pcomp))
|
||||
ABORT(r);
|
||||
if ((lcomp->state != NR_ICE_COMPONENT_DISABLED) &&
|
||||
(pcomp->state != NR_ICE_COMPONENT_DISABLED)) {
|
||||
if(r=nr_ice_component_pair_candidates(pctx,lcomp,pcomp))
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
lcomp=STAILQ_NEXT(lcomp,entry);
|
||||
pcomp=STAILQ_NEXT(pcomp,entry);
|
||||
@ -567,7 +574,9 @@ int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_c
|
||||
|
||||
comp=STAILQ_FIRST(&stream->components);
|
||||
while(comp){
|
||||
if(!comp->nominated)
|
||||
if((comp->state != NR_ICE_COMPONENT_DISABLED) &&
|
||||
(comp->local_component->state != NR_ICE_COMPONENT_DISABLED) &&
|
||||
!comp->nominated)
|
||||
break;
|
||||
|
||||
comp=STAILQ_NEXT(comp,entry);
|
||||
@ -578,7 +587,7 @@ int nr_ice_media_stream_component_nominated(nr_ice_media_stream *stream,nr_ice_c
|
||||
goto done;
|
||||
|
||||
/* All done... */
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/ICE-STREAM(%s): all components have nominated candidate pairs",stream->pctx->label,stream->label);
|
||||
r_log(LOG_ICE,LOG_INFO,"ICE-PEER(%s)/ICE-STREAM(%s): all active components have nominated candidate pairs",stream->pctx->label,stream->label);
|
||||
nr_ice_media_stream_set_state(stream,NR_ICE_MEDIA_STREAM_CHECKS_COMPLETED);
|
||||
|
||||
/* Cancel our timer */
|
||||
@ -724,6 +733,7 @@ int nr_ice_media_stream_send(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, in
|
||||
return(_status);
|
||||
}
|
||||
|
||||
/* Returns R_REJECTED if the component is unpaired or has been disabled. */
|
||||
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)
|
||||
{
|
||||
int r,_status;
|
||||
@ -733,6 +743,10 @@ int nr_ice_media_stream_get_active(nr_ice_peer_ctx *pctx, nr_ice_media_stream *s
|
||||
if(r=nr_ice_peer_ctx_find_component(pctx, str, component, &comp))
|
||||
ABORT(r);
|
||||
|
||||
if (comp->state == NR_ICE_COMPONENT_UNPAIRED ||
|
||||
comp->state == NR_ICE_COMPONENT_DISABLED)
|
||||
ABORT(R_REJECTED);
|
||||
|
||||
if(!comp->active)
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
||||
@ -797,3 +811,26 @@ int nr_ice_media_stream_finalize(nr_ice_media_stream *lstr,nr_ice_media_stream *
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int nr_ice_media_stream_disable_component(nr_ice_media_stream *stream, int component_id)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_component *comp;
|
||||
|
||||
if (stream->ice_state != NR_ICE_MEDIA_STREAM_UNPAIRED)
|
||||
ABORT(R_FAILED);
|
||||
|
||||
if ((r=nr_ice_media_stream_find_component(stream, component_id, &comp)))
|
||||
ABORT(r);
|
||||
|
||||
/* Can only disable before pairing */
|
||||
if (comp->state != NR_ICE_COMPONENT_UNPAIRED)
|
||||
ABORT(R_FAILED);
|
||||
|
||||
comp->state = NR_ICE_COMPONENT_DISABLED;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,7 @@ int nr_ice_media_stream_find_component(nr_ice_media_stream *str, int comp_id, nr
|
||||
int nr_ice_media_stream_addrs(nr_ice_peer_ctx *pctx, nr_ice_media_stream *str, int component, nr_transport_addr *local, nr_transport_addr *remote);
|
||||
int
|
||||
nr_ice_peer_ctx_parse_media_stream_attribute(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *attr);
|
||||
int nr_ice_media_stream_disable_component(nr_ice_media_stream *stream, int component_id);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -208,6 +208,15 @@ static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream
|
||||
ABORT(R_BAD_DATA);
|
||||
}
|
||||
|
||||
if (comp->state == NR_ICE_COMPONENT_DISABLED) {
|
||||
r_log(LOG_ICE,LOG_ERR,"Peer offered candidates for disabled remote component");
|
||||
ABORT(R_BAD_DATA);
|
||||
}
|
||||
if (comp->local_component->state == NR_ICE_COMPONENT_DISABLED) {
|
||||
r_log(LOG_ICE,LOG_ERR,"Peer offered candidates for disabled local component");
|
||||
ABORT(R_BAD_DATA);
|
||||
}
|
||||
|
||||
cand->component=comp;
|
||||
|
||||
TAILQ_INSERT_TAIL(&comp->candidates,cand,entry_comp);
|
||||
@ -220,7 +229,31 @@ static int nr_ice_ctx_parse_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream
|
||||
return(_status);
|
||||
}
|
||||
|
||||
static int nr_ice_peer_ctx_find_pstream(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, nr_ice_media_stream **pstreamp)
|
||||
{
|
||||
int _status;
|
||||
nr_ice_media_stream *pstream;
|
||||
|
||||
/* Because we don't have forward pointers, iterate through all the
|
||||
peer streams to find one that matches us */
|
||||
pstream=STAILQ_FIRST(&pctx->peer_streams);
|
||||
while(pstream) {
|
||||
if (pstream->local_stream == stream)
|
||||
break;
|
||||
|
||||
pstream = STAILQ_NEXT(pstream, entry);
|
||||
}
|
||||
if (!pstream) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): peer (%s) has no stream matching stream %s",pctx->ctx->label,pctx->label,stream->label);
|
||||
ABORT(R_NOT_FOUND);
|
||||
}
|
||||
|
||||
*pstreamp = pstream;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_peer_ctx_parse_trickle_candidate(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream, char *candidate)
|
||||
{
|
||||
@ -326,6 +359,31 @@ int nr_ice_peer_ctx_pair_candidates(nr_ice_peer_ctx *pctx)
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_peer_ctx_disable_component(nr_ice_peer_ctx *pctx, nr_ice_media_stream *lstream, int component_id)
|
||||
{
|
||||
int r, _status;
|
||||
nr_ice_media_stream *pstream;
|
||||
nr_ice_component *component;
|
||||
int j;
|
||||
|
||||
if ((r=nr_ice_peer_ctx_find_pstream(pctx, lstream, &pstream)))
|
||||
ABORT(r);
|
||||
|
||||
/* We shouldn't be calling this after we have started pairing */
|
||||
if (pstream->ice_state != NR_ICE_MEDIA_STREAM_UNPAIRED)
|
||||
ABORT(R_FAILED);
|
||||
|
||||
if ((r=nr_ice_media_stream_find_component(pstream, component_id,
|
||||
&component)))
|
||||
ABORT(r);
|
||||
|
||||
component->state = NR_ICE_COMPONENT_DISABLED;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
static void nr_ice_peer_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||
{
|
||||
nr_ice_peer_ctx *pctx=cb_arg;
|
||||
|
@ -78,6 +78,8 @@ int nr_ice_peer_ctx_log_state(nr_ice_peer_ctx *pctx);
|
||||
int nr_ice_peer_ctx_stream_done(nr_ice_peer_ctx *pctx, nr_ice_media_stream *stream);
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
Loading…
Reference in New Issue
Block a user