mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-02 02:18:31 +00:00
res_rtp_asterisk: Add ice_blacklist option
Introduces ice_blacklist configuration in rtp.conf. Subnets listed in the form ice_blacklist = <subnet spec>, e.g. ice_blacklist = 192.168.1.0/255.255.255.0, are excluded from ICE host, srflx and relay discovery. This is useful for optimizing the ICE process where a system has multiple host address ranges and/or physical interfaces and certain of them are not expected to be used for RTP. Multiple ice_blacklist configuration lines may be used. If left unconfigured, all discovered host addresses are used, as per previous behavior. Documention in rtp.conf.sample. ASTERISK-26418 #close Change-Id: Ibee88f80d7693874fda1cceaef94a03bd86012c9
This commit is contained in:
committed by
Joshua Colp
parent
6adc293b14
commit
3c62b60e56
5
CHANGES
5
CHANGES
@@ -71,6 +71,11 @@ res_pjsip
|
|||||||
Note: The caller-id and redirecting number strings obtained from incoming
|
Note: The caller-id and redirecting number strings obtained from incoming
|
||||||
SIP URI user fields are now always truncated at the first semicolon.
|
SIP URI user fields are now always truncated at the first semicolon.
|
||||||
|
|
||||||
|
res_rtp_asterisk
|
||||||
|
------------------
|
||||||
|
* An option, ice_blacklist, has been added which allows certain subnets to be
|
||||||
|
excluded from local ICE candidates.
|
||||||
|
|
||||||
app_confbridge
|
app_confbridge
|
||||||
------------------
|
------------------
|
||||||
* Some sounds played into the bridge are played asynchronously. This, for
|
* Some sounds played into the bridge are played asynchronously. This, for
|
||||||
|
@@ -59,6 +59,18 @@ rtpend=20000
|
|||||||
; Password used to authenticate with TURN relay server.
|
; Password used to authenticate with TURN relay server.
|
||||||
; turnpassword=
|
; turnpassword=
|
||||||
;
|
;
|
||||||
|
; Subnets to exclude from ICE host, srflx and relay discovery. This is useful
|
||||||
|
; to optimize the ICE process where a system has multiple host address ranges
|
||||||
|
; and/or physical interfaces and certain of them are not expected to be used
|
||||||
|
; for RTP. For example, VPNs and local interconnections may not be suitable or
|
||||||
|
; necessary for ICE. Multiple subnets may be listed. If left unconfigured,
|
||||||
|
; all discovered host addresses are used.
|
||||||
|
;
|
||||||
|
; e.g. ice_blacklist = 192.168.1.0/255.255.255.0
|
||||||
|
; ice_blacklist = 10.32.77.0/255.255.255.0
|
||||||
|
;
|
||||||
|
; ice_blacklist =
|
||||||
|
;
|
||||||
[ice_host_candidates]
|
[ice_host_candidates]
|
||||||
;
|
;
|
||||||
; When Asterisk is behind a static one-to-one NAT and ICE is in use, ICE will
|
; When Asterisk is behind a static one-to-one NAT and ICE is in use, ICE will
|
||||||
|
@@ -51,6 +51,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||||||
#include <pjlib.h>
|
#include <pjlib.h>
|
||||||
#include <pjlib-util.h>
|
#include <pjlib-util.h>
|
||||||
#include <pjnath.h>
|
#include <pjnath.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "asterisk/stun.h"
|
#include "asterisk/stun.h"
|
||||||
@@ -145,6 +146,9 @@ static pj_str_t turnaddr;
|
|||||||
static int turnport = DEFAULT_TURN_PORT;
|
static int turnport = DEFAULT_TURN_PORT;
|
||||||
static pj_str_t turnusername;
|
static pj_str_t turnusername;
|
||||||
static pj_str_t turnpassword;
|
static pj_str_t turnpassword;
|
||||||
|
static struct ast_ha *ice_blacklist = NULL; /*!< Blacklisted ICE networks */
|
||||||
|
static ast_rwlock_t ice_blacklist_lock = AST_RWLOCK_INIT_VALUE;
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Pool factory used by pjlib to allocate memory. */
|
/*! \brief Pool factory used by pjlib to allocate memory. */
|
||||||
static pj_caching_pool cachingpool;
|
static pj_caching_pool cachingpool;
|
||||||
@@ -2446,11 +2450,38 @@ static int rtp_learning_rtp_seq_update(struct rtp_learning_info *info, uint16_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_PJPROJECT
|
#ifdef HAVE_PJPROJECT
|
||||||
|
/*!
|
||||||
|
* \internal
|
||||||
|
* \brief Checks an address against the ICE blacklist
|
||||||
|
* \note If there is no ice_blacklist list, always returns 0
|
||||||
|
*
|
||||||
|
* \param address The address to consider
|
||||||
|
* \retval 0 if address is not ICE blacklisted
|
||||||
|
* \retval 1 if address is ICE blacklisted
|
||||||
|
*/
|
||||||
|
static int rtp_address_is_ice_blacklisted(const pj_sockaddr_t *address)
|
||||||
|
{
|
||||||
|
char buf[PJ_INET6_ADDRSTRLEN];
|
||||||
|
struct ast_sockaddr saddr;
|
||||||
|
int result = 1;
|
||||||
|
|
||||||
|
ast_sockaddr_parse(&saddr, pj_sockaddr_print(address, buf, sizeof(buf), 0), 0);
|
||||||
|
|
||||||
|
ast_rwlock_rdlock(&ice_blacklist_lock);
|
||||||
|
if (!ice_blacklist || (ast_apply_ha(ice_blacklist, &saddr) == AST_SENSE_ALLOW)) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
ast_rwlock_unlock(&ice_blacklist_lock);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *addr, int port, int component,
|
static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *addr, int port, int component,
|
||||||
int transport)
|
int transport)
|
||||||
{
|
{
|
||||||
pj_sockaddr address[16];
|
pj_sockaddr address[16];
|
||||||
unsigned int count = PJ_ARRAY_SIZE(address), pos = 0;
|
unsigned int count = PJ_ARRAY_SIZE(address), pos = 0;
|
||||||
|
int basepos = -1;
|
||||||
|
|
||||||
/* Add all the local interface IP addresses */
|
/* Add all the local interface IP addresses */
|
||||||
if (ast_sockaddr_is_ipv4(addr)) {
|
if (ast_sockaddr_is_ipv4(addr)) {
|
||||||
@@ -2464,9 +2495,18 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
|
|||||||
host_candidate_overrides_apply(count, address);
|
host_candidate_overrides_apply(count, address);
|
||||||
|
|
||||||
for (pos = 0; pos < count; pos++) {
|
for (pos = 0; pos < count; pos++) {
|
||||||
pj_sockaddr_set_port(&address[pos], port);
|
if (!rtp_address_is_ice_blacklisted(&address[pos])) {
|
||||||
ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_HOST, 65535, &address[pos], &address[pos], NULL,
|
if (basepos == -1) {
|
||||||
|
basepos = pos;
|
||||||
|
}
|
||||||
|
pj_sockaddr_set_port(&address[pos], port);
|
||||||
|
ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_HOST, 65535, &address[pos], &address[pos], NULL,
|
||||||
pj_sockaddr_get_len(&address[pos]));
|
pj_sockaddr_get_len(&address[pos]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (basepos == -1) {
|
||||||
|
/* start with first address unless excluded above */
|
||||||
|
basepos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If configured to use a STUN server to get our external mapped address do so */
|
/* If configured to use a STUN server to get our external mapped address do so */
|
||||||
@@ -2475,15 +2515,27 @@ static void rtp_add_candidates_to_ice(struct ast_rtp_instance *instance, struct
|
|||||||
|
|
||||||
if (!ast_stun_request(component == AST_RTP_ICE_COMPONENT_RTCP ? rtp->rtcp->s : rtp->s, &stunaddr, NULL, &answer)) {
|
if (!ast_stun_request(component == AST_RTP_ICE_COMPONENT_RTCP ? rtp->rtcp->s : rtp->s, &stunaddr, NULL, &answer)) {
|
||||||
pj_sockaddr base;
|
pj_sockaddr base;
|
||||||
|
pj_sockaddr ext;
|
||||||
pj_str_t mapped = pj_str(ast_strdupa(ast_inet_ntoa(answer.sin_addr)));
|
pj_str_t mapped = pj_str(ast_strdupa(ast_inet_ntoa(answer.sin_addr)));
|
||||||
|
int srflx = 1;
|
||||||
|
|
||||||
/* Use the first local host candidate as the base */
|
/* Use the first local host candidate as the base */
|
||||||
pj_sockaddr_cp(&base, &address[0]);
|
pj_sockaddr_cp(&base, &address[basepos]);
|
||||||
|
|
||||||
pj_sockaddr_init(pj_AF_INET(), &address[0], &mapped, ntohs(answer.sin_port));
|
pj_sockaddr_init(pj_AF_INET(), &ext, &mapped, ntohs(answer.sin_port));
|
||||||
|
|
||||||
ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_SRFLX, 65535, &address[0], &base,
|
/* If the returned address is the same as one of our host candidates, don't send the srflx */
|
||||||
&base, pj_sockaddr_get_len(&address[0]));
|
for (pos = 0; pos < count; pos++) {
|
||||||
|
if ((pj_sockaddr_cmp(&address[pos], &ext) == 0) && !rtp_address_is_ice_blacklisted(&address[pos])) {
|
||||||
|
srflx = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (srflx) {
|
||||||
|
ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_SRFLX, 65535, &ext, &base,
|
||||||
|
&base, pj_sockaddr_get_len(&ext));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5394,6 +5446,10 @@ static int rtp_reload(int reload)
|
|||||||
turnusername = pj_str(NULL);
|
turnusername = pj_str(NULL);
|
||||||
turnpassword = pj_str(NULL);
|
turnpassword = pj_str(NULL);
|
||||||
host_candidate_overrides_clear();
|
host_candidate_overrides_clear();
|
||||||
|
ast_rwlock_wrlock(&ice_blacklist_lock);
|
||||||
|
ast_free_ha(ice_blacklist);
|
||||||
|
ice_blacklist = NULL;
|
||||||
|
ast_rwlock_unlock(&ice_blacklist_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cfg) {
|
if (cfg) {
|
||||||
@@ -5503,6 +5559,25 @@ static int rtp_reload(int reload)
|
|||||||
AST_RWLIST_INSERT_TAIL(&host_candidates, candidate, next);
|
AST_RWLIST_INSERT_TAIL(&host_candidates, candidate, next);
|
||||||
}
|
}
|
||||||
AST_RWLIST_UNLOCK(&host_candidates);
|
AST_RWLIST_UNLOCK(&host_candidates);
|
||||||
|
|
||||||
|
/* Read ICE blacklist configuration lines */
|
||||||
|
ast_rwlock_wrlock(&ice_blacklist_lock);
|
||||||
|
for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
|
||||||
|
if (!strcasecmp(var->name, "ice_blacklist")) {
|
||||||
|
struct ast_ha *na;
|
||||||
|
int ha_error = 0;
|
||||||
|
if (!(na = ast_append_ha("d", var->value, ice_blacklist, &ha_error))) {
|
||||||
|
ast_log(LOG_WARNING, "Invalid ice_blacklist value: %s\n", var->value);
|
||||||
|
} else {
|
||||||
|
ice_blacklist = na;
|
||||||
|
}
|
||||||
|
if (ha_error) {
|
||||||
|
ast_log(LOG_ERROR, "Bad ice_blacklist configuration value line %d : %s\n", var->lineno, var->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast_rwlock_unlock(&ice_blacklist_lock);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
ast_config_destroy(cfg);
|
ast_config_destroy(cfg);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user