<p>Kirsty Tyerman has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/10860">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">pbx_dundi: added IPv4/IPv6 dual bind support to DUNDi<br><br>ASTERISK-28234<br>Reported-by: Kirsty Tyerman<br><br>Change-Id: I5d6e6b52dbe51415046bb3953fd16f5b421bc2e1<br>---<br>M pbx/pbx_dundi.c<br>1 file changed, 108 insertions(+), 23 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/60/10860/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c</span><br><span>index f196721..3b30eaa 100644</span><br><span>--- a/pbx/pbx_dundi.c</span><br><span>+++ b/pbx/pbx_dundi.c</span><br><span>@@ -184,6 +184,7 @@</span><br><span> static struct io_context *io;</span><br><span> static struct ast_sched_context *sched;</span><br><span> static int netsocket = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+static int netsocket2 = -1;</span><br><span> static pthread_t netthreadid = AST_PTHREADT_NULL;</span><br><span> static pthread_t precachethreadid = AST_PTHREADT_NULL;</span><br><span> static pthread_t clearcachethreadid = AST_PTHREADT_NULL;</span><br><span>@@ -2079,14 +2080,14 @@</span><br><span>   return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int socket_read(int *id, int fd, short events, void *cbdata)</span><br><span style="color: hsl(120, 100%, 40%);">+static int socket_read(int *id, int fd, short events, void *sock)</span><br><span> {</span><br><span>        struct ast_sockaddr sin;</span><br><span>     int res;</span><br><span>     struct dundi_hdr *h;</span><br><span>         char buf[MAX_PACKET_SIZE];</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  res = ast_recvfrom(netsocket, buf, sizeof(buf), 0, &sin);</span><br><span style="color: hsl(120, 100%, 40%);">+ res = ast_recvfrom(*((int *)sock), buf, sizeof(buf), 0, &sin);</span><br><span>   if (res < 0) {</span><br><span>            if (errno != ECONNREFUSED)</span><br><span>                   ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));</span><br><span>@@ -2196,7 +2197,11 @@</span><br><span>        from the network, and queue them for delivery to the channels */</span><br><span>  int res;</span><br><span>     /* Establish I/O callback for socket read */</span><br><span style="color: hsl(0, 100%, 40%);">-    int *socket_read_id = ast_io_add(io, netsocket, socket_read, AST_IO_IN, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+        int *socket_read_id = ast_io_add(io, netsocket, socket_read, AST_IO_IN, &netsocket);</span><br><span style="color: hsl(120, 100%, 40%);">+      int *socket_read_id2 = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (netsocket2 >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             socket_read_id2 = ast_io_add(io, netsocket2, socket_read, AST_IO_IN, &netsocket2);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span> </span><br><span>        while (!dundi_shutdown) {</span><br><span>            res = ast_sched_wait(sched);</span><br><span>@@ -2213,6 +2218,10 @@</span><br><span> </span><br><span>    ast_io_remove(io, socket_read_id);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        if (!socket_read_id2) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_io_remove(io, socket_read_id2);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  return NULL;</span><br><span> }</span><br><span> </span><br><span>@@ -3158,7 +3167,17 @@</span><br><span>       int res;</span><br><span>     if (dundidebug)</span><br><span>              dundi_showframe(pack->h, 0, &pack->parent->addr, pack->datalen - sizeof(struct dundi_hdr));</span><br><span style="color: hsl(0, 100%, 40%);">-     res = ast_sendto(netsocket, pack->data, pack->datalen, 0, &pack->parent->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (netsocket2 < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              res = ast_sendto(netsocket, pack->data, pack->datalen, 0, &pack->parent->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (ast_sockaddr_is_ipv4(&pack->parent->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    res = ast_sendto(netsocket, pack->data, pack->datalen, 0, &pack->parent->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+               } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      res = ast_sendto(netsocket2, pack->data, pack->datalen, 0, &pack->parent->addr);</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>  if (res < 0) {</span><br><span>            ast_log(LOG_WARNING, "Failed to transmit to '%s': %s\n",</span><br><span>                   ast_sockaddr_stringify(&pack->parent->addr), strerror(errno));</span><br><span>@@ -4912,7 +4931,7 @@</span><br><span>     get_ipaddress(ipaddr, sizeof(ipaddr), hn, family);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int set_config(char *config_file, struct ast_sockaddr *sin, int reload)</span><br><span style="color: hsl(120, 100%, 40%);">+static int set_config(char *config_file, struct ast_sockaddr *sin, int reload, struct ast_sockaddr *sin2)</span><br><span> {</span><br><span>    struct ast_config *cfg;</span><br><span>      struct ast_variable *v;</span><br><span>@@ -4923,7 +4942,8 @@</span><br><span>      int port = 0;</span><br><span>        int globalpcmodel = 0;</span><br><span>       dundi_eid testeid;</span><br><span style="color: hsl(0, 100%, 40%);">-      char bind_addr[80];</span><br><span style="color: hsl(120, 100%, 40%);">+   char bind_addr[80]={0,};</span><br><span style="color: hsl(120, 100%, 40%);">+      char bind_addr2[80]={0,};</span><br><span> </span><br><span>        if (!(cfg = ast_config_load(config_file, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {</span><br><span>               ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);</span><br><span>@@ -4953,6 +4973,12 @@</span><br><span>                                    ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);</span><br><span>                               }</span><br><span>                    }</span><br><span style="color: hsl(120, 100%, 40%);">+             } else if (!strcasecmp(v->name, "bindaddr2")) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  if (get_ipaddress(bind_addr2, sizeof(bind_addr2), v->value, AF_UNSPEC) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (!ast_sockaddr_parse(sin2, bind_addr2, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                       ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);</span><br><span style="color: hsl(120, 100%, 40%);">+                                }</span><br><span style="color: hsl(120, 100%, 40%);">+                     }</span><br><span>            } else if (!strcasecmp(v->name, "authdebug")) {</span><br><span>                         authdebug = ast_true(v->value);</span><br><span>           } else if (!strcasecmp(v->name, "ttl")) {</span><br><span>@@ -5027,6 +5053,10 @@</span><br><span> </span><br><span>  set_host_ipaddr(sin);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+     if (!ast_sockaddr_isnull(sin2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_sockaddr_set_port(sin2, port);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  AST_LIST_UNLOCK(&peers);</span><br><span> </span><br><span>     mark_mappings();</span><br><span>@@ -5089,6 +5119,18 @@</span><br><span>            clearcachethreadid = AST_PTHREADT_NULL;</span><br><span>      }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (netsocket >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              close(netsocket);</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 (netsocket2 >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             close(netsocket2);</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 (io) {</span><br><span style="color: hsl(120, 100%, 40%);">+             io_context_destroy(io);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  mark_mappings();</span><br><span>     prune_mappings();</span><br><span>    mark_peers();</span><br><span>@@ -5114,10 +5156,12 @@</span><br><span> static int reload(void)</span><br><span> {</span><br><span>      struct ast_sockaddr sin;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ast_sockaddr sin2;</span><br><span> </span><br><span>        ast_sockaddr_setnull(&sin);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_sockaddr_setnull(&sin2);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    if (set_config("dundi.conf", &sin, 1))</span><br><span style="color: hsl(120, 100%, 40%);">+  if (set_config("dundi.conf", &sin, 1, &sin2))</span><br><span>              return AST_MODULE_LOAD_FAILURE;</span><br><span> </span><br><span>  return AST_MODULE_LOAD_SUCCESS;</span><br><span>@@ -5126,6 +5170,7 @@</span><br><span> static int load_module(void)</span><br><span> {</span><br><span>         struct ast_sockaddr sin;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct ast_sockaddr sin2;</span><br><span> </span><br><span>        dundi_set_output(dundi_debug_output);</span><br><span>        dundi_set_error(dundi_error_output);</span><br><span>@@ -5139,29 +5184,69 @@</span><br><span>       }</span><br><span> </span><br><span>        ast_sockaddr_setnull(&sin);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_sockaddr_setnull(&sin2);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    if (set_config("dundi.conf", &sin, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+        if (set_config("dundi.conf", &sin, 0, &sin2)) {</span><br><span>            goto declined;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (ast_sockaddr_is_ipv6(&sin)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           netsocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);</span><br><span style="color: hsl(0, 100%, 40%);">-   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!ast_sockaddr_isnull(&sin2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if ((ast_sockaddr_is_ipv4(&sin) == ast_sockaddr_is_ipv4(&sin2)) || (ast_sockaddr_is_ipv6(&sin) == ast_sockaddr_is_ipv6(&sin2))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_log(LOG_ERROR, "bind & bind2 ip protocol should be different");</span><br><span style="color: hsl(120, 100%, 40%);">+                     goto declined;</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%);">+           /*bind netsocket to ipv4, netsocket2 to ipv6 */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>            netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);</span><br><span style="color: hsl(120, 100%, 40%);">+          netsocket2 = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);</span><br><span style="color: hsl(120, 100%, 40%);">+                if (netsocket < 0 || netsocket2 < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto declined;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ast_sockaddr_is_ipv4(&sin)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (ast_bind(netsocket, &sin)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                          ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_sockaddr_stringify(&sin), strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                           goto declined;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (ast_bind(netsocket2, &sin2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_sockaddr_stringify(&sin), strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                           goto declined;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+             } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (ast_bind(netsocket, &sin2)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_sockaddr_stringify(&sin), strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                           goto declined;</span><br><span style="color: hsl(120, 100%, 40%);">+                        }</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (ast_bind(netsocket2, &sin)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                   ast_sockaddr_stringify(&sin), strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                           goto declined;</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_set_qos(netsocket, tos, 0, "DUNDi");</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_set_qos(netsocket2, tos, 0, "DUNDi");</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (ast_sockaddr_is_ipv6(&sin)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 netsocket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP);</span><br><span style="color: hsl(120, 100%, 40%);">+         } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (netsocket < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                       goto declined;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (ast_bind(netsocket, &sin))  {</span><br><span style="color: hsl(120, 100%, 40%);">+                 ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                           ast_sockaddr_stringify(&sin), strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+                   goto declined;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_set_qos(netsocket, tos, 0, "DUNDi");</span><br><span>   }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (netsocket < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-         goto declined;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (ast_bind(netsocket, &sin))  {</span><br><span style="color: hsl(0, 100%, 40%);">-           ast_log(LOG_ERROR, "Unable to bind to %s : %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                     ast_sockaddr_stringify(&sin), strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">-             goto declined;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       ast_set_qos(netsocket, tos, 0, "DUNDi");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>   if (start_network_thread()) {</span><br><span>                ast_log(LOG_ERROR, "Unable to start network thread\n");</span><br><span>            goto declined;</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/10860">change 10860</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/10860"/><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: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I5d6e6b52dbe51415046bb3953fd16f5b421bc2e1 </div>
<div style="display:none"> Gerrit-Change-Number: 10860 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Kirsty Tyerman <kirsty.tyerman@boeing.com> </div>