]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 59258 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Tue, 27 Mar 2007 18:05:46 +0000 (18:05 +0000)
committerRussell Bryant <russell@russellbryant.com>
Tue, 27 Mar 2007 18:05:46 +0000 (18:05 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r59258 | russell | 2007-03-27 13:04:02 -0500 (Tue, 27 Mar 2007) | 4 lines

Fix the use of the "sourceaddress" option when "bindaddr" is set to 0.0.0.0
instead of having each interface explicitly listed.
(issue #7874, patch by stevens)

........

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

channels/chan_iax2.c

index 4e3bf6173ee62bad3fdfb520daf22d72b5bb420a..3f2a54fdf1387f6867db593461054d294586955d 100644 (file)
@@ -171,6 +171,7 @@ static int max_reg_expire;
 static int timingfd = -1;                              /* Timing file descriptor */
 
 static struct ast_netsock_list *netsock;
+static struct ast_netsock_list *outsock;               /*!< used if sourceaddress specified and bindaddr == INADDR_ANY */
 static int defaultsockfd = -1;
 
 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
@@ -8242,20 +8243,40 @@ static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
                if (res == 0) {
                        /* ip address valid. */
                        sin.sin_port = htons(port);
-                       sock = ast_netsock_find(netsock, &sin);
+                       if (!(sock = ast_netsock_find(netsock, &sin)))
+                               sock = ast_netsock_find(outsock, &sin);
                        if (sock) {
                                sockfd = ast_netsock_sockfd(sock);
                                nonlocal = 0;
+                       } else {
+                               unsigned int orig_saddr = sin.sin_addr.s_addr;
+                               /* INADDR_ANY matches anyway! */
+                               sin.sin_addr.s_addr = INADDR_ANY;
+                               if (ast_netsock_find(netsock, &sin)) {
+                                       sin.sin_addr.s_addr = orig_saddr;
+                                       sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
+                                       if (sock) {
+                                               sockfd = ast_netsock_sockfd(sock);
+                                               ast_netsock_unref(sock);
+                                               nonlocal = 0;
+                                       } else {
+                                               nonlocal = 2;
+                                       }
+                               }
                        }
                }
        }
                
        peer->sockfd = sockfd;
 
-       if (nonlocal) {
+       if (nonlocal == 1) {
                ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
                        srcaddr, peer->name);
                return -1;
+        } else if (nonlocal == 2) {
+               ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
+                       srcaddr, peer->name);
+                       return -1;
        } else {
                ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
                return 0;
@@ -9051,7 +9072,16 @@ static int set_config(char *config_file, int reload)
                        ast_netsock_unref(ns);
                }
        }
-       
+       if (reload) {
+               ast_netsock_release(outsock);
+               outsock = ast_netsock_list_alloc();
+               if (!outsock) {
+                       ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
+                       return -1;
+               }
+               ast_netsock_init(outsock);
+       }
+
        if (min_reg_expire > max_reg_expire) {
                ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
                        min_reg_expire, max_reg_expire, max_reg_expire);
@@ -9948,6 +9978,7 @@ static int __unload_module(void)
                usleep(10000);
        
        ast_netsock_release(netsock);
+       ast_netsock_release(outsock);
        for (x=0;x<IAX_MAX_CALLS;x++)
                if (iaxs[x])
                        iax2_destroy(x);
@@ -10023,6 +10054,13 @@ static int load_module(void)
        }
        ast_netsock_init(netsock);
 
+       outsock = ast_netsock_list_alloc();
+       if (!outsock) {
+               ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
+               return -1;
+       }
+       ast_netsock_init(outsock);
+
        ast_mutex_init(&waresl.lock);
 
        AST_LIST_HEAD_INIT(&iaxq.queue);
@@ -10053,6 +10091,7 @@ static int load_module(void)
        } else {
                ast_log(LOG_ERROR, "Unable to start network thread\n");
                ast_netsock_release(netsock);
+               ast_netsock_release(outsock);
        }
 
        AST_LIST_LOCK(&registrations);