[Asterisk-code-review] res pjsip endpoint identifier ip: Add support for SRV lookups. (asterisk[14])

Joshua Colp asteriskteam at digium.com
Thu Jan 5 09:33:18 CST 2017


Joshua Colp has uploaded a new change for review. ( https://gerrit.asterisk.org/4698 )

Change subject: res_pjsip_endpoint_identifier_ip: Add support for SRV lookups.
......................................................................

res_pjsip_endpoint_identifier_ip: Add support for SRV lookups.

This change implements SRV support for the IP based endpoint
identifier module. All possible addresses through SRV are looked
up and added as matches. If no SRV records are available a
fallback to normal host resolution is done. If an IP address
is provided then no SRV lookup occurs.

ASTERISK-26693

Change-Id: I6b641e275bf96629320efa8b479737062aed82ac
---
M CHANGES
M res/res_pjsip_endpoint_identifier_ip.c
2 files changed, 85 insertions(+), 22 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/98/4698/1

diff --git a/CHANGES b/CHANGES
index 7419ff3..8b9ff24 100644
--- a/CHANGES
+++ b/CHANGES
@@ -44,6 +44,11 @@
    ID, AuthenticateQualify, OutboundProxy, Path, QualifyFrequency and
    QualifyTimeout.  Existing fields have not been disturbed.
 
+res_pjsip_endpoint_identifier_ip
+------------------
+ * SRV lookups will now be done on provided hostnames to determine additional
+   source IP addresses for requests.
+
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 14.1.0 to Asterisk 14.2.0 ------------
 ------------------------------------------------------------------------------
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index 7a7af0b..2d79da0 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -153,6 +153,69 @@
 	.identify_endpoint = ip_identify,
 };
 
+/*! \brief Helper function which performs a host lookup and adds result to identify match */
+static int ip_identify_match_host_lookup(struct ip_identify_match *identify, const char *host)
+{
+	struct ast_sockaddr *addrs;
+	int num_addrs = 0, error = 0, i;
+	int results = 0;
+
+	num_addrs = ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC);
+	if (!num_addrs) {
+		return -1;
+	}
+
+	for (i = 0; i < num_addrs; ++i) {
+		/* Check if the address is already in the list, if so don't bother adding it again */
+		if (identify->matches && (ast_apply_ha(identify->matches, &addrs[i]) != AST_SENSE_ALLOW)) {
+			continue;
+		}
+
+		/* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
+		identify->matches = ast_append_ha("d", ast_sockaddr_stringify_addr(&addrs[i]), identify->matches, &error);
+
+		if (!identify->matches || error) {
+			results = -1;
+			break;
+		}
+
+		results += 1;
+	}
+
+	ast_free(addrs);
+
+	return results;
+}
+
+/*! \brief Helper function which performs an SRV lookup and then resolves the hostname */
+static int ip_identify_match_srv_lookup(struct ip_identify_match *identify, const char *prefix, const char *host)
+{
+	char service[NI_MAXHOST];
+	struct srv_context *context = NULL;
+	int srv_ret;
+	const char *srvhost;
+	unsigned short srvport;
+	int results = 0;
+
+	snprintf(service, sizeof(service), "%s.%s", prefix, host);
+
+	while (!(srv_ret = ast_srv_lookup(&context, service, &srvhost, &srvport))) {
+		int hosts;
+
+		/* In the case of the SRV lookup we don't care if it fails, we will output a log message
+		 * when we fallback to a normal lookup.
+		 */
+		hosts = ip_identify_match_host_lookup(identify, srvhost);
+		if (hosts) {
+			hosts += results;
+		}
+	}
+
+	ast_srv_cleanup(&context);
+
+	return results;
+}
+
 /*! \brief Custom handler for match field */
 static int ip_identify_match_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
 {
@@ -165,9 +228,9 @@
 	}
 
 	while ((current_string = ast_strip(strsep(&input_string, ",")))) {
-		struct ast_sockaddr *addrs;
-		int num_addrs = 0, error = 0, i;
 		char *mask = strrchr(current_string, '/');
+		struct ast_sockaddr address;
+		int error, results = 0;
 
 		if (ast_strlen_zero(current_string)) {
 			continue;
@@ -185,29 +248,24 @@
 			continue;
 		}
 
-		num_addrs = ast_sockaddr_resolve(&addrs, current_string, PARSE_PORT_FORBID, AST_AF_UNSPEC);
-		if (!num_addrs) {
-			ast_log(LOG_ERROR, "Address '%s' provided on ip endpoint identifier '%s' did not resolve to any address\n",
-				var->value, ast_sorcery_object_get_id(obj));
-			return -1;
+		/* If the provided string is not an IP address perform SRV resolution on it */
+		if (!ast_sockaddr_parse(&address, current_string, 0)) {
+			results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string);
+			results += ip_identify_match_srv_lookup(identify, "_sip._tcp", current_string);
+			results += ip_identify_match_srv_lookup(identify, "_sips._tcp", current_string);
 		}
 
-		for (i = 0; i < num_addrs; ++i) {
-			/* We deny what we actually want to match because there is an implicit permit all rule for ACLs */
-			identify->matches = ast_append_ha("d", ast_sockaddr_stringify_addr(&addrs[i]), identify->matches, &error);
-
-			if (!identify->matches || error) {
-				ast_log(LOG_ERROR, "Failed to add address '%s' to ip endpoint identifier '%s'\n",
-					ast_sockaddr_stringify_addr(&addrs[i]), ast_sorcery_object_get_id(obj));
-				error = -1;
-				break;
+		/* If SRV falls fall back to a normal lookup on the host itself */
+		if (!results) {
+			results = ip_identify_match_host_lookup(identify, current_string);
+			if (results == 0) {
+				ast_log(LOG_ERROR, "Address '%s' provided on ip endpoint identifier '%s' did not resolve to any address\n",
+					current_string, ast_sorcery_object_get_id(obj));
+			} else if (results == -1) {
+				ast_log(LOG_ERROR, "An error occurred when adding resolution results of '%s' on '%s'\n",
+					current_string, ast_sorcery_object_get_id(obj));
+				return -1;
 			}
-		}
-
-		ast_free(addrs);
-
-		if (error) {
-			return -1;
 		}
 	}
 

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I6b641e275bf96629320efa8b479737062aed82ac
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: 14
Gerrit-Owner: Joshua Colp <jcolp at digium.com>



More information about the asterisk-code-review mailing list