From c5916fb39f1d6c0fe1292f2d1de5f4e925ef1a1f Mon Sep 17 00:00:00 2001 From: "Michael L. Young" Date: Thu, 28 Aug 2014 20:31:48 +0000 Subject: chan_iax2: Fix Dynamic IAX2 Registrations After Temporary DNS Failure 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 | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'channels/chan_iax2.c') diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 630a66342..a41f173b9 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -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(®->addr)) { + reg->addr.ss.ss_family = AST_AF_UNSPEC; + ast_dnsmgr_lookup(reg->hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL); + if (!ast_sockaddr_port(®->addr)) { + ast_sockaddr_set_port(®->addr, reg->port); + } else { + reg->port = ast_sockaddr_port(®->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, ®->addr, ®->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(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); + + reg->port = ast_sockaddr_port(®->addr); + + if (!porta && !reg->port) { + reg->port = IAX_DEFAULT_PORTNO; + } else if (porta) { + sscanf(porta, "%5d", ®->port); + } + + ast_sockaddr_set_port(®->addr, reg->port); AST_LIST_LOCK(®istrations); AST_LIST_INSERT_HEAD(®istrations, 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(®->addr) && reg->port) { + ast_sockaddr_set_port(®->addr, reg->port); + } if (!reg->callno) { -- cgit v1.2.3