<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/10045">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins2: Verified
Richard Mudgett: Looks good to me, but someone else must approve
Michael L. Young: Looks good to me, but someone else must approve
Kevin Harwell: Looks good to me, approved
Joshua Colp: Approved for Submit
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjproject: Add utility functions to convert between socket structures<br><br>Currently, to convert from a pj_sockaddr to an ast_sockaddr, the address<br>needs to be rendered to a string and then parsed into the correct<br>structure. This also involves a call to getaddrinfo(3). The same is true<br>for the inverse operation.<br><br>Instead, because we know the internal structure of both ast_sockaddr and<br>pj_sockaddr, we can translate directly between the two without the<br>need for an intermediate string.<br><br>Change-Id: If0fc4bba9643f755604c6ffbb0d7cc46020bc761<br>---<br>M include/asterisk/res_pjproject.h<br>M res/res_pjproject.c<br>M res/res_pjproject.exports.in<br>3 files changed, 205 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/asterisk/res_pjproject.h b/include/asterisk/res_pjproject.h</span><br><span>index 17ebdd2..d195c0f 100644</span><br><span>--- a/include/asterisk/res_pjproject.h</span><br><span>+++ b/include/asterisk/res_pjproject.h</span><br><span>@@ -22,6 +22,8 @@</span><br><span> #include <pj/types.h></span><br><span> #include <pj/pool.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_sockaddr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*!</span><br><span> * \brief Retrieve a pjproject build option</span><br><span> *</span><br><span>@@ -97,4 +99,28 @@</span><br><span> */</span><br><span> void ast_pjproject_caching_pool_destroy(pj_caching_pool *cp);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Fill a pj_sockaddr from an ast_sockaddr</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.24.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param addr The source address to copy</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param pjaddr The target address to receive the copied address</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 Success</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 Failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sockaddr_to_pj_sockaddr(const struct ast_sockaddr *addr, pj_sockaddr *pjaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Fill an ast_sockaddr from a pj_sockaddr</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.24.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param addr The target address to receive the copied address</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param pjaddr The source address to copy</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval 0 Success</span><br><span style="color: hsl(120, 100%, 40%);">+ * \retval -1 Failure</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sockaddr_from_pj_sockaddr(struct ast_sockaddr *addr, const pj_sockaddr *pjaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* _RES_PJPROJECT_H */</span><br><span>diff --git a/res/res_pjproject.c b/res/res_pjproject.c</span><br><span>index ebd71b9..5b133ec 100644</span><br><span>--- a/res/res_pjproject.c</span><br><span>+++ b/res/res_pjproject.c</span><br><span>@@ -110,6 +110,8 @@</span><br><span> #include "asterisk/res_pjproject.h"</span><br><span> #include "asterisk/vector.h"</span><br><span> #include "asterisk/sorcery.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/test.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/netsock2.h"</span><br><span> </span><br><span> static struct ast_sorcery *pjproject_sorcery;</span><br><span> static pj_log_func *log_cb_orig;</span><br><span>@@ -471,6 +473,176 @@</span><br><span> pj_caching_pool_destroy(cp);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sockaddr_to_pj_sockaddr(const struct ast_sockaddr *addr, pj_sockaddr *pjaddr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (addr->ss.ss_family == AF_INET) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sockaddr_in *sin = (struct sockaddr_in *) &addr->ss;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjaddr->ipv4.sin_family = pj_AF_INET();</span><br><span style="color: hsl(120, 100%, 40%);">+ pjaddr->ipv4.sin_addr = sin->sin_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjaddr->ipv4.sin_port = sin->sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (addr->ss.ss_family == AF_INET6) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *) &addr->ss;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjaddr->ipv6.sin6_family = pj_AF_INET6();</span><br><span style="color: hsl(120, 100%, 40%);">+ pjaddr->ipv6.sin6_port = sin->sin6_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjaddr->ipv6.sin6_flowinfo = sin->sin6_flowinfo;</span><br><span style="color: hsl(120, 100%, 40%);">+ pjaddr->ipv6.sin6_scope_id = sin->sin6_scope_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&pjaddr->ipv6.sin6_addr, &sin->sin6_addr, sizeof(pjaddr->ipv6.sin6_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(pjaddr, 0, sizeof(*pjaddr));</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ast_sockaddr_from_pj_sockaddr(struct ast_sockaddr *addr, const pj_sockaddr *pjaddr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pjaddr->addr.sa_family == pj_AF_INET()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sockaddr_in *sin = (struct sockaddr_in *) &addr->ss;</span><br><span style="color: hsl(120, 100%, 40%);">+ sin->sin_family = AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+ sin->sin_addr = pjaddr->ipv4.sin_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ sin->sin_port = pjaddr->ipv4.sin_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ addr->len = sizeof(struct sockaddr_in);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (pjaddr->addr.sa_family == pj_AF_INET6()) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *) &addr->ss;</span><br><span style="color: hsl(120, 100%, 40%);">+ sin->sin6_family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+ sin->sin6_port = pjaddr->ipv6.sin6_port;</span><br><span style="color: hsl(120, 100%, 40%);">+ sin->sin6_flowinfo = pjaddr->ipv6.sin6_flowinfo;</span><br><span style="color: hsl(120, 100%, 40%);">+ sin->sin6_scope_id = pjaddr->ipv6.sin6_scope_id;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(&sin->sin6_addr, &pjaddr->ipv6.sin6_addr, sizeof(sin->sin6_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ addr->len = sizeof(struct sockaddr_in6);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(addr, 0, sizeof(*addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef TEST_FRAMEWORK</span><br><span style="color: hsl(120, 100%, 40%);">+static void fill_with_garbage(void *x, ssize_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned char *w = x;</span><br><span style="color: hsl(120, 100%, 40%);">+ while (len > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int r = ast_random();</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(w, &r, len > sizeof(r) ? sizeof(r) : len);</span><br><span style="color: hsl(120, 100%, 40%);">+ w += sizeof(r);</span><br><span style="color: hsl(120, 100%, 40%);">+ len -= sizeof(r);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(ast_sockaddr_to_pj_sockaddr_test)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *candidates[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ "127.0.0.1:5555",</span><br><span style="color: hsl(120, 100%, 40%);">+ "[::]:4444",</span><br><span style="color: hsl(120, 100%, 40%);">+ "192.168.0.100:0",</span><br><span style="color: hsl(120, 100%, 40%);">+ "[fec0::1:80]:0",</span><br><span style="color: hsl(120, 100%, 40%);">+ "[fec0::1]:80",</span><br><span style="color: hsl(120, 100%, 40%);">+ NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+ }, **candidate = candidates;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+ info->name = "ast_sockaddr_to_pj_sockaddr_test";</span><br><span style="color: hsl(120, 100%, 40%);">+ info->category = "/res/res_pjproject/";</span><br><span style="color: hsl(120, 100%, 40%);">+ info->summary = "Validate conversions from an ast_sockaddr to a pj_sockaddr";</span><br><span style="color: hsl(120, 100%, 40%);">+ info->description = "This test converts an ast_sockaddr to a pj_sockaddr and validates\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "that the two evaluate to the same string when formatted.";</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+ case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (*candidate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sockaddr addr = {{0,}};</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_sockaddr pjaddr;</span><br><span style="color: hsl(120, 100%, 40%);">+ char buffer[512];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fill_with_garbage(&pjaddr, sizeof(pj_sockaddr));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_sockaddr_parse(&addr, *candidate, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_status_update(test, "Failed to parse candidate IP: %s\n", *candidate);</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_sockaddr_to_pj_sockaddr(&addr, &pjaddr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_status_update(test, "Failed to convert ast_sockaddr to pj_sockaddr: %s\n", *candidate);</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_sockaddr_print(&pjaddr, buffer, sizeof(buffer), 1 | 2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcmp(*candidate, buffer)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_status_update(test, "Converted sockaddrs do not match: \"%s\" and \"%s\"\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ *candidate,</span><br><span style="color: hsl(120, 100%, 40%);">+ buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ candidate++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(ast_sockaddr_from_pj_sockaddr_test)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char *candidates[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ "127.0.0.1:5555",</span><br><span style="color: hsl(120, 100%, 40%);">+ "[::]:4444",</span><br><span style="color: hsl(120, 100%, 40%);">+ "192.168.0.100:0",</span><br><span style="color: hsl(120, 100%, 40%);">+ "[fec0::1:80]:0",</span><br><span style="color: hsl(120, 100%, 40%);">+ "[fec0::1]:80",</span><br><span style="color: hsl(120, 100%, 40%);">+ NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+ }, **candidate = candidates;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+ info->name = "ast_sockaddr_from_pj_sockaddr_test";</span><br><span style="color: hsl(120, 100%, 40%);">+ info->category = "/res/res_pjproject/";</span><br><span style="color: hsl(120, 100%, 40%);">+ info->summary = "Validate conversions from a pj_sockaddr to an ast_sockaddr";</span><br><span style="color: hsl(120, 100%, 40%);">+ info->description = "This test converts a pj_sockaddr to an ast_sockaddr and validates\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "that the two evaluate to the same string when formatted.";</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+ case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (*candidate) {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_sockaddr addr = {{0,}};</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_sockaddr pjaddr;</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_str_t t;</span><br><span style="color: hsl(120, 100%, 40%);">+ char buffer[512];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ fill_with_garbage(&addr, sizeof(addr));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pj_strset(&t, *candidate, strlen(*candidate));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &t, &pjaddr) != PJ_SUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_status_update(test, "Failed to parse candidate IP: %s\n", *candidate);</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_sockaddr_from_pj_sockaddr(&addr, &pjaddr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_status_update(test, "Failed to convert pj_sockaddr to ast_sockaddr: %s\n", *candidate);</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ snprintf(buffer, sizeof(buffer), "%s", ast_sockaddr_stringify(&addr));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcmp(*candidate, buffer)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_test_status_update(test, "Converted sockaddrs do not match: \"%s\" and \"%s\"\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ *candidate,</span><br><span style="color: hsl(120, 100%, 40%);">+ buffer);</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ candidate++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static int load_module(void)</span><br><span> {</span><br><span> ast_debug(3, "Starting PJPROJECT logging to Asterisk logger\n");</span><br><span>@@ -540,6 +712,9 @@</span><br><span> </span><br><span> ast_cli_register_multiple(pjproject_cli, ARRAY_LEN(pjproject_cli));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_REGISTER(ast_sockaddr_to_pj_sockaddr_test);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_REGISTER(ast_sockaddr_from_pj_sockaddr_test);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return AST_MODULE_LOAD_SUCCESS;</span><br><span> }</span><br><span> </span><br><span>@@ -563,6 +738,9 @@</span><br><span> </span><br><span> ast_sorcery_unref(pjproject_sorcery);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_UNREGISTER(ast_sockaddr_to_pj_sockaddr_test);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_UNREGISTER(ast_sockaddr_from_pj_sockaddr_test);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span>diff --git a/res/res_pjproject.exports.in b/res/res_pjproject.exports.in</span><br><span>index f1821a6..c823197 100644</span><br><span>--- a/res/res_pjproject.exports.in</span><br><span>+++ b/res/res_pjproject.exports.in</span><br><span>@@ -1,6 +1,6 @@</span><br><span> {</span><br><span> global:</span><br><span style="color: hsl(0, 100%, 40%);">- LINKER_SYMBOL_PREFIXast_pjproject_*;</span><br><span style="color: hsl(120, 100%, 40%);">+ LINKER_SYMBOL_PREFIXast_*;</span><br><span> local:</span><br><span> *;</span><br><span> };</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10045">change 10045</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/10045"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: If0fc4bba9643f755604c6ffbb0d7cc46020bc761 </div>
<div style="display:none"> Gerrit-Change-Number: 10045 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean.bright@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Michael L. Young <elgueromexicano@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Richard Mudgett <rmudgett@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Sean Bright <sean.bright@gmail.com> </div>