<p>Joshua Colp <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/9954">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Matthew Fredrickson: Looks good to me, approved
  Joshua Colp: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">pbx_dundi: Added IPv6 support for dundi<br><br>Change includes move to netsock2 library.<br><br>ASTERISK-27164<br>Reported-by: Adam Secombe<br><br>Change-Id: Ia9e8dc3d153de7a291dbda4bd87fc827dd2bb846<br>---<br>M CHANGES<br>M pbx/dundi-parser.c<br>M pbx/dundi-parser.h<br>M pbx/pbx_dundi.c<br>4 files changed, 199 insertions(+), 105 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/CHANGES b/CHANGES</span><br><span>index c1cd83f..783e2e6 100644</span><br><span>--- a/CHANGES</span><br><span>+++ b/CHANGES</span><br><span>@@ -125,6 +125,10 @@</span><br><span> ------------------</span><br><span>  * The format_jpeg module has been removed.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+pbx_dundi</span><br><span style="color: hsl(120, 100%, 40%);">+------------------</span><br><span style="color: hsl(120, 100%, 40%);">+ * DUNDi now supports IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> Core:</span><br><span> ------------------</span><br><span>  * libedit is no longer available as an embedded library and must be provided</span><br><span>diff --git a/pbx/dundi-parser.c b/pbx/dundi-parser.c</span><br><span>index 808559c..f24ec86 100644</span><br><span>--- a/pbx/dundi-parser.c</span><br><span>+++ b/pbx/dundi-parser.c</span><br><span>@@ -37,6 +37,7 @@</span><br><span> #include "asterisk/dundi.h"</span><br><span> #include "dundi-parser.h"</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void internaloutput(const char *str)</span><br><span> {</span><br><span>     fputs(str, stdout);</span><br><span>@@ -428,7 +429,7 @@</span><br><span>    outputf("\n");</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)</span><br><span style="color: hsl(120, 100%, 40%);">+void dundi_showframe(struct dundi_hdr *fhi, int rx, struct ast_sockaddr *sin, int datalen)</span><br><span> {</span><br><span>  char *pref[] = {</span><br><span>             "Tx",</span><br><span>@@ -469,11 +470,13 @@</span><br><span>              pref[rx],</span><br><span>            fhi->oseqno, fhi->iseqno, class, fhi->cmdresp & 0x40 ? "Response" : "Command");</span><br><span>     outputf(tmp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      snprintf(tmp, (int)sizeof(tmp),</span><br><span style="color: hsl(0, 100%, 40%);">-         "%s     Flags: %s STrans: %5.5d  DTrans: %5.5d [%s:%d]%s\n", (rx > 1) ? "     " : "",</span><br><span style="color: hsl(120, 100%, 40%);">+                "%s     Flags: %s STrans: %5.5d  DTrans: %5.5d [%s]%s\n", (rx > 1) ? "     " : "",</span><br><span>          subclass, ntohs(fhi->strans) & ~DUNDI_FLAG_RESERVED, ntohs(fhi->dtrans) & ~DUNDI_FLAG_RETRANS,</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port),</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_sockaddr_stringify(sin),</span><br><span>                 fhi->cmdresp & 0x80 ? " (Final)" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         outputf(tmp);</span><br><span>        dump_ies(fhi->ies, rx > 1, datalen);</span><br><span> }</span><br><span>diff --git a/pbx/dundi-parser.h b/pbx/dundi-parser.h</span><br><span>index b24d486..ba93299 100644</span><br><span>--- a/pbx/dundi-parser.h</span><br><span>+++ b/pbx/dundi-parser.h</span><br><span>@@ -60,7 +60,7 @@</span><br><span> extern void dundi_set_output(void (*output)(const char *data));</span><br><span> /* Choose a different function for errors */</span><br><span> extern void dundi_set_error(void (*output)(const char *data));</span><br><span style="color: hsl(0, 100%, 40%);">-extern void dundi_showframe(struct dundi_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen);</span><br><span style="color: hsl(120, 100%, 40%);">+extern void dundi_showframe(struct dundi_hdr *fhi, int rx, struct ast_sockaddr *sin, int datalen);</span><br><span> </span><br><span> extern const char *dundi_ie2str(int ie);</span><br><span> </span><br><span>diff --git a/pbx/pbx_dundi.c b/pbx/pbx_dundi.c</span><br><span>index a94d71c..7fcf8cf 100644</span><br><span>--- a/pbx/pbx_dundi.c</span><br><span>+++ b/pbx/pbx_dundi.c</span><br><span>@@ -242,7 +242,7 @@</span><br><span> struct dundi_request;</span><br><span> </span><br><span> struct dundi_transaction {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct sockaddr_in addr;                       /*!< Other end of transaction */</span><br><span style="color: hsl(120, 100%, 40%);">+    struct ast_sockaddr addr;                      /*!< Other end of transaction */</span><br><span>   struct timeval start;                          /*!< When this transaction was created */</span><br><span>  dundi_eid eids[DUNDI_MAX_STACK + 1];</span><br><span>         int eidcount;                                  /*!< Number of eids in eids */</span><br><span>@@ -301,7 +301,7 @@</span><br><span> </span><br><span> struct dundi_peer {</span><br><span>    dundi_eid eid;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct sockaddr_in addr;               /*!< Address of DUNDi peer */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_sockaddr addr;              /*!< Address of DUNDi peer */</span><br><span>      AST_LIST_HEAD_NOLOCK(permissionlist, permission) permit;</span><br><span>     struct permissionlist include;</span><br><span>       dundi_eid us_eid;</span><br><span>@@ -407,18 +407,20 @@</span><br><span> static int dundi_lookup_internal(struct dundi_result *result, int maxret, struct ast_channel *chan, const char *dcontext, const char *number, int ttl, int blockempty, struct dundi_hint_metadata *md, int *expiration, int cybpass, int modeselect, dundi_eid *skip, dundi_eid *avoid[], int direct[]);</span><br><span> static int dundi_precache_internal(const char *context, const char *number, int ttl, dundi_eid *avoids[]);</span><br><span> static struct dundi_transaction *create_transaction(struct dundi_peer *p);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct dundi_transaction *find_transaction(struct dundi_hdr *hdr, struct sockaddr_in *sin)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static struct dundi_transaction *find_transaction(struct dundi_hdr *hdr, struct ast_sockaddr *sin)</span><br><span> {</span><br><span>        struct dundi_transaction *trans;</span><br><span> </span><br><span>         /* Look for an exact match first */</span><br><span>  AST_LIST_TRAVERSE(&alltrans, trans, all) {</span><br><span style="color: hsl(0, 100%, 40%);">-          if (!inaddrcmp(&trans->addr, sin) &&</span><br><span style="color: hsl(0, 100%, 40%);">-                  ((trans->strans == (ntohs(hdr->dtrans) & 32767)) /* Matches our destination */ ||</span><br><span style="color: hsl(0, 100%, 40%);">-                          ((trans->dtrans == (ntohs(hdr->strans) & 32767)) && (!hdr->dtrans))) /* We match their destination */) {</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (hdr->strans)</span><br><span style="color: hsl(0, 100%, 40%);">-                             trans->dtrans = ntohs(hdr->strans) & 32767;</span><br><span style="color: hsl(0, 100%, 40%);">-                   return trans;</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!ast_sockaddr_cmp(&trans->addr, sin) &&</span><br><span style="color: hsl(120, 100%, 40%);">+                    ((trans->strans == (ntohs(hdr->dtrans) & 32767)) /* Matches our destination */ ||</span><br><span style="color: hsl(120, 100%, 40%);">+                           ((trans->dtrans == (ntohs(hdr->strans) & 32767)) && (!hdr->dtrans))) /* We match their destination */) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (hdr->strans) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         trans->dtrans = ntohs(hdr->strans) & 32767;</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+                     return trans;</span><br><span>                }</span><br><span>    }</span><br><span> </span><br><span>@@ -434,7 +436,7 @@</span><br><span>          /* Create new transaction */</span><br><span>                 if (!(trans = create_transaction(NULL)))</span><br><span>                     break;</span><br><span style="color: hsl(0, 100%, 40%);">-          memcpy(&trans->addr, sin, sizeof(trans->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_sockaddr_copy(&trans->addr, sin);</span><br><span>                 trans->dtrans = ntohs(hdr->strans) & 32767;</span><br><span>        default:</span><br><span>             break;</span><br><span>@@ -449,7 +451,7 @@</span><br><span> {</span><br><span>    return dundi_send(trans, DUNDI_COMMAND_ACK, 0, final, NULL);</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-static void dundi_reject(struct dundi_hdr *h, struct sockaddr_in *sin)</span><br><span style="color: hsl(120, 100%, 40%);">+static void dundi_reject(struct dundi_hdr *h, struct ast_sockaddr *sin)</span><br><span> {</span><br><span>        struct {</span><br><span>             struct dundi_packet pack;</span><br><span>@@ -461,7 +463,7 @@</span><br><span>              return;</span><br><span>      memset(&tmp, 0, sizeof(tmp));</span><br><span>    memset(&trans, 0, sizeof(trans));</span><br><span style="color: hsl(0, 100%, 40%);">-   memcpy(&trans.addr, sin, sizeof(trans.addr));</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_sockaddr_copy(&trans.addr, sin);</span><br><span>     tmp.hdr.strans = h->dtrans;</span><br><span>       tmp.hdr.dtrans = h->strans;</span><br><span>       tmp.hdr.iseqno = h->oseqno;</span><br><span>@@ -1291,8 +1293,9 @@</span><br><span> </span><br><span> static void apply_peer(struct dundi_transaction *trans, struct dundi_peer *p)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!trans->addr.sin_addr.s_addr)</span><br><span style="color: hsl(0, 100%, 40%);">-            memcpy(&trans->addr, &p->addr, sizeof(trans->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ast_sockaddr_isnull(&trans->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_sockaddr_copy(&trans->addr, &p->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span>    trans->us_eid = p->us_eid;</span><br><span>     trans->them_eid = p->eid;</span><br><span>      /* Enable encryption if appropriate */</span><br><span>@@ -1321,7 +1324,7 @@</span><br><span>       ast_debug(1, "Register expired for '%s'\n", ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));</span><br><span>  peer->registerexpire = -1;</span><br><span>        peer->lastms = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    memset(&peer->addr, 0, sizeof(peer->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_setnull(&peer->addr);</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span>@@ -1706,17 +1709,16 @@</span><br><span>                                 int needqual = 0;</span><br><span>                            AST_SCHED_DEL(sched, peer->registerexpire);</span><br><span>                               peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer);</span><br><span style="color: hsl(0, 100%, 40%);">-                         snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(trans->addr.sin_addr),</span><br><span style="color: hsl(0, 100%, 40%);">-                                      ntohs(trans->addr.sin_port), expire);</span><br><span style="color: hsl(120, 100%, 40%);">+                              snprintf(data, sizeof(data), "%s:%d", ast_sockaddr_stringify(&trans->addr), expire);</span><br><span>                                ast_db_put("dundi/dpeers", dundi_eid_to_str_short(eid_str, sizeof(eid_str), &peer->eid), data);</span><br><span style="color: hsl(0, 100%, 40%);">-                                if (inaddrcmp(&peer->addr, &trans->addr)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                       ast_verb(3, "Registered DUNDi peer '%s' at '%s:%d'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),</span><br><span style="color: hsl(0, 100%, 40%);">-                                                    ast_inet_ntoa(trans->addr.sin_addr), ntohs(trans->addr.sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+                              if (ast_sockaddr_cmp(&peer->addr, &trans->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                      ast_verb(3, "Registered DUNDi peer '%s' at '%s'\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                         ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),</span><br><span style="color: hsl(120, 100%, 40%);">+                                          ast_sockaddr_stringify(&trans->addr));</span><br><span>                                        needqual = 1;</span><br><span>                                }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-                           memcpy(&peer->addr, &trans->addr, sizeof(peer->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                               ast_sockaddr_copy(&peer->addr, &trans->addr);</span><br><span>                          dundi_ie_append_short(ied, DUNDI_IE_EXPIRATION, default_expiration);</span><br><span>                                 dundi_send(trans, DUNDI_COMMAND_REGRESPONSE, 0, 1, ied);</span><br><span>                             if (needqual)</span><br><span>@@ -1840,7 +1842,7 @@</span><br><span>                                                        ast_copy_string(trans->parent->dei->ipaddr, ies.q_ipaddr, sizeof(trans->parent->dei->ipaddr));</span><br><span>                                             if (!ast_eid_cmp(&trans->them_eid, &trans->parent->query_eid)) {</span><br><span>                                                    /* If it's them, update our address */</span><br><span style="color: hsl(0, 100%, 40%);">-                                                      ast_copy_string(trans->parent->dei->ipaddr, ast_inet_ntoa(trans->addr.sin_addr), sizeof(trans->parent->dei->ipaddr));</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    ast_copy_string(trans->parent->dei->ipaddr, ast_sockaddr_stringify_addr(&trans->addr), sizeof(trans->parent->dei->ipaddr));</span><br><span>                                                 }</span><br><span>                                    }</span><br><span>                                    if (ies.hint) {</span><br><span>@@ -2023,7 +2025,7 @@</span><br><span>      return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int handle_frame(struct dundi_hdr *h, struct sockaddr_in *sin, int datalen)</span><br><span style="color: hsl(120, 100%, 40%);">+static int handle_frame(struct dundi_hdr *h, struct ast_sockaddr *sin, int datalen)</span><br><span> {</span><br><span>       struct dundi_transaction *trans;</span><br><span>     trans = find_transaction(h, sin);</span><br><span>@@ -2066,13 +2068,12 @@</span><br><span> </span><br><span> static int socket_read(int *id, int fd, short events, void *cbdata)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-     struct sockaddr_in sin;</span><br><span style="color: hsl(120, 100%, 40%);">+       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 style="color: hsl(0, 100%, 40%);">-      socklen_t len = sizeof(sin);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        res = recvfrom(netsocket, buf, sizeof(buf) - 1, 0,(struct sockaddr *) &sin, &len);</span><br><span style="color: hsl(120, 100%, 40%);">+    res = ast_recvfrom(netsocket, 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>@@ -2580,6 +2581,26 @@</span><br><span>     return CLI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static char *dundi_sockaddr_stringify_host(const struct ast_sockaddr *addr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (ast_sockaddr_isnull(addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return "(Unspecified)";</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     return ast_sockaddr_stringify_host(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%);">+static uint16_t dundi_sockaddr_port(const struct ast_sockaddr *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%);">+     * Test to avoid a debug message complaining about addr</span><br><span style="color: hsl(120, 100%, 40%);">+        * not being an IPv4 or IPv6 address.</span><br><span style="color: hsl(120, 100%, 40%);">+  */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_sockaddr_isnull(addr)) {</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%);">+     return ast_sockaddr_port(addr);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static char *dundi_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span> {</span><br><span>  struct dundi_peer *peer;</span><br><span>@@ -2625,8 +2646,8 @@</span><br><span>             ast_cli(a->fd, "Peer:    %s\n", ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid));</span><br><span>           ast_cli(a->fd, "Model:   %s\n", model2str(peer->model));</span><br><span>             ast_cli(a->fd, "Order:   %s\n", order);</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_cli(a->fd, "Host:    %s\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "<Unspecified>");</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_cli(a->fd, "Port:    %d\n", ntohs(peer->addr.sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_cli(a->fd, "Host:    %s\n", ast_sockaddr_isnull(&peer->addr) ? "<Unspecified>" : ast_sockaddr_stringify_host(&peer->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_cli(a->fd, "Port:    %d\n", dundi_sockaddr_port(&peer->addr));</span><br><span>               ast_cli(a->fd, "Dynamic: %s\n", peer->dynamic ? "yes" : "no");</span><br><span>           ast_cli(a->fd, "Reg:     %s\n", peer->registerid < 0 ? "No" : "Yes");</span><br><span>                 ast_cli(a->fd, "In Key:  %s\n", ast_strlen_zero(peer->inkey) ? "<None>" : peer->inkey);</span><br><span>@@ -2658,8 +2679,8 @@</span><br><span> </span><br><span> static char *dundi_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-#define FORMAT2 "%-20.20s %-15.15s     %-6.6s %-10.10s %-8.8s %-15.15s\n"</span><br><span style="color: hsl(0, 100%, 40%);">-#define FORMAT "%-20.20s %-15.15s %s %-6d %-10.10s %-8.8s %-15.15s\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define FORMAT2 "%-20.20s %-41s     %-6.6s %-10.10s %-8.8s %-15.15s\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define FORMAT "%-20.20s %-41s %s %-6d %-10.10s %-8.8s %-15.15s\n"</span><br><span>     struct dundi_peer *peer;</span><br><span>     int registeredonly=0;</span><br><span>        char avgms[20];</span><br><span>@@ -2696,9 +2717,11 @@</span><br><span>             char status[20];</span><br><span>             int print_line = -1;</span><br><span>                 char srch[2000];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>           total_peers++;</span><br><span style="color: hsl(0, 100%, 40%);">-          if (registeredonly && !peer->addr.sin_addr.s_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+         if (registeredonly && ast_sockaddr_isnull(&peer->addr)) {</span><br><span>                     continue;</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span>            if (peer->maxms) {</span><br><span>                        if (peer->lastms < 0) {</span><br><span>                                strcpy(status, "UNREACHABLE");</span><br><span>@@ -2724,9 +2747,9 @@</span><br><span>                     snprintf(avgms, sizeof(avgms), "%d ms", peer->avgms);</span><br><span>           else</span><br><span>                         strcpy(avgms, "Unavail");</span><br><span style="color: hsl(0, 100%, 40%);">-             snprintf(srch, sizeof(srch), FORMAT, ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),</span><br><span style="color: hsl(0, 100%, 40%);">-                                       peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",</span><br><span style="color: hsl(0, 100%, 40%);">-                                      peer->dynamic ? "(D)" : "(S)", ntohs(peer->addr.sin_port), model2str(peer->model), avgms, status);</span><br><span style="color: hsl(120, 100%, 40%);">+               snprintf(srch, sizeof(srch), FORMAT, ast_eid_to_str(eid_str, sizeof(eid_str),</span><br><span style="color: hsl(120, 100%, 40%);">+                 &peer->eid), dundi_sockaddr_stringify_host(&peer->addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                        peer->dynamic ? "(D)" : "(S)", dundi_sockaddr_port(&peer->addr), model2str(peer->model), avgms, status);</span><br><span> </span><br><span>                 if (a->argc == 5) {</span><br><span>                   if (!strcasecmp(a->argv[3],"include") && strstr(srch,a->argv[4])) {</span><br><span>@@ -2742,8 +2765,8 @@</span><br><span> </span><br><span>         if (print_line) {</span><br><span>                    ast_cli(a->fd, FORMAT, ast_eid_to_str(eid_str, sizeof(eid_str), &peer->eid),</span><br><span style="color: hsl(0, 100%, 40%);">-                                  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",</span><br><span style="color: hsl(0, 100%, 40%);">-                                      peer->dynamic ? "(D)" : "(S)", ntohs(peer->addr.sin_port), model2str(peer->model), avgms, status);</span><br><span style="color: hsl(120, 100%, 40%);">+                               dundi_sockaddr_stringify_host(&peer->addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                            peer->dynamic ? "(D)" : "(S)", dundi_sockaddr_port(&peer->addr), model2str(peer->model), avgms, status);</span><br><span>            }</span><br><span>    }</span><br><span>    ast_cli(a->fd, "%d dundi peers [%d online, %d offline, %d unmonitored]\n", total_peers, online_peers, offline_peers, unmonitored_peers);</span><br><span>@@ -2755,8 +2778,8 @@</span><br><span> </span><br><span> static char *dundi_show_trans(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-#define FORMAT2 "%-22.22s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n"</span><br><span style="color: hsl(0, 100%, 40%);">-#define FORMAT "%-16.16s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define FORMAT2 "%-47s %-5.5s %-5.5s %-3.3s %-3.3s %-3.3s\n"</span><br><span style="color: hsl(120, 100%, 40%);">+#define FORMAT "%-41s:%5d %-5.5d %-5.5d %-3.3d %-3.3d %-3.3d\n"</span><br><span>    struct dundi_transaction *trans;</span><br><span>     switch (cmd) {</span><br><span>       case CLI_INIT:</span><br><span>@@ -2774,8 +2797,9 @@</span><br><span>       AST_LIST_LOCK(&peers);</span><br><span>   ast_cli(a->fd, FORMAT2, "Remote", "Src", "Dst", "Tx", "Rx", "Ack");</span><br><span>   AST_LIST_TRAVERSE(&alltrans, trans, all) {</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_cli(a->fd, FORMAT, ast_inet_ntoa(trans->addr.sin_addr),</span><br><span style="color: hsl(0, 100%, 40%);">-                       ntohs(trans->addr.sin_port), trans->strans, trans->dtrans, trans->oseqno, trans->iseqno, trans->aseqno);</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_cli(a->fd, FORMAT, ast_sockaddr_stringify_host(&trans->addr),</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_sockaddr_port(&trans->addr), trans->strans, trans->dtrans,</span><br><span style="color: hsl(120, 100%, 40%);">+                   trans->oseqno, trans->iseqno, trans->aseqno);</span><br><span>       }</span><br><span>    AST_LIST_UNLOCK(&peers);</span><br><span>         return CLI_SUCCESS;</span><br><span>@@ -3095,8 +3119,9 @@</span><br><span>  int tid;</span><br><span> </span><br><span>         /* Don't allow creation of transactions to non-registered peers */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (p && !p->addr.sin_addr.s_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (p && ast_sockaddr_isnull(&p->addr)) {</span><br><span>             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span>    tid = get_trans_id();</span><br><span>        if (tid < 1)</span><br><span>              return NULL;</span><br><span>@@ -3125,11 +3150,10 @@</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 = sendto(netsocket, pack->data, pack->datalen, 0, (struct sockaddr *)&pack->parent->addr, sizeof(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>      if (res < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_log(LOG_WARNING, "Failed to transmit to '%s:%d': %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                   ast_inet_ntoa(pack->parent->addr.sin_addr),</span><br><span style="color: hsl(0, 100%, 40%);">-                       ntohs(pack->parent->addr.sin_port), strerror(errno));</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_WARNING, "Failed to transmit to '%s': %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                    ast_sockaddr_stringify(&pack->parent->addr), strerror(errno));</span><br><span>     }</span><br><span>    if (res > 0)</span><br><span>              res = 0;</span><br><span>@@ -3235,10 +3259,10 @@</span><br><span>   AST_LIST_LOCK(&peers);</span><br><span>   if (pack->retrans < 1) {</span><br><span>               pack->retransid = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                if (!ast_test_flag(pack->parent, FLAG_ISQUAL))</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_log(LOG_NOTICE, "Max retries exceeded to host '%s:%d' msg %d on call %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                               ast_inet_ntoa(pack->parent->addr.sin_addr),</span><br><span style="color: hsl(0, 100%, 40%);">-                               ntohs(pack->parent->addr.sin_port), pack->h->oseqno, ntohs(pack->h->strans));</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!ast_test_flag(pack->parent, FLAG_ISQUAL)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   ast_log(LOG_NOTICE, "Max retries exceeded to host '%s' msg %d on call %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                ast_sockaddr_stringify(&pack->parent->addr), pack->h->oseqno, ntohs(pack->h->strans));</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span>            destroy_trans(pack->parent, 1);</span><br><span>           res = 0;</span><br><span>     } else {</span><br><span>@@ -3593,8 +3617,9 @@</span><br><span>     char eid_str2[20];</span><br><span> </span><br><span>       /* Ignore if not registered */</span><br><span style="color: hsl(0, 100%, 40%);">-  if (!p->addr.sin_addr.s_addr)</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ast_sockaddr_isnull(&p->addr)) {</span><br><span>          return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span>    if (p->maxms && ((p->lastms < 0) || (p->lastms >= p->maxms)))</span><br><span>              return 0;</span><br><span> </span><br><span>@@ -4527,15 +4552,31 @@</span><br><span>      char eid_str[20];</span><br><span>    ast_eid_to_str(eid_str, sizeof(eid_str), eid);</span><br><span>       if (!ast_db_get("dundi/dpeers", eid_str, data, sizeof(data))) {</span><br><span style="color: hsl(0, 100%, 40%);">-               c = strchr(data, ':');</span><br><span style="color: hsl(120, 100%, 40%);">+                /*</span><br><span style="color: hsl(120, 100%, 40%);">+             * data is in the form:</span><br><span style="color: hsl(120, 100%, 40%);">+                * IPv6 address: [ffff:ffff::ffff:ffff]:port:expire</span><br><span style="color: hsl(120, 100%, 40%);">+            * IPv4 address: a.b.c.d:port:expire</span><br><span style="color: hsl(120, 100%, 40%);">+           */</span><br><span style="color: hsl(120, 100%, 40%);">+           c = data;</span><br><span style="color: hsl(120, 100%, 40%);">+             if (*c == '[') {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* Need to skip over the IPv6 address. */</span><br><span style="color: hsl(120, 100%, 40%);">+                     c = strchr(c, ']');</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (c) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      c = strchr(c, ':');</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span>            if (c) {</span><br><span>                     *c = '\0';</span><br><span>                   c++;</span><br><span>                         if (sscanf(c, "%5d:%30d", &port, &expire) == 2) {</span><br><span>                          /* Got it! */</span><br><span style="color: hsl(0, 100%, 40%);">-                           inet_aton(data, &peer->addr.sin_addr);</span><br><span style="color: hsl(0, 100%, 40%);">-                           peer->addr.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-                             peer->addr.sin_port = htons(port);</span><br><span style="color: hsl(120, 100%, 40%);">+                         struct ast_sockaddr *addrs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                         if (ast_sockaddr_resolve(&addrs, data, PARSE_PORT_FORBID, AF_UNSPEC) > 0){</span><br><span style="color: hsl(120, 100%, 40%);">+                                     ast_sockaddr_copy(&peer->addr, &addrs[0]);</span><br><span style="color: hsl(120, 100%, 40%);">+                                 ast_free(addrs);</span><br><span style="color: hsl(120, 100%, 40%);">+                              }</span><br><span style="color: hsl(120, 100%, 40%);">+                             ast_sockaddr_set_port(&peer->addr, port);</span><br><span>                             peer->registerexpire = ast_sched_add(sched, (expire + 10) * 1000, do_register_expire, peer);</span><br><span>                      }</span><br><span>            }</span><br><span>@@ -4546,11 +4587,10 @@</span><br><span> static void build_peer(dundi_eid *eid, struct ast_variable *v, int *globalpcmode)</span><br><span> {</span><br><span>        struct dundi_peer *peer;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct ast_hostent he;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct hostent *hp;</span><br><span>  dundi_eid testeid;</span><br><span>   int needregister=0;</span><br><span>  char eid_str[20];</span><br><span style="color: hsl(120, 100%, 40%);">+     int port = 0;</span><br><span> </span><br><span>    AST_LIST_LOCK(&peers);</span><br><span>   AST_LIST_TRAVERSE(&peers, peer, list) {</span><br><span>@@ -4567,8 +4607,6 @@</span><br><span>          peer->registerid = -1;</span><br><span>            peer->registerexpire = -1;</span><br><span>                peer->qualifyid = -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                peer->addr.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-             peer->addr.sin_port = htons(DUNDI_PORT);</span><br><span>          populate_addr(peer, eid);</span><br><span>            AST_LIST_INSERT_HEAD(&peers, peer, list);</span><br><span>        }</span><br><span>@@ -4584,15 +4622,17 @@</span><br><span>          } else if (!strcasecmp(v->name, "outkey")) {</span><br><span>                    ast_copy_string(peer->outkey, v->value, sizeof(peer->outkey));</span><br><span>              } else if (!strcasecmp(v->name, "port")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 peer->addr.sin_port = htons(atoi(v->value));</span><br><span style="color: hsl(120, 100%, 40%);">+                    port = atoi(v->value);</span><br><span>            } else if (!strcasecmp(v->name, "host")) {</span><br><span>                      if (!strcasecmp(v->value, "dynamic")) {</span><br><span>                                 peer->dynamic = 1;</span><br><span>                        } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                                hp = ast_gethostbyname(v->value, &he);</span><br><span style="color: hsl(0, 100%, 40%);">-                           if (hp) {</span><br><span style="color: hsl(0, 100%, 40%);">-                                       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                           struct ast_sockaddr *addrs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                         if (ast_sockaddr_resolve(&addrs, v->value, PARSE_PORT_FORBID, AF_UNSPEC) > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                     ast_sockaddr_copy(&peer->addr, &addrs[0]);</span><br><span>                                        peer->dynamic = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                                 ast_free(addrs);</span><br><span>                             } else {</span><br><span>                                     ast_log(LOG_WARNING, "Unable to find host '%s' at line %d\n", v->value, v->lineno);</span><br><span>                                  peer->dead = 1;</span><br><span>@@ -4663,6 +4703,11 @@</span><br><span>                  }</span><br><span>            }</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!ast_sockaddr_isnull(&peer->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_sockaddr_set_port(&peer->addr, (0 < port) ? port : DUNDI_PORT);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  (*globalpcmode) |= peer->pcmodel;</span><br><span>         if (!peer->model && !peer->pcmodel) {</span><br><span>          ast_log(LOG_WARNING, "Peer '%s' lacks a model or pcmodel, discarding!\n",</span><br><span>@@ -4811,20 +4856,54 @@</span><br><span>        .matchmore   = dundi_matchmore,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int set_config(char *config_file, struct sockaddr_in* sin, int reload)</span><br><span style="color: hsl(120, 100%, 40%);">+static int get_ipaddress(char *ip, size_t size, const char *str, int family)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_sockaddr *addrs;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_sockaddr_resolve(&addrs, str, 0, family)) {</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_copy_string(ip, ast_sockaddr_stringify_host(&addrs[0]), size);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_free(addrs);</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%);">+static void set_host_ipaddr(struct ast_sockaddr *sin)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      char hn[MAXHOSTNAMELEN];</span><br><span style="color: hsl(120, 100%, 40%);">+      struct addrinfo hints;</span><br><span style="color: hsl(120, 100%, 40%);">+        int family;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&hints, 0, sizeof(hints));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ast_sockaddr_is_ipv6(sin)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              family = AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              family = AF_INET;</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 (gethostname(hn, sizeof(hn) - 1) < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         ast_log(LOG_WARNING, "Unable to get host name!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return;</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%);">+   get_ipaddress(ipaddr, sizeof(ipaddr), hn, family);</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%);">+static int set_config(char *config_file, struct ast_sockaddr *sin, int reload)</span><br><span> {</span><br><span>         struct ast_config *cfg;</span><br><span>      struct ast_variable *v;</span><br><span>      char *cat;</span><br><span>   int x;</span><br><span>       struct ast_flags config_flags = { 0 };</span><br><span style="color: hsl(0, 100%, 40%);">-  char hn[MAXHOSTNAMELEN] = "";</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_hostent he;</span><br><span style="color: hsl(0, 100%, 40%);">-  struct hostent *hp;</span><br><span style="color: hsl(0, 100%, 40%);">-     struct sockaddr_in sin2;</span><br><span>     static int last_port = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     int port = 0;</span><br><span>        int globalpcmodel = 0;</span><br><span>       dundi_eid testeid;</span><br><span style="color: hsl(120, 100%, 40%);">+    char bind_addr[80];</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>@@ -4835,16 +4914,6 @@</span><br><span>    dundi_cache_time = DUNDI_DEFAULT_CACHE_TIME;</span><br><span>         any_peer = NULL;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    ipaddr[0] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">-       if (!gethostname(hn, sizeof(hn)-1)) {</span><br><span style="color: hsl(0, 100%, 40%);">-           hp = ast_gethostbyname(hn, &he);</span><br><span style="color: hsl(0, 100%, 40%);">-            if (hp) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       memcpy(&sin2.sin_addr, hp->h_addr, sizeof(sin2.sin_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_copy_string(ipaddr, ast_inet_ntoa(sin2.sin_addr), sizeof(ipaddr));</span><br><span style="color: hsl(0, 100%, 40%);">-          } else</span><br><span style="color: hsl(0, 100%, 40%);">-                  ast_log(LOG_WARNING, "Unable to look up host '%s'\n", hn);</span><br><span style="color: hsl(0, 100%, 40%);">-    } else</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_log(LOG_WARNING, "Unable to get host name!\n");</span><br><span>        AST_LIST_LOCK(&peers);</span><br><span> </span><br><span>       if (ast_eid_is_empty(&ast_eid_default)) {</span><br><span>@@ -4857,19 +4926,13 @@</span><br><span>      v = ast_variable_browse(cfg, "general");</span><br><span>   while(v) {</span><br><span>           if (!strcasecmp(v->name, "port")){</span><br><span style="color: hsl(0, 100%, 40%);">-                 sin->sin_port = htons(atoi(v->value));</span><br><span style="color: hsl(0, 100%, 40%);">-                    if(last_port==0){</span><br><span style="color: hsl(0, 100%, 40%);">-                               last_port=sin->sin_port;</span><br><span style="color: hsl(0, 100%, 40%);">-                     } else if(sin->sin_port != last_port)</span><br><span style="color: hsl(0, 100%, 40%);">-                                ast_log(LOG_WARNING, "change to port ignored until next asterisk re-start\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                      port = atoi(v->value);</span><br><span>            } else if (!strcasecmp(v->name, "bindaddr")) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     struct hostent *hep;</span><br><span style="color: hsl(0, 100%, 40%);">-                    struct ast_hostent hent;</span><br><span style="color: hsl(0, 100%, 40%);">-                        hep = ast_gethostbyname(v->value, &hent);</span><br><span style="color: hsl(0, 100%, 40%);">-                        if (hep) {</span><br><span style="color: hsl(0, 100%, 40%);">-                              memcpy(&sin->sin_addr, hep->h_addr, sizeof(sin->sin_addr));</span><br><span style="color: hsl(0, 100%, 40%);">-                        } else</span><br><span style="color: hsl(0, 100%, 40%);">-                          ast_log(LOG_WARNING, "Invalid host/IP '%s'\n", v->value);</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (get_ipaddress(bind_addr, sizeof(bind_addr), v->value, AF_UNSPEC) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               if (!ast_sockaddr_parse(sin, bind_addr, 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>@@ -4924,6 +4987,26 @@</span><br><span>              }</span><br><span>            v = v->next;</span><br><span>      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (port == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              port = DUNDI_PORT;</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_isnull(sin)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               sprintf(bind_addr, "0.0.0.0:%d", port);</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_sockaddr_parse(sin, bind_addr, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+        } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_sockaddr_set_port(sin, port);</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 (last_port == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         last_port = port;</span><br><span style="color: hsl(120, 100%, 40%);">+     } else if (last_port != port) {</span><br><span style="color: hsl(120, 100%, 40%);">+               ast_log(LOG_WARNING, "change to port ignored until next asterisk re-start\n");</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%);">+   set_host_ipaddr(sin);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      AST_LIST_UNLOCK(&peers);</span><br><span>         mark_mappings();</span><br><span>     v = ast_variable_browse(cfg, "mappings");</span><br><span>@@ -4995,7 +5078,9 @@</span><br><span> </span><br><span> static int reload(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct sockaddr_in sin;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_sockaddr sin;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sockaddr_setnull(&sin);</span><br><span> </span><br><span>  if (set_config("dundi.conf", &sin, 1))</span><br><span>                 return AST_MODULE_LOAD_FAILURE;</span><br><span>@@ -5005,15 +5090,11 @@</span><br><span> </span><br><span> static int load_module(void)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-      struct sockaddr_in sin;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_sockaddr sin;</span><br><span> </span><br><span>         dundi_set_output(dundi_debug_output);</span><br><span>        dundi_set_error(dundi_error_output);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-        sin.sin_family = AF_INET;</span><br><span style="color: hsl(0, 100%, 40%);">-       sin.sin_port = htons(DUNDI_PORT);</span><br><span style="color: hsl(0, 100%, 40%);">-       sin.sin_addr.s_addr = INADDR_ANY;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span>    /* Make a UDP socket */</span><br><span>      io = io_context_create();</span><br><span>    sched = ast_sched_context_create();</span><br><span>@@ -5022,19 +5103,25 @@</span><br><span>                goto declined;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sockaddr_setnull(&sin);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    if (set_config("dundi.conf", &sin, 0)) {</span><br><span>               goto declined;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);</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> </span><br><span>        if (netsocket < 0) {</span><br><span>              ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));</span><br><span>              goto declined;</span><br><span>       }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (bind(netsocket, (struct sockaddr *) &sin, sizeof(sin))) {</span><br><span style="color: hsl(0, 100%, 40%);">-               ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                      ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), strerror(errno));</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>          goto declined;</span><br><span>       }</span><br><span> </span><br><span>@@ -5052,7 +5139,7 @@</span><br><span>        ast_custom_function_register(&dundi_query_function);</span><br><span>     ast_custom_function_register(&dundi_result_function);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ast_verb(2, "DUNDi Ready and Listening on %s port %d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_verb(2, "DUNDi Ready and Listening on %s\n", ast_sockaddr_stringify(&sin));</span><br><span> </span><br><span>    return AST_MODULE_LOAD_SUCCESS;</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/9954">change 9954</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/9954"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 16.0 </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ia9e8dc3d153de7a291dbda4bd87fc827dd2bb846 </div>
<div style="display:none"> Gerrit-Change-Number: 9954 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: Richard Mudgett <rmudgett@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: Matthew Fredrickson <creslin@digium.com> </div>