[Asterisk-code-review] res pjsip: Add utility functions to convert between socket s... (asterisk[13])

Sean Bright asteriskteam at digium.com
Tue Aug 28 12:23:00 CDT 2018


Sean Bright has uploaded this change for review. ( https://gerrit.asterisk.org/10013


Change subject: res_pjsip: Add utility functions to convert between socket structures
......................................................................

res_pjsip: Add utility functions to convert between socket structures

Currently, to convert from a pj_sockaddr to an ast_sockaddr, the address
needs to be rendered to a string and then parsed into the correct
structure. This also involves a call to getaddrinfo(3). The same is true
for the inverse operation.

Instead, because we know the internal structure of both ast_sockaddr and
pj_sockaddr, we can translate directly between the two without the
need for an intermediate string.

Change-Id: If0fc4bba9643f755604c6ffbb0d7cc46020bc761
---
M include/asterisk/res_pjsip.h
M res/res_pjsip.c
2 files changed, 181 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/13/10013/1

diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 17282d6..1adbd7f 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -3211,4 +3211,28 @@
  */
 void ast_sip_transport_state_unregister(struct ast_sip_tpmgr_state_callback *element);
 
+/*!
+ * \brief Fill a pj_sockaddr from an ast_sockaddr
+ * \since 13.23.0
+ *
+ * \param addr The source address to copy
+ * \param pjaddr The target address to receive the copied address
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sockaddr_to_pj_sockaddr(const struct ast_sockaddr *addr, pj_sockaddr *pjaddr);
+
+/*!
+ * \brief Fill an ast_sockaddr from a pj_sockaddr
+ * \since 13.23.0
+ *
+ * \param addr The target address to receive the copied address
+ * \param pjaddr The source address to copy
+ *
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sockaddr_from_pj_sockaddr(struct ast_sockaddr *addr, const pj_sockaddr *pjaddr);
+
 #endif /* _RES_PJSIP_H */
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index ece03d3..50e1e18 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -4759,6 +4759,50 @@
 	return ast_threadpool_queue_size(sip_threadpool);
 }
 
+int ast_sockaddr_to_pj_sockaddr(const struct ast_sockaddr *addr, pj_sockaddr *pjaddr)
+{
+	memset(pjaddr, 0, sizeof(*pjaddr));
+	if (addr->ss.ss_family == AF_INET) {
+		struct sockaddr_in *sin = (struct sockaddr_in *) &addr->ss;
+		pjaddr->ipv4.sin_family = pj_AF_INET();
+		pjaddr->ipv4.sin_addr   = sin->sin_addr;
+		pjaddr->ipv4.sin_port   = sin->sin_port;
+	} else if (addr->ss.ss_family == AF_INET6) {
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *) &addr->ss;
+		pjaddr->ipv6.sin6_family   = pj_AF_INET6();
+		pjaddr->ipv6.sin6_port     = sin->sin6_port;
+		pjaddr->ipv6.sin6_flowinfo = sin->sin6_flowinfo;
+		pjaddr->ipv6.sin6_scope_id = sin->sin6_scope_id;
+		memcpy(&pjaddr->ipv6.sin6_addr, &sin->sin6_addr, sizeof(pjaddr->ipv6.sin6_addr));
+	} else {
+		return -1;
+	}
+	return 0;
+}
+
+int ast_sockaddr_from_pj_sockaddr(struct ast_sockaddr *addr, const pj_sockaddr *pjaddr)
+{
+	memset(addr, 0, sizeof(*addr));
+	if (pjaddr->addr.sa_family == pj_AF_INET()) {
+		struct sockaddr_in *sin = (struct sockaddr_in *) &addr->ss;
+		sin->sin_family = AF_INET;
+		sin->sin_addr   = pjaddr->ipv4.sin_addr;
+		sin->sin_port   = pjaddr->ipv4.sin_port;
+		addr->len = sizeof(struct sockaddr_in);
+	} else if (pjaddr->addr.sa_family == pj_AF_INET6()) {
+		struct sockaddr_in6 *sin = (struct sockaddr_in6 *) &addr->ss;
+		sin->sin6_family   = AF_INET6;
+		sin->sin6_port     = pjaddr->ipv6.sin6_port;
+		sin->sin6_flowinfo = pjaddr->ipv6.sin6_flowinfo;
+		sin->sin6_scope_id = pjaddr->ipv6.sin6_scope_id;
+		memcpy(&sin->sin6_addr, &pjaddr->ipv6.sin6_addr, sizeof(sin->sin6_addr));
+		addr->len = sizeof(struct sockaddr_in6);
+	} else {
+		return -1;
+	}
+	return 0;
+}
+
 #ifdef TEST_FRAMEWORK
 AST_TEST_DEFINE(xml_sanitization_end_null)
 {
@@ -4810,6 +4854,115 @@
 
 	return AST_TEST_PASS;
 }
+
+AST_TEST_DEFINE(ast_sockaddr_to_pj_sockaddr_test)
+{
+	char *candidates[] = {
+		"127.0.0.1:5555",
+		"[::]:4444",
+		"192.168.0.100:0",
+		"[fec0::1:80]:0",
+		"[fec0::1]:80",
+		NULL,
+	}, **candidate = candidates;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "ast_sockaddr_to_pj_sockaddr_test";
+		info->category = "/res/res_pjsip/";
+		info->summary = "Validate conversions from an ast_sockaddr to a pj_sockaddr";
+		info->description = "This test converts an ast_sockaddr to a pj_sockaddr and validates\n"
+			"that the two evaluate to the same string when formatted.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	while (*candidate) {
+		struct ast_sockaddr addr = {{0,}};
+		pj_sockaddr pjaddr;
+		char buffer[512];
+
+		if (!ast_sockaddr_parse(&addr, *candidate, 0)) {
+			ast_test_status_update(test, "Failed to parse candidate IP: %s\n", *candidate);
+			return AST_TEST_FAIL;
+		}
+
+		if (ast_sockaddr_to_pj_sockaddr(&addr, &pjaddr)) {
+			ast_test_status_update(test, "Failed to convert ast_sockaddr to pj_sockaddr: %s\n", *candidate);
+			return AST_TEST_FAIL;
+		}
+
+		pj_sockaddr_print(&pjaddr, buffer, sizeof(buffer), 1 | 2);
+
+		if (strcmp(*candidate, buffer)) {
+			ast_test_status_update(test, "Converted sockaddrs do not match: \"%s\" and \"%s\"\n",
+				*candidate,
+				buffer);
+			return AST_TEST_FAIL;
+		}
+
+		candidate++;
+	}
+
+	return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(ast_sockaddr_from_pj_sockaddr_test)
+{
+	char *candidates[] = {
+		"127.0.0.1:5555",
+		"[::]:4444",
+		"192.168.0.100:0",
+		"[fec0::1:80]:0",
+		"[fec0::1]:80",
+		NULL,
+	}, **candidate = candidates;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "ast_sockaddr_from_pj_sockaddr_test";
+		info->category = "/res/res_pjsip/";
+		info->summary = "Validate conversions from a pj_sockaddr to an ast_sockaddr";
+		info->description = "This test converts a pj_sockaddr to an ast_sockaddr and validates\n"
+			"that the two evaluate to the same string when formatted.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	while (*candidate) {
+		struct ast_sockaddr addr = {{0,}};
+		pj_sockaddr pjaddr;
+		pj_str_t t;
+		char buffer[512];
+
+		pj_strset(&t, *candidate, strlen(*candidate));
+
+		if (pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &t, &pjaddr) != PJ_SUCCESS) {
+			ast_test_status_update(test, "Failed to parse candidate IP: %s\n", *candidate);
+			return AST_TEST_FAIL;
+		}
+
+		if (ast_sockaddr_from_pj_sockaddr(&addr, &pjaddr)) {
+			ast_test_status_update(test, "Failed to convert pj_sockaddr to ast_sockaddr: %s\n", *candidate);
+			return AST_TEST_FAIL;
+		}
+
+		snprintf(buffer, sizeof(buffer), "%s", ast_sockaddr_stringify(&addr));
+
+		if (strcmp(*candidate, buffer)) {
+			ast_test_status_update(test, "Converted sockaddrs do not match: \"%s\" and \"%s\"\n",
+				*candidate,
+				buffer);
+			return AST_TEST_FAIL;
+		}
+
+		candidate++;
+	}
+
+	return AST_TEST_PASS;
+}
 #endif
 
 /*!
@@ -5046,6 +5199,8 @@
 
 	AST_TEST_REGISTER(xml_sanitization_end_null);
 	AST_TEST_REGISTER(xml_sanitization_exceeds_buffer);
+	AST_TEST_REGISTER(ast_sockaddr_to_pj_sockaddr_test);
+	AST_TEST_REGISTER(ast_sockaddr_from_pj_sockaddr_test);
 
 	ast_pjproject_ref();
 
@@ -5080,6 +5235,8 @@
 {
 	AST_TEST_UNREGISTER(xml_sanitization_end_null);
 	AST_TEST_UNREGISTER(xml_sanitization_exceeds_buffer);
+	AST_TEST_UNREGISTER(ast_sockaddr_to_pj_sockaddr_test);
+	AST_TEST_UNREGISTER(ast_sockaddr_from_pj_sockaddr_test);
 	ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
 
 	/* The thread this is called from cannot call PJSIP/PJLIB functions,

-- 
To view, visit https://gerrit.asterisk.org/10013
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-MessageType: newchange
Gerrit-Change-Id: If0fc4bba9643f755604c6ffbb0d7cc46020bc761
Gerrit-Change-Number: 10013
Gerrit-PatchSet: 1
Gerrit-Owner: Sean Bright <sean.bright at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20180828/032f85d7/attachment-0001.html>


More information about the asterisk-code-review mailing list