]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/bnet_server.c
Real fix of bug #1897
[bacula/bacula] / bacula / src / lib / bnet_server.c
index fcd9483f1ce86e17400ae3345a0921af2ad3ebab..853c1c7e59b3dd1c428f1089569760a2d5f0f868 100644 (file)
@@ -1,12 +1,12 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
+   modify it under the terms of version three of the GNU Affero General Public
    License as published by the Free Software Foundation and included
    in the file LICENSE.
 
@@ -15,7 +15,7 @@
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public License
+   You should have received a copy of the GNU Affero General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
@@ -29,7 +29,6 @@
   * Originally written by Kern Sibbald for inclusion in apcupsd,
   *  but heavily modified for Bacula
   *
-  *   Version $Id$
   */
 
 #include "bacula.h"
@@ -42,7 +41,7 @@
 #include <arpa/nameser.h>
 #endif
 #ifdef HAVE_RESOLV_H
-#include <resolv.h>
+//#include <resolv.h>
 #endif
 
 
@@ -65,15 +64,16 @@ void bnet_stop_thread_server(pthread_t tid)
 }
 
 /*
-        Become Threaded Network Server
-    This function is able to handle multiple server ips in
-    ipv4 and ipv6 style. The Addresse are give in a comma
-    seperated string in bind_addr
-    In the moment it is inpossible to bind different ports.
-*/
-void
-bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
-                   void *handle_client_request(void *bsock))
+ * Become Threaded Network Server
+ *
+ * This function is able to handle multiple server ips in
+ * ipv4 and ipv6 style. The Addresse are give in a comma
+ * seperated string in bind_addr
+ *
+ * At the moment it is inpossible to bind different ports.
+ */
+void bnet_thread_server(dlist *addr_list, int max_clients, workq_t *client_wq,
+                        void *handle_client_request(void *bsock))
 {
    int newsockfd, stat;
    socklen_t clilen;
@@ -83,7 +83,7 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
 #ifdef HAVE_LIBWRAP
    struct request_info request;
 #endif
-   IPADDR *p;
+   IPADDR *ipaddr, *next;
    struct s_sockfd {
       dlink link;                     /* this MUST be the first item */
       int fd;
@@ -93,23 +93,39 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
    dlist sockfds;
 
    char allbuf[256 * 10];
-   Dmsg1(100, "Addresses %s\n", build_addresses_str(addrs, allbuf, sizeof(allbuf)));
 
-   foreach_dlist(p, addrs) {
+   /*
+    * Remove any duplicate addresses.
+    */
+   for (ipaddr = (IPADDR *)addr_list->first(); ipaddr;
+        ipaddr = (IPADDR *)addr_list->next(ipaddr)) {
+      for (next = (IPADDR *)addr_list->next(ipaddr); next;
+           next = (IPADDR *)addr_list->next(next)) {
+         if (ipaddr->get_sockaddr_len() == next->get_sockaddr_len() &&
+             memcmp(ipaddr->get_sockaddr(), next->get_sockaddr(),
+                    ipaddr->get_sockaddr_len()) == 0) {
+            addr_list->remove(next);
+         }
+      }
+   }
+
+   Dmsg1(100, "Addresses %s\n", build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
+
+   foreach_dlist(ipaddr, addr_list) {
       /* Allocate on stack from -- no need to free */
       fd_ptr = (s_sockfd *)alloca(sizeof(s_sockfd));
-      fd_ptr->port = p->get_port_net_order();
+      fd_ptr->port = ipaddr->get_port_net_order();
       /*
        * Open a TCP socket
        */
-      for (tlog= 60; (fd_ptr->fd=socket(p->get_family(), SOCK_STREAM, 0)) < 0; tlog -= 10) {
+      for (tlog= 60; (fd_ptr->fd=socket(ipaddr->get_family(), SOCK_STREAM, 0)) < 0; tlog -= 10) {
          if (tlog <= 0) {
             berrno be;
             char curbuf[256];
             Emsg3(M_ABORT, 0, _("Cannot open stream socket. ERR=%s. Current %s All %s\n"),
                        be.bstrerror(),
-                       p->build_address_str(curbuf, sizeof(curbuf)),
-                       build_addresses_str(addrs, allbuf, sizeof(allbuf)));
+                       ipaddr->build_address_str(curbuf, sizeof(curbuf)),
+                       build_addresses_str(addr_list, allbuf, sizeof(allbuf)));
          }
          bmicrosleep(10, 0);
       }
@@ -124,7 +140,7 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
       }
 
       int tmax = 30 * (60 / 5);    /* wait 30 minutes max */
-      for (tlog = 0; bind(fd_ptr->fd, p->get_sockaddr(), p->get_sockaddr_len()) < 0; tlog -= 5) {
+      for (tlog = 0; bind(fd_ptr->fd, ipaddr->get_sockaddr(), ipaddr->get_sockaddr_len()) < 0; tlog -= 5) {
          berrno be;
          if (tlog <= 0) {
             tlog = 2 * 60;         /* Complain every 2 minutes */
@@ -137,7 +153,7 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
                   be.bstrerror());
          }
       }
-      listen(fd_ptr->fd, 5);       /* tell system we are ready */
+      listen(fd_ptr->fd, 50);      /* tell system we are ready */
       sockfds.append(fd_ptr);
    }
    /* Start work queue thread */
@@ -208,7 +224,7 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
             sockaddr_to_ascii(&cli_addr, buf, sizeof(buf));
             V(mutex);
             BSOCK *bs;
-            bs = init_bsock(NULL, newsockfd, "client", buf, fd_ptr->port, &cli_addr);
+            bs = init_bsock(NULL, newsockfd, "client", buf, ntohs(fd_ptr->port), &cli_addr);
             if (bs == NULL) {
                Jmsg0(NULL, M_ABORT, 0, _("Could not create client BSOCK.\n"));
             }
@@ -238,5 +254,3 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
             be.bstrerror());
    }
 }
-
-