[Asterisk-code-review] res rtp asterisk: Manually ported blackice from 11.22 (asterisk[13])

Michael Walton asteriskteam at digium.com
Tue Oct 4 19:02:55 CDT 2016


Michael Walton has uploaded a new change for review.

  https://gerrit.asterisk.org/4023

Change subject: res_rtp_asterisk: Manually ported blackice from 11.22
......................................................................

res_rtp_asterisk: Manually ported blackice from 11.22

Introduces blackice configuration in rtp.conf. Subnets listed in the
form blackice = <subnet spec>, e.g. blackice =
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 blackice
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

Change-Id: Ibee88f80d7693874fda1cceaef94a03bd86012c9
---
M configs/samples/rtp.conf.sample
M res/res_rtp_asterisk.c
2 files changed, 82 insertions(+), 6 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/23/4023/1

diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample
index 2ef5dd2..fce6460 100644
--- a/configs/samples/rtp.conf.sample
+++ b/configs/samples/rtp.conf.sample
@@ -59,6 +59,18 @@
 ; Password used to authenticate with TURN relay server.
 ; 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. blackice = 192.168.1.0/255.255.255.0
+;      blackice = 10.32.77.0/255.255.255.0
+;
+; blackice = 
+;
 [ice_host_candidates]
 ;
 ; When Asterisk is behind a static one-to-one NAT and ICE is in use, ICE will
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 627f800..8530dd8 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -51,6 +51,7 @@
 #include <pjlib.h>
 #include <pjlib-util.h>
 #include <pjnath.h>
+#include <ifaddrs.h>
 #endif
 
 #include "asterisk/stun.h"
@@ -145,6 +146,9 @@
 static int turnport = DEFAULT_TURN_PORT;
 static pj_str_t turnusername;
 static pj_str_t turnpassword;
+static struct ast_ha *blackice = NULL;    /*!< Blacklisted ICE networks */
+static ast_rwlock_t blackice_lock = AST_RWLOCK_INIT_VALUE;
+
 
 /*! \brief Pool factory used by pjlib to allocate memory. */
 static pj_caching_pool cachingpool;
@@ -2451,6 +2455,9 @@
 {
 	pj_sockaddr address[16];
 	unsigned int count = PJ_ARRAY_SIZE(address), pos = 0;
+	struct ast_sockaddr saddr;
+	char buf[PJ_INET6_ADDRSTRLEN];
+	int basepos = -1;
 
 	/* Add all the local interface IP addresses */
 	if (ast_sockaddr_is_ipv4(addr)) {
@@ -2464,9 +2471,24 @@
 	host_candidate_overrides_apply(count, address);
 
 	for (pos = 0; pos < count; 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,
+		ast_sockaddr_parse(&saddr, pj_sockaddr_print(&address[pos], buf, sizeof(buf), 0), 0);
+		/* Remove blacklisted addresses by testing against blackice subnet list */
+		ast_rwlock_rdlock(&blackice_lock);
+		if ((blackice == NULL) || (ast_apply_ha(blackice, &saddr) == AST_SENSE_ALLOW)) {
+			ast_rwlock_unlock(&blackice_lock);
+			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]));
+		} else {
+			ast_rwlock_unlock(&blackice_lock);
+		}
+	}
+	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 */
@@ -2475,15 +2497,34 @@
 
 		if (!ast_stun_request(component == AST_RTP_ICE_COMPONENT_RTCP ? rtp->rtcp->s : rtp->s, &stunaddr, NULL, &answer)) {
 			pj_sockaddr base;
+			pj_sockaddr ext;
 			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 */
-			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,
-					     &base, pj_sockaddr_get_len(&address[0]));
+			/* If the returned address is the same as one of our local candidates, don't send the srflx */
+			for (pos = 0; pos < count; pos++) {
+				if (pj_sockaddr_cmp(&address[pos], &ext) == 0) {
+					ast_sockaddr_parse(&saddr, pj_sockaddr_print(&address[pos], buf, sizeof(buf), 0), 0);
+					ast_rwlock_rdlock(&blackice_lock);
+					if ((blackice == NULL) || (ast_apply_ha(blackice, &saddr) == AST_SENSE_ALLOW)) {
+						ast_rwlock_unlock(&blackice_lock);
+						srflx = 0;
+						break;
+					} else {
+						ast_rwlock_unlock(&blackice_lock);
+					}
+				}
+			}
+
+			if (srflx) {
+				ast_rtp_ice_add_cand(rtp, component, transport, PJ_ICE_CAND_TYPE_SRFLX, 65535, &ext, &base,
+							 &base, pj_sockaddr_get_len(&ext));
+			}
 		}
 	}
 
@@ -5377,6 +5418,10 @@
 	turnusername = pj_str(NULL);
 	turnpassword = pj_str(NULL);
 	host_candidate_overrides_clear();
+	ast_rwlock_wrlock(&blackice_lock);
+	ast_free_ha(blackice);
+	blackice = NULL;
+	ast_rwlock_unlock(&blackice_lock);
 #endif
 
 	if (cfg) {
@@ -5486,6 +5531,25 @@
 			AST_RWLIST_INSERT_TAIL(&host_candidates, candidate, next);
 		}
 		AST_RWLIST_UNLOCK(&host_candidates);
+
+		/* Read blackice configuration lines */
+		ast_rwlock_wrlock(&blackice_lock);
+		for (var = ast_variable_browse(cfg, "general"); var; var = var->next) {
+			if (!strcasecmp(var->name, "blackice")) {
+				struct ast_ha *na;
+				int ha_error = 0;
+				if (!(na = ast_append_ha("d", var->value, blackice, &ha_error))) {
+					ast_log(LOG_WARNING, "Invalid blackice value: %s\n", var->value);
+				} else {
+					blackice = na;
+				}
+				if (ha_error) {
+					ast_log(LOG_ERROR, "Bad blackice configuration value line %d : %s\n", var->lineno, var->value);
+				}
+			}
+		}
+		ast_rwlock_unlock(&blackice_lock);
+
 #endif
 		ast_config_destroy(cfg);
 	}

-- 
To view, visit https://gerrit.asterisk.org/4023
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibee88f80d7693874fda1cceaef94a03bd86012c9
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-Owner: Michael Walton <mike at farsouthnet.com>



More information about the asterisk-code-review mailing list