]> git.sur5r.net Git - bacula/bacula/commitdiff
First try at fixing bug #1897
authorMarco van Wieringen <mvw@planets.elm.net>
Mon, 25 Jun 2012 17:42:28 +0000 (19:42 +0200)
committerKern Sibbald <kern@sibbald.com>
Sat, 20 Apr 2013 12:50:51 +0000 (14:50 +0200)
Remove any duplicate addresses on a addr dlist.
For listening it makes no sense as we cannot listen
multiple times on the same address with different sockets.
And for outbound connecting its also kind of strange to
try to connect multiple times to the same address.

bacula/src/lib/bnet_server.c
bacula/src/lib/bsock.c
bacula/src/lib/protos.h

index 093941728171e16bebf23bf77544b0a630f036ad..32dbe7ae375fbe9254eded770d9aaf79e02b0b7f 100644 (file)
@@ -64,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;
@@ -82,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;
@@ -92,23 +93,37 @@ 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())) {
+            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);
       }
@@ -123,7 +138,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 */
index 0eeb74be483327ba3c17e9f936812aa244deb7f2..c630bfbaf28d2026fa360f30091afdce48c80c68 100644 (file)
@@ -192,7 +192,7 @@ bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service,
 {
    int sockfd = -1;
    dlist *addr_list;
-   IPADDR *ipaddr;
+   IPADDR *ipaddr, *next;
    bool connected = false;
    int turnon = 1;
    const char *errstr;
@@ -212,6 +212,19 @@ bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service,
       return false;
    }
 
+   /*
+    * 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())) {
+            addr_list->remove(next);
+         }
+      }
+   }
+
    foreach_dlist(ipaddr, addr_list) {
       ipaddr->set_port_net(htons(port));
       char allbuf[256 * 10];
index e161158b4d0b93da8f3026d85a6ece6d1239a0a5..c956eccb354e321a149621423d5629c5c7a8c3ad 100644 (file)
@@ -246,7 +246,7 @@ void       set_db_type           (const char *name);
 void       register_message_callback(void msg_callback(int type, char *msg));
 
 /* bnet_server.c */
-void       bnet_thread_server(dlist *addr, int max_clients, workq_t *client_wq,
+void       bnet_thread_server(dlist *addr_list, int max_clients, workq_t *client_wq,
                    void *handle_client_request(void *bsock));
 void       bnet_stop_thread_server(pthread_t tid);
 void             bnet_server             (int port, void handle_client_request(BSOCK *bsock));