]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/bnet_server.c
Fix compiler warning noted in bug #2309
[bacula/bacula] / bacula / src / lib / bnet_server.c
index 598d003741ffeb63fc7ddba007d8f5e852c28c45..0144047d28f5e8212b09b4a776ed35e5687e05c1 100644 (file)
@@ -1,29 +1,20 @@
 /*
-   Bacula® - The Network Backup Solution
-
-   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 three of the GNU Affero General Public
-   License as published by the Free Software Foundation and included
-   in the file LICENSE.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   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 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.
-
-   Bacula® is a registered trademark of Kern Sibbald.
-   The licensor of Bacula is the Free Software Foundation Europe
-   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
-   Switzerland, email:ftf@fsfeurope.org.
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2016 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
  /*
   * Originally written by Kern Sibbald for inclusion in apcupsd,
@@ -63,26 +54,25 @@ 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
+     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))
 {
    int newsockfd, stat;
    socklen_t clilen;
-   struct sockaddr cli_addr;       /* client's address */
+   struct sockaddr_storage clientaddr;   /* client's address */
    int tlog;
    int turnon = 1;
 #ifdef HAVE_LIBWRAP
    struct request_info request;
 #endif
-   IPADDR *p;
+   IPADDR *addr;
    struct s_sockfd {
       dlink link;                     /* this MUST be the first item */
       int fd;
@@ -92,22 +82,25 @@ 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_duplicate_addresses(addrs);
+   Dmsg1(20, "Addresses %s\n", build_addresses_str(addrs, allbuf, sizeof(allbuf)));
+   /*
+    * Listen on each address provided.
+    */
+   foreach_dlist(addr, addrs) {
       /* 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 = addr->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(addr->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)),
+                       addr->build_address_str(curbuf, sizeof(curbuf)),
                        build_addresses_str(addrs, allbuf, sizeof(allbuf)));
          }
          bmicrosleep(10, 0);
@@ -122,22 +115,35 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
                be.bstrerror());
       }
 
-      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) {
+      int tmax = 1 * (60 / 5);    /* wait 1 minute max */
+      for (tlog = 0; bind(fd_ptr->fd, addr->get_sockaddr(), addr->get_sockaddr_len()) == SOCKET_ERROR; tlog -= 5) {
          berrno be;
          if (tlog <= 0) {
-            tlog = 2 * 60;         /* Complain every 2 minutes */
+            tlog = 1 * 60;         /* Complain every 1 minute */
             Emsg2(M_WARNING, 0, _("Cannot bind port %d: ERR=%s: Retrying ...\n"),
                   ntohs(fd_ptr->port), be.bstrerror());
+            Dmsg2(20, "Cannot bind port %d: ERR=%s: Retrying ...\n",
+                  ntohs(fd_ptr->port), be.bstrerror());
+
          }
          bmicrosleep(5, 0);
          if (--tmax <= 0) {
             Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), ntohs(fd_ptr->port),
                   be.bstrerror());
+            Pmsg2(000, "Aborting cannot bind port %d: ERR=%s.\n", ntohs(fd_ptr->port),
+                  be.bstrerror());
          }
       }
-      listen(fd_ptr->fd, 50);      /* tell system we are ready */
-      sockfds.append(fd_ptr);
+      if (listen(fd_ptr->fd, 50) < 0) {      /* tell system we are ready */
+         berrno be;
+         Emsg2(M_ABORT, 0, _("Cannot bind port %d: ERR=%s.\n"), ntohs(fd_ptr->port),
+               be.bstrerror());
+      } else {
+         sockfds.append(fd_ptr);
+      }
+   }
+   if (sockfds.size() == 0) {
+      Emsg0(M_ABORT, 0, _("No addr/port found to listen on.\n"));
    }
    /* Start work queue thread */
    if ((stat = workq_init(client_wq, max_clients, handle_client_request)) != 0) {
@@ -170,10 +176,12 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
          if (FD_ISSET(fd_ptr->fd, &sockset)) {
             /* Got a connection, now accept it. */
             do {
-               clilen = sizeof(cli_addr);
-               newsockfd = accept(fd_ptr->fd, &cli_addr, &clilen);
-            } while (newsockfd < 0 && errno == EINTR);
-            if (newsockfd < 0) {
+               clilen = sizeof(clientaddr);
+               newsockfd = baccept(fd_ptr->fd, (struct sockaddr *)&clientaddr, &clilen);
+               newsockfd = set_socket_errno(newsockfd);
+            } while (newsockfd == SOCKET_ERROR && (errno == EINTR || errno == EAGAIN));
+            if (newsockfd == SOCKET_ERROR) {
+               Dmsg2(20, "Accept=%d errno=%d\n", newsockfd, errno);
                continue;
             }
 #ifdef HAVE_LIBWRAP
@@ -184,8 +192,9 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
                V(mutex);
                Jmsg2(NULL, M_SECURITY, 0,
                      _("Connection from %s:%d refused by hosts.access\n"),
-                     sockaddr_to_ascii(&cli_addr, buf, sizeof(buf)),
-                     sockaddr_get_port(&cli_addr));
+                     sockaddr_to_ascii((struct sockaddr *)&clientaddr,
+                                       sizeof(clientaddr), buf, sizeof(buf)),
+                     sockaddr_get_port((struct sockaddr *)&clientaddr));
                close(newsockfd);
                continue;
             }
@@ -204,10 +213,11 @@ bnet_thread_server(dlist *addrs, int max_clients, workq_t *client_wq,
 
             /* see who client is. i.e. who connected to us. */
             P(mutex);
-            sockaddr_to_ascii(&cli_addr, buf, sizeof(buf));
+            sockaddr_to_ascii((struct sockaddr *)&clientaddr, sizeof(clientaddr), 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),
+                    (struct sockaddr *)&clientaddr);
             if (bs == NULL) {
                Jmsg0(NULL, M_ABORT, 0, _("Could not create client BSOCK.\n"));
             }