[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