[Asterisk-code-review] res rtp asterisk: Add ice blacklist option (asterisk[14])

Anonymous Coward asteriskteam at digium.com
Wed Oct 19 14:58:26 CDT 2016


Anonymous Coward #1000019 has submitted this change and it was merged. ( https://gerrit.asterisk.org/4110 )

Change subject: res_rtp_asterisk: Add ice_blacklist option
......................................................................


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
---
M CHANGES
M configs/samples/rtp.conf.sample
M res/res_rtp_asterisk.c
3 files changed, 98 insertions(+), 6 deletions(-)

Approvals:
  Kevin Harwell: Looks good to me, but someone else must approve
  Mark Michelson: Looks good to me, approved
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, but someone else must approve



diff --git a/CHANGES b/CHANGES
index 92b2a90..e8a3168 100644
--- a/CHANGES
+++ b/CHANGES
@@ -71,6 +71,11 @@
    Note: The caller-id and redirecting number strings obtained from incoming
    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
 ------------------
   * Some sounds played into the bridge are played asynchronously. This, for
diff --git a/configs/samples/rtp.conf.sample b/configs/samples/rtp.conf.sample
index 2ef5dd2..fdd1d53 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. 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]
 ;
 ; 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 520fd76..4bf6252 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 *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. */
 static pj_caching_pool cachingpool;
@@ -2446,11 +2450,38 @@
 }
 
 #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,
 				      int transport)
 {
 	pj_sockaddr address[16];
 	unsigned int count = PJ_ARRAY_SIZE(address), pos = 0;
+	int basepos = -1;
 
 	/* Add all the local interface IP addresses */
 	if (ast_sockaddr_is_ipv4(addr)) {
@@ -2464,9 +2495,18 @@
 	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,
+		if (!rtp_address_is_ice_blacklisted(&address[pos])) {
+			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]));
+		}
+	}
+	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 +2515,27 @@
 
 		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 host candidates, don't send the srflx */
+			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));
+			}
 		}
 	}
 
@@ -5393,6 +5445,10 @@
 	turnusername = pj_str(NULL);
 	turnpassword = pj_str(NULL);
 	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
 
 	if (cfg) {
@@ -5502,6 +5558,25 @@
 			AST_RWLIST_INSERT_TAIL(&host_candidates, candidate, next);
 		}
 		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
 		ast_config_destroy(cfg);
 	}

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Ibee88f80d7693874fda1cceaef94a03bd86012c9
Gerrit-PatchSet: 2
Gerrit-Project: asterisk
Gerrit-Branch: 14
Gerrit-Owner: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-Reviewer: Mark Michelson <mmichelson at digium.com>
Gerrit-Reviewer: Michael Walton <mike at farsouthnet.com>



More information about the asterisk-code-review mailing list