mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 11:58:55 +00:00
Bug 825708 - Part 2: calculate priority using properties. r=ekr
This commit is contained in:
parent
3f7e613b77
commit
1c89612f08
@ -82,6 +82,7 @@ extern "C" {
|
||||
#include "nricectx.h"
|
||||
#include "nricemediastream.h"
|
||||
#include "nr_socket_prsock.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -368,6 +369,20 @@ RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef USE_INTERFACE_PRIORITIZER
|
||||
nr_interface_prioritizer *prioritizer = CreateInterfacePrioritizer();
|
||||
if (!prioritizer) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Couldn't create interface prioritizer.");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
r = nr_ice_ctx_set_interface_prioritizer(ctx->ctx_, prioritizer);
|
||||
if (r) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Couldn't set interface prioritizer.");
|
||||
return nullptr;
|
||||
}
|
||||
#endif // USE_INTERFACE_PRIORITIZER
|
||||
|
||||
// Create the handler objects
|
||||
ctx->ice_handler_vtbl_ = new nr_ice_handler_vtbl();
|
||||
ctx->ice_handler_vtbl_->select_pair = &NrIceCtx::select_pair;
|
||||
|
189
media/mtransport/nrinterfaceprioritizer.cpp
Normal file
189
media/mtransport/nrinterfaceprioritizer.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include "logging.h"
|
||||
#include "nrinterfaceprioritizer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
MOZ_MTLOG_MODULE("mtransport")
|
||||
|
||||
namespace {
|
||||
|
||||
class LocalAddress {
|
||||
public:
|
||||
LocalAddress()
|
||||
: key_(),
|
||||
is_vpn_(-1),
|
||||
estimated_speed_(-1),
|
||||
type_preference_(-1) {}
|
||||
|
||||
bool Init(const nr_local_addr& local_addr) {
|
||||
char buf[MAXIFNAME + 41];
|
||||
int r = nr_transport_addr_fmt_ifname_addr_string(&local_addr.addr, buf, sizeof(buf));
|
||||
if (r) {
|
||||
MOZ_MTLOG(PR_LOG_ERROR, "Error formatting interface address string.");
|
||||
return false;
|
||||
}
|
||||
key_ = buf;
|
||||
is_vpn_ = (local_addr.interface.type & NR_INTERFACE_TYPE_VPN) != 0 ? 1 : 0;
|
||||
estimated_speed_ = local_addr.interface.estimated_speed;
|
||||
type_preference_ = GetNetworkTypePreference(local_addr.interface.type);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator<(const LocalAddress& rhs) const {
|
||||
// Interface that is "less" here is preferred.
|
||||
// If type preferences are different, we should simply sort by
|
||||
// |type_preference_|.
|
||||
if (type_preference_ != rhs.type_preference_) {
|
||||
return type_preference_ < rhs.type_preference_;
|
||||
}
|
||||
|
||||
// If type preferences are the same, the next thing we use to sort is vpn.
|
||||
// If two LocalAddress are different in |is_vpn_|, the LocalAddress that is
|
||||
// not in vpn gets priority.
|
||||
if (is_vpn_ != rhs.is_vpn_) {
|
||||
return is_vpn_ < rhs.is_vpn_;
|
||||
}
|
||||
|
||||
// Compare estimated speed.
|
||||
if (estimated_speed_ != rhs.estimated_speed_) {
|
||||
return estimated_speed_ > rhs.estimated_speed_;
|
||||
}
|
||||
|
||||
// All things above are the same, we can at least sort with key.
|
||||
return key_ < rhs.key_;
|
||||
}
|
||||
|
||||
const std::string& GetKey() const {
|
||||
return key_;
|
||||
}
|
||||
|
||||
private:
|
||||
// Getting the preference corresponding to a type. Getting lower number here
|
||||
// means the type of network is preferred.
|
||||
static inline int GetNetworkTypePreference(int type) {
|
||||
if (type & NR_INTERFACE_TYPE_WIRED) {
|
||||
return 1;
|
||||
}
|
||||
if (type & NR_INTERFACE_TYPE_WIFI) {
|
||||
return 2;
|
||||
}
|
||||
if (type & NR_INTERFACE_TYPE_MOBILE) {
|
||||
return 3;
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
|
||||
std::string key_;
|
||||
int is_vpn_;
|
||||
int estimated_speed_;
|
||||
int type_preference_;
|
||||
};
|
||||
|
||||
class InterfacePrioritizer {
|
||||
public:
|
||||
InterfacePrioritizer()
|
||||
: local_addrs_(),
|
||||
preference_map_(),
|
||||
sorted_(false) {}
|
||||
|
||||
int add(const nr_local_addr *iface) {
|
||||
LocalAddress addr;
|
||||
if (!addr.Init(*iface)) {
|
||||
return R_FAILED;
|
||||
}
|
||||
std::pair<std::set<LocalAddress>::iterator, bool> r =
|
||||
local_addrs_.insert(addr);
|
||||
if (!r.second) {
|
||||
return R_ALREADY; // This address is already in the set.
|
||||
}
|
||||
sorted_ = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sort() {
|
||||
UCHAR tmp_pref = 127;
|
||||
preference_map_.clear();
|
||||
for (std::set<LocalAddress>::iterator i = local_addrs_.begin();
|
||||
i != local_addrs_.end(); ++i) {
|
||||
if (tmp_pref == 0) {
|
||||
return R_FAILED;
|
||||
}
|
||||
preference_map_.insert(make_pair(i->GetKey(), tmp_pref--));
|
||||
}
|
||||
sorted_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getPreference(const char *key, UCHAR *pref) {
|
||||
if (!sorted_) {
|
||||
return R_FAILED;
|
||||
}
|
||||
std::map<std::string, UCHAR>::iterator i = preference_map_.find(key);
|
||||
if (i == preference_map_.end()) {
|
||||
return R_NOT_FOUND;
|
||||
}
|
||||
*pref = i->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<LocalAddress> local_addrs_;
|
||||
std::map<std::string, UCHAR> preference_map_;
|
||||
bool sorted_;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
static int add_interface(void *obj, nr_local_addr *iface) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->add(iface);
|
||||
}
|
||||
|
||||
static int get_priority(void *obj, const char *key, UCHAR *pref) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->getPreference(key, pref);
|
||||
}
|
||||
|
||||
static int sort_preference(void *obj) {
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(obj);
|
||||
return ip->sort();
|
||||
}
|
||||
|
||||
static int destroy(void **objp) {
|
||||
if (!objp || !*objp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
InterfacePrioritizer *ip = static_cast<InterfacePrioritizer*>(*objp);
|
||||
*objp = 0;
|
||||
delete ip;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static nr_interface_prioritizer_vtbl priorizer_vtbl = {
|
||||
add_interface,
|
||||
get_priority,
|
||||
sort_preference,
|
||||
destroy
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nr_interface_prioritizer* CreateInterfacePrioritizer() {
|
||||
nr_interface_prioritizer *ip;
|
||||
int r = nr_interface_prioritizer_create_int(new InterfacePrioritizer(),
|
||||
&priorizer_vtbl,
|
||||
&ip);
|
||||
if (r != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
18
media/mtransport/nrinterfaceprioritizer.h
Normal file
18
media/mtransport/nrinterfaceprioritizer.h
Normal file
@ -0,0 +1,18 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef nrinterfacepriority_h__
|
||||
#define nrinterfacepriority_h__
|
||||
|
||||
extern "C" {
|
||||
#include "nr_api.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
nr_interface_prioritizer* CreateInterfacePrioritizer();
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -40,7 +40,7 @@ LOCAL_INCLUDES += \
|
||||
-I$(topsrcdir)/media/mtransport/third_party/nrappkit/src/port/linux/include \
|
||||
-I$(topsrcdir)/media/mtransport/third_party/nrappkit/src/port/generic/include \
|
||||
$(NULL)
|
||||
DEFINES += -DLINUX
|
||||
DEFINES += -DLINUX -DUSE_INTERFACE_PRIORITIZER
|
||||
endif
|
||||
|
||||
ifeq ($(OS_TARGET), Android)
|
||||
@ -71,6 +71,7 @@ MTRANSPORT_LCPPSRCS = \
|
||||
nricemediastream.cpp \
|
||||
nriceresolverfake.cpp \
|
||||
nriceresolver.cpp \
|
||||
nrinterfaceprioritizer.cpp \
|
||||
nr_socket_prsock.cpp \
|
||||
nr_timer.cpp \
|
||||
transportflow.cpp \
|
||||
@ -86,6 +87,7 @@ ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
|
||||
MTRANSPORT_LCPPSRCS += \
|
||||
gonk_addrs.cpp \
|
||||
$(NULL)
|
||||
DEFINES += -DUSE_INTERFACE_PRIORITIZER
|
||||
endif
|
||||
|
||||
MTRANSPORT_CPPSRCS = $(addprefix $(topsrcdir)/media/mtransport/, $(MTRANSPORT_LCPPSRCS))
|
||||
|
2
media/mtransport/third_party/nICEr/nicer.gyp
vendored
2
media/mtransport/third_party/nICEr/nicer.gyp
vendored
@ -78,6 +78,8 @@
|
||||
"./src/net/transport_addr_reg.h",
|
||||
"./src/net/local_addr.c",
|
||||
"./src/net/local_addr.h",
|
||||
"./src/net/nr_interface_prioritizer.c",
|
||||
"./src/net/nr_interface_prioritizer.h",
|
||||
|
||||
# STUN
|
||||
"./src/stun/addrs.c",
|
||||
|
@ -358,23 +358,37 @@ int nr_ice_candidate_compute_priority(nr_ice_candidate *cand)
|
||||
if(type_preference > 126)
|
||||
r_log(LOG_ICE,LOG_ERR,"Illegal type preference %d",type_preference);
|
||||
|
||||
|
||||
if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,
|
||||
&interface_preference)) {
|
||||
if (r==R_NOT_FOUND) {
|
||||
if (next_automatic_preference == 1) {
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname);
|
||||
ABORT(R_NOT_FOUND);
|
||||
if(!cand->ctx->interface_prioritizer) {
|
||||
/* Prioritizer is not set, read from registry */
|
||||
if(r=NR_reg_get2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,
|
||||
&interface_preference)) {
|
||||
if (r==R_NOT_FOUND) {
|
||||
if (next_automatic_preference == 1) {
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Out of preference values. Can't assign one for interface %s",cand->base.ifname);
|
||||
ABORT(R_NOT_FOUND);
|
||||
}
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname,
|
||||
next_automatic_preference);
|
||||
if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
|
||||
ABORT(r);
|
||||
}
|
||||
interface_preference=next_automatic_preference;
|
||||
next_automatic_preference--;
|
||||
}
|
||||
r_log(LOG_ICE,LOG_DEBUG,"Automatically assigning preference for interface %s->%d",cand->base.ifname,
|
||||
next_automatic_preference);
|
||||
if (r=NR_reg_set2_uchar(NR_ICE_REG_PREF_INTERFACE_PRFX,cand->base.ifname,next_automatic_preference)){
|
||||
else {
|
||||
ABORT(r);
|
||||
}
|
||||
interface_preference=next_automatic_preference;
|
||||
next_automatic_preference--;
|
||||
}
|
||||
else {
|
||||
}
|
||||
else {
|
||||
char key_of_interface[MAXIFNAME + 41];
|
||||
|
||||
if(r=nr_transport_addr_fmt_ifname_addr_string(&cand->base,key_of_interface,
|
||||
sizeof(key_of_interface))) {
|
||||
ABORT(r);
|
||||
}
|
||||
if(r=nr_interface_prioritizer_get_priority(cand->ctx->interface_prioritizer,
|
||||
key_of_interface,&interface_preference)) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
@ -170,31 +170,24 @@ int nr_ice_component_destroy(nr_ice_component **componentp)
|
||||
return(0);
|
||||
}
|
||||
|
||||
#define MAXADDRS 100 // Ridiculously high
|
||||
/* Make all the candidates we can make at the beginning */
|
||||
int nr_ice_component_initialize(struct nr_ice_ctx_ *ctx,nr_ice_component *component)
|
||||
{
|
||||
int r,_status;
|
||||
nr_local_addr addrs[MAXADDRS];
|
||||
nr_local_addr *addrs=ctx->local_addrs;
|
||||
nr_socket *sock;
|
||||
nr_ice_socket *isock=0;
|
||||
nr_ice_candidate *cand=0;
|
||||
char *lufrag;
|
||||
char *lpwd;
|
||||
Data pwd;
|
||||
int addr_ct;
|
||||
int addr_ct=ctx->local_addr_ct;
|
||||
int i;
|
||||
int j;
|
||||
char label[256];
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): initializing component with id %d",ctx->label,component->component_id);
|
||||
|
||||
/* First, gather all the local addresses we have */
|
||||
if(r=nr_stun_find_local_addresses(addrs,MAXADDRS,&addr_ct)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
if(addr_ct==0){
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): no local addresses available",ctx->label);
|
||||
ABORT(R_NOT_FOUND);
|
||||
|
@ -156,6 +156,33 @@ int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers,int
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_local_addrs(nr_ice_ctx *ctx,nr_local_addr *addrs,int ct)
|
||||
{
|
||||
int _status,i,r;
|
||||
|
||||
if(ctx->local_addrs) {
|
||||
RFREE(ctx->local_addrs);
|
||||
ctx->local_addr_ct=0;
|
||||
ctx->local_addrs=0;
|
||||
}
|
||||
|
||||
if (ct) {
|
||||
if(!(ctx->local_addrs=RCALLOC(sizeof(nr_local_addr)*ct)))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
for (i=0;i<ct;++i) {
|
||||
if (r=nr_local_addr_copy(ctx->local_addrs+i,addrs+i)) {
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
ctx->local_addr_ct = ct;
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
|
||||
{
|
||||
int _status;
|
||||
@ -171,6 +198,20 @@ int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver)
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *ip)
|
||||
{
|
||||
int _status;
|
||||
|
||||
if (ctx->interface_prioritizer) {
|
||||
ABORT(R_ALREADY);
|
||||
}
|
||||
|
||||
ctx->interface_prioritizer = ip;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
#ifdef USE_TURN
|
||||
int nr_ice_fetch_turn_servers(int ct, nr_ice_turn_server **out)
|
||||
@ -301,6 +342,9 @@ int nr_ice_ctx_create(char *label, UINT4 flags, nr_ice_ctx **ctxp)
|
||||
ctx->turn_server_ct=0;
|
||||
#endif /* USE_TURN */
|
||||
|
||||
ctx->local_addrs=0;
|
||||
ctx->local_addr_ct=0;
|
||||
|
||||
/* 255 is the max for our priority algorithm */
|
||||
if((ctx->stun_server_ct+ctx->turn_server_ct)>255){
|
||||
r_log(LOG_ICE,LOG_WARNING,"Too many STUN/TURN servers specified: max=255");
|
||||
@ -348,6 +392,8 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||
|
||||
RFREE(ctx->stun_servers);
|
||||
|
||||
RFREE(ctx->local_addrs);
|
||||
|
||||
for (i = 0; i < ctx->turn_server_ct; i++) {
|
||||
RFREE(ctx->turn_servers[i].username);
|
||||
r_data_destroy(&ctx->turn_servers[i].password);
|
||||
@ -374,6 +420,7 @@ static void nr_ice_ctx_destroy_cb(NR_SOCKET s, int how, void *cb_arg)
|
||||
}
|
||||
|
||||
nr_resolver_destroy(&ctx->resolver);
|
||||
nr_interface_prioritizer_destroy(&ctx->interface_prioritizer);
|
||||
|
||||
RFREE(ctx);
|
||||
}
|
||||
@ -416,10 +463,13 @@ void nr_ice_initialize_finished_cb(NR_SOCKET s, int h, void *cb_arg)
|
||||
}
|
||||
}
|
||||
|
||||
#define MAXADDRS 100 // Ridiculously high
|
||||
int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
|
||||
{
|
||||
int r,_status;
|
||||
nr_ice_media_stream *stream;
|
||||
nr_local_addr addrs[MAXADDRS];
|
||||
int i,addr_ct;
|
||||
|
||||
r_log(LOG_ICE,LOG_DEBUG,"ICE(%s): Initializing candidates",ctx->label);
|
||||
ctx->state=NR_ICE_STATE_INITIALIZING;
|
||||
@ -431,6 +481,30 @@ int nr_ice_initialize(nr_ice_ctx *ctx, NR_async_cb done_cb, void *cb_arg)
|
||||
ABORT(R_BAD_ARGS);
|
||||
}
|
||||
|
||||
/* First, gather all the local addresses we have */
|
||||
if(r=nr_stun_find_local_addresses(addrs,MAXADDRS,&addr_ct)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to find local addresses",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* Sort interfaces by preference */
|
||||
if(ctx->interface_prioritizer) {
|
||||
for(i=0;i<addr_ct;i++){
|
||||
if(r=nr_interface_prioritizer_add_interface(ctx->interface_prioritizer,addrs+i)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to add interface ",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
if(r=nr_interface_prioritizer_sort_preference(ctx->interface_prioritizer)) {
|
||||
r_log(LOG_ICE,LOG_ERR,"ICE(%s): unable to sort interface by preference",ctx->label);
|
||||
ABORT(r);
|
||||
}
|
||||
}
|
||||
|
||||
if (r=nr_ice_ctx_set_local_addrs(ctx,addrs,addr_ct)) {
|
||||
ABORT(r);
|
||||
}
|
||||
|
||||
/* Initialize all the media stream/component pairs */
|
||||
stream=STAILQ_FIRST(&ctx->streams);
|
||||
while(stream){
|
||||
|
@ -43,6 +43,7 @@ extern "C" {
|
||||
#include "transport_addr.h"
|
||||
#include "nr_socket.h"
|
||||
#include "nr_resolver.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
#include "stun_client_ctx.h"
|
||||
#include "stun_server_ctx.h"
|
||||
#include "turn_client_ctx.h"
|
||||
@ -122,8 +123,11 @@ struct nr_ice_ctx_ {
|
||||
int stun_server_ct;
|
||||
nr_ice_turn_server *turn_servers; /* The list of turn servers */
|
||||
int turn_server_ct;
|
||||
nr_local_addr *local_addrs; /* The list of available local addresses and corresponding interface information */
|
||||
int local_addr_ct;
|
||||
|
||||
nr_resolver *resolver; /* The resolver to use */
|
||||
nr_interface_prioritizer *interface_prioritizer; /* Priority decision logic */
|
||||
|
||||
nr_ice_foundation_head foundations;
|
||||
|
||||
@ -161,6 +165,7 @@ int nr_ice_ctx_finalize(nr_ice_ctx *ctx, nr_ice_peer_ctx *pctx);
|
||||
int nr_ice_ctx_set_stun_servers(nr_ice_ctx *ctx,nr_ice_stun_server *servers, int ct);
|
||||
int nr_ice_ctx_set_turn_servers(nr_ice_ctx *ctx,nr_ice_turn_server *servers, int ct);
|
||||
int nr_ice_ctx_set_resolver(nr_ice_ctx *ctx, nr_resolver *resolver);
|
||||
int nr_ice_ctx_set_interface_prioritizer(nr_ice_ctx *ctx, nr_interface_prioritizer *prioritizer);
|
||||
|
||||
extern int LOG_ICE;
|
||||
|
||||
|
88
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.c
vendored
Normal file
88
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.c
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "nr_api.h"
|
||||
#include "nr_interface_prioritizer.h"
|
||||
#include "transport_addr.h"
|
||||
|
||||
int nr_interface_prioritizer_create_int(void *obj,
|
||||
nr_interface_prioritizer_vtbl *vtbl,nr_interface_prioritizer **ifpp)
|
||||
{
|
||||
int _status;
|
||||
nr_interface_prioritizer *ifp=0;
|
||||
|
||||
if(!(ifp=RCALLOC(sizeof(nr_interface_prioritizer))))
|
||||
ABORT(R_NO_MEMORY);
|
||||
|
||||
ifp->obj = obj;
|
||||
ifp->vtbl = vtbl;
|
||||
|
||||
*ifpp = ifp;
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_destroy(nr_interface_prioritizer **ifpp)
|
||||
{
|
||||
nr_interface_prioritizer *ifp;
|
||||
|
||||
if (!ifpp || !*ifpp)
|
||||
return(0);
|
||||
|
||||
ifp = *ifpp;
|
||||
*ifpp = 0;
|
||||
ifp->vtbl->destroy(&ifp->obj);
|
||||
RFREE(ifp);
|
||||
return(0);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_add_interface(nr_interface_prioritizer *ifp,
|
||||
nr_local_addr *addr)
|
||||
{
|
||||
return ifp->vtbl->add_interface(ifp->obj, addr);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_get_priority(nr_interface_prioritizer *ifp,
|
||||
const char *key, UCHAR *interface_preference)
|
||||
{
|
||||
return ifp->vtbl->get_priority(ifp->obj,key,interface_preference);
|
||||
}
|
||||
|
||||
int nr_interface_prioritizer_sort_preference(nr_interface_prioritizer *ifp)
|
||||
{
|
||||
return ifp->vtbl->sort_preference(ifp->obj);
|
||||
}
|
66
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.h
vendored
Normal file
66
media/mtransport/third_party/nICEr/src/net/nr_interface_prioritizer.h
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (c) 2007, Adobe Systems, Incorporated
|
||||
Copyright (c) 2013, Mozilla
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of Adobe Systems, Network Resonance, Mozilla nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _nr_interface_prioritizer
|
||||
#define _nr_interface_prioritizer
|
||||
|
||||
#include "transport_addr.h"
|
||||
#include "local_addr.h"
|
||||
|
||||
typedef struct nr_interface_prioritizer_vtbl_ {
|
||||
int (*add_interface)(void *obj, nr_local_addr *iface);
|
||||
int (*get_priority)(void *obj, const char *key, UCHAR *pref);
|
||||
int (*sort_preference)(void *obj);
|
||||
int (*destroy)(void **obj);
|
||||
} nr_interface_prioritizer_vtbl;
|
||||
|
||||
typedef struct nr_interface_prioritizer_ {
|
||||
void *obj;
|
||||
nr_interface_prioritizer_vtbl *vtbl;
|
||||
} nr_interface_prioritizer;
|
||||
|
||||
int nr_interface_prioritizer_create_int(void *obj, nr_interface_prioritizer_vtbl *vtbl,
|
||||
nr_interface_prioritizer **prioritizer);
|
||||
|
||||
int nr_interface_prioritizer_destroy(nr_interface_prioritizer **prioritizer);
|
||||
|
||||
int nr_interface_prioritizer_add_interface(nr_interface_prioritizer *prioritizer,
|
||||
nr_local_addr *addr);
|
||||
|
||||
int nr_interface_prioritizer_get_priority(nr_interface_prioritizer *prioritizer,
|
||||
const char *key, UCHAR *interface_preference);
|
||||
|
||||
int nr_interface_prioritizer_sort_preference(nr_interface_prioritizer *prioritizer);
|
||||
#endif
|
@ -78,6 +78,27 @@ int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr)
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len)
|
||||
{
|
||||
int _status;
|
||||
char buffer[40];
|
||||
|
||||
switch(addr->ip_version){
|
||||
case NR_IPV4:
|
||||
if (!inet_ntop(AF_INET, &addr->u.addr4.sin_addr,buffer,sizeof(buffer))) {
|
||||
strncpy(buffer, "[error]", len);
|
||||
}
|
||||
snprintf(buf,len,"%s:%s",addr->ifname,buffer);
|
||||
break;
|
||||
default:
|
||||
ABORT(R_INTERNAL);
|
||||
}
|
||||
|
||||
_status=0;
|
||||
abort:
|
||||
return(_status);
|
||||
}
|
||||
|
||||
int nr_sockaddr_to_transport_addr(struct sockaddr *saddr, int saddr_len, int protocol, int keep, nr_transport_addr *addr)
|
||||
{
|
||||
int r,_status;
|
||||
|
@ -91,6 +91,7 @@ int nr_transport_addr_is_loopback(nr_transport_addr *addr);
|
||||
int nr_transport_addr_copy(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_copy_keep_ifname(nr_transport_addr *to, nr_transport_addr *from);
|
||||
int nr_transport_addr_fmt_addr_string(nr_transport_addr *addr);
|
||||
int nr_transport_addr_fmt_ifname_addr_string(const nr_transport_addr *addr, char *buf, int len);
|
||||
int nr_transport_addr_set_port(nr_transport_addr *addr, int port);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user