chan_iax2: Fix Dynamic IAX2 Registrations After Temporary DNS Failure
authorMichael L. Young <elgueromexicano@gmail.com>
Thu, 28 Aug 2014 20:31:48 +0000 (20:31 +0000)
committerMichael L. Young <elgueromexicano@gmail.com>
Thu, 28 Aug 2014 20:31:48 +0000 (20:31 +0000)
The reporter on the issue found some issues when upgrading from version 10 to 11
on 55 hosts.

Two situations that can occur with dynamic registrations.

1.  With dnsmgr disabled, if the host is not resolvable we are not trying to
    resolve the host again when it is time to attempt to register again.  This
    results in never registering to the host.
2.  With dnsmgr enabled, when the host is temporarily not resolvable the
    address is set to 0.0.0.0:0 and then when the host is resolvable the port
    is not being restored and stays set to 0.

This patch resolves these two issues by:

* Storing the hostname so that it can be used for resolving with DNS.
* Resolve the hostname on the next scheduled attempt to register.
* Storing the port used to reach the host so that when the hostname is
  resolvable again, we can set the port again if the port is still unset after
  looking up the host.

ASTERISK-23767 #close
Reported by: David Herselman
Tested by: David Herselman, Michael L. Young
Patches:
    asterisk-23767-dns_reg_retry_and_set_port_11_v3.diff
                                     uploaded by Michael L. Young (license 5026)

Review: https://reviewboard.asterisk.org/r/3856/
........

Merged revisions 422274 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 422275 from http://svn.asterisk.org/svn/asterisk/branches/12
........

Merged revisions 422276 from http://svn.asterisk.org/svn/asterisk/branches/13

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@422277 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c

index 630a663..a41f173 100644 (file)
@@ -635,6 +635,8 @@ struct iax2_registry {
        struct ast_sockaddr us;                 /*!< Who the server thinks we are */
        struct ast_dnsmgr_entry *dnsmgr;        /*!< DNS refresh manager */
        AST_LIST_ENTRY(iax2_registry) entry;
+       int port;
+       char hostname[];
 };
 
 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
@@ -8564,6 +8566,17 @@ static int iax2_do_register(struct iax2_registry *reg);
 static void __iax2_do_register_s(const void *data)
 {
        struct iax2_registry *reg = (struct iax2_registry *)data;
+
+       if (ast_sockaddr_isnull(&reg->addr)) {
+               reg->addr.ss.ss_family = AST_AF_UNSPEC;
+               ast_dnsmgr_lookup(reg->hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL);
+               if (!ast_sockaddr_port(&reg->addr)) {
+                       ast_sockaddr_set_port(&reg->addr, reg->port);
+               } else {
+                       reg->port = ast_sockaddr_port(&reg->addr);
+               }
+       }
+
        reg->expire = -1;
        iax2_do_register(reg);
 }
@@ -8796,8 +8809,9 @@ static int iax2_append_register(const char *hostname, const char *username,
 {
        struct iax2_registry *reg;
 
-       if (!(reg = ast_calloc(1, sizeof(*reg))))
+       if (!(reg = ast_calloc(1, sizeof(*reg) + strlen(hostname) + 1))) {
                return -1;
+       }
 
        reg->addr.ss.ss_family = AST_AF_UNSPEC;
        if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
@@ -8806,13 +8820,24 @@ static int iax2_append_register(const char *hostname, const char *username,
        }
 
        ast_copy_string(reg->username, username, sizeof(reg->username));
+       strcpy(reg->hostname, hostname); /* Note: This is safe */
 
-       if (secret)
+       if (secret) {
                ast_copy_string(reg->secret, secret, sizeof(reg->secret));
+       }
 
        reg->expire = -1;
        reg->refresh = IAX_DEFAULT_REG_EXPIRE;
-       ast_sockaddr_set_port(&reg->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
+
+       reg->port = ast_sockaddr_port(&reg->addr);
+
+       if (!porta && !reg->port) {
+               reg->port = IAX_DEFAULT_PORTNO;
+       } else if (porta) {
+               sscanf(porta, "%5d", &reg->port);
+       }
+
+       ast_sockaddr_set_port(&reg->addr, reg->port);
 
        AST_LIST_LOCK(&registrations);
        AST_LIST_INSERT_HEAD(&registrations, reg, entry);
@@ -12167,6 +12192,9 @@ static int iax2_do_register(struct iax2_registry *reg)
                        (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
                return -1;
        }
+       if (!ast_sockaddr_port(&reg->addr) && reg->port) {
+               ast_sockaddr_set_port(&reg->addr, reg->port);
+       }
 
        if (!reg->callno) {