]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
ctdb-tcp: Factor out listening code to avoid repetition
authorMartin Schwenke <mschwenke@ddn.com>
Fri, 5 Jul 2024 05:51:25 +0000 (15:51 +1000)
committerVolker Lendecke <vl@samba.org>
Tue, 20 Aug 2024 13:06:33 +0000 (13:06 +0000)
Modernise debug and comments while here.

Signed-off-by: Martin Schwenke <mschwenke@ddn.com>
Reviewed-by: Volker Lendecke <vl@samba.org>
ctdb/tcp/tcp_connect.c

index 7d2a3e649eab38b482820c2fa71d2731465745b6..61f7918e3b5735e50956c3c34aae6d84dc8f1492 100644 (file)
@@ -386,24 +386,105 @@ static void ctdb_listen_event(struct tevent_context *ev, struct tevent_fd *fde,
        }
  }
 
+static int ctdb_tcp_listen_addr(struct ctdb_context *ctdb,
+                               ctdb_sock_addr *addr,
+                               bool strict)
+{
+       struct ctdb_tcp *ctcp = talloc_get_type_abort(
+               ctdb->transport_data, struct ctdb_tcp);
+       ctdb_sock_addr sock;
+       int sock_size;
+       int one = 1;
+       struct tevent_fd *fde = NULL;
+       int ret;
+
+       sock = *addr;
+       ctcp->listen_fd = -1;
+
+       switch (sock.sa.sa_family) {
+       case AF_INET:
+               sock_size = sizeof(sock.ip);
+               break;
+       case AF_INET6:
+               sock_size = sizeof(sock.ip6);
+               break;
+       default:
+               DBG_ERR("Unknown family %u\n", sock.sa.sa_family);
+               goto failed;
+       }
+
+       ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
+       if (ctcp->listen_fd == -1) {
+               DBG_ERR("Socket failed - %s (%d)\n", strerror(errno), errno);
+               goto failed;
+       }
+
+       set_close_on_exec(ctcp->listen_fd);
+
+       ret = setsockopt(ctcp->listen_fd,
+                        SOL_SOCKET,
+                        SO_REUSEADDR,
+                        (char *)&one,
+                        sizeof(one));
+       if (ret == -1) {
+               DBG_WARNING("Failed to set REUSEADDR on fd - %s (%d)\n",
+                           strerror(errno),
+                           errno);
+       }
+
+       ret =bind(ctcp->listen_fd, (struct sockaddr * )&sock, sock_size);
+       if (ret != 0) {
+               if (strict || errno != EADDRNOTAVAIL) {
+                       DBG_ERR("Failed to bind() to socket - %s (%d)\n",
+                               strerror(errno),
+                               errno);
+               } else {
+                       DBG_DEBUG("Failed to bind() to socket - %s (%d)\n",
+                                 strerror(errno),
+                                 errno);
+               }
+               goto failed;
+       }
+
+       ret = listen(ctcp->listen_fd, 10);
+       if (ret == -1) {
+               DBG_ERR("Failed to listen() on socket - %s (%d)\n",
+                       strerror(errno),
+                       errno);
+               goto failed;
+       }
+
+       fde = tevent_add_fd(ctdb->ev,
+                           ctcp,
+                           ctcp->listen_fd,
+                           TEVENT_FD_READ,
+                           ctdb_listen_event,
+                           ctdb);
+       tevent_fd_set_auto_close(fde);
+
+       return 0;
+
+failed:
+       if (ctcp->listen_fd != -1) {
+               close(ctcp->listen_fd);
+               ctcp->listen_fd = -1;
+       }
+       return -1;
+}
 
 /*
   automatically find which address to listen on
 */
 static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
 {
-       struct ctdb_tcp *ctcp = talloc_get_type(ctdb->transport_data,
-                                               struct ctdb_tcp);
-        ctdb_sock_addr sock;
        int lock_fd;
        unsigned int i;
        const char *lock_path = CTDB_RUNDIR "/.socket_lock";
        struct flock lock;
-       int one = 1;
-       int sock_size;
-       struct tevent_fd *fde;
+       int ret;
 
-       /* If there are no nodes, then it won't be possible to find
+       /*
+        * If there are no nodes, then it won't be possible to find
         * the first one.  Log a failure and short circuit the whole
         * process.
         */
@@ -412,13 +493,15 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
                return -1;
        }
 
-       /* in order to ensure that we don't get two nodes with the
-          same address, we must make the bind() and listen() calls
-          atomic. The SO_REUSEADDR setsockopt only prevents double
-          binds if the first socket is in LISTEN state  */
+       /*
+        * In order to ensure that we don't get two nodes with the
+        * same address, we must make the bind() and listen() calls
+        * atomic. The SO_REUSEADDR setsockopt only prevents double
+        * binds if the first socket is in LISTEN state.
+        */
        lock_fd = open(lock_path, O_RDWR|O_CREAT, 0666);
        if (lock_fd == -1) {
-               DEBUG(DEBUG_CRIT,("Unable to open %s\n", lock_path));
+               DBG_ERR("Unable to open %s\n", lock_path);
                return -1;
        }
 
@@ -429,7 +512,7 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
        lock.l_pid = 0;
 
        if (fcntl(lock_fd, F_SETLKW, &lock) != 0) {
-               DEBUG(DEBUG_CRIT,("Unable to lock %s\n", lock_path));
+               DBG_ERR("Unable to lock %s\n", lock_path);
                close(lock_fd);
                return -1;
        }
@@ -438,91 +521,36 @@ static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
                if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
                        continue;
                }
-               sock = ctdb->nodes[i]->address;
-
-               switch (sock.sa.sa_family) {
-               case AF_INET:
-                       sock_size = sizeof(sock.ip);
-                       break;
-               case AF_INET6:
-                       sock_size = sizeof(sock.ip6);
-                       break;
-               default:
-                       DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
-                               sock.sa.sa_family));
-                       continue;
-               }
-
-               ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
-               if (ctcp->listen_fd == -1) {
-                       ctdb_set_error(ctdb, "socket failed\n");
-                       continue;
-               }
-
-               set_close_on_exec(ctcp->listen_fd);
-
-               if (setsockopt(ctcp->listen_fd,SOL_SOCKET,SO_REUSEADDR,
-                              (char *)&one,sizeof(one)) == -1) {
-                       DEBUG(DEBUG_WARNING, ("Failed to set REUSEADDR on fd - %s\n",
-                                             strerror(errno)));
-               }
 
-               if (bind(ctcp->listen_fd, (struct sockaddr * )&sock, sock_size) == 0) {
+               ret = ctdb_tcp_listen_addr(ctdb,
+                                          &ctdb->nodes[i]->address,
+                                          false);
+               if (ret == 0) {
                        break;
                }
-
-               if (errno == EADDRNOTAVAIL) {
-                       DEBUG(DEBUG_DEBUG,(__location__ " Failed to bind() to socket. %s(%d)\n",
-                                       strerror(errno), errno));
-               } else {
-                       DEBUG(DEBUG_ERR,(__location__ " Failed to bind() to socket. %s(%d)\n",
-                                       strerror(errno), errno));
-               }
-
-               close(ctcp->listen_fd);
-               ctcp->listen_fd = -1;
        }
 
        if (i == ctdb->num_nodes) {
-               DEBUG(DEBUG_CRIT,("Unable to bind to any of the node addresses - giving up\n"));
-               goto failed;
+               D_ERR("Unable to bind to any node address - giving up\n");
+               return -1;
        }
+
        ctdb->address = talloc_memdup(ctdb,
                                      &ctdb->nodes[i]->address,
                                      sizeof(ctdb_sock_addr));
        if (ctdb->address == NULL) {
-               ctdb_set_error(ctdb, "Out of memory at %s:%d",
-                              __FILE__, __LINE__);
-               goto failed;
+               DBG_ERR("Memory allocation error\n");
+               return -1;
        }
 
        ctdb->name = talloc_strdup(ctdb, ctdb->nodes[i]->name);
        if (ctdb->name == NULL) {
-               ctdb_set_error(ctdb, "Out of memory at %s:%d",
-                              __FILE__, __LINE__);
-               goto failed;
-       }
-       DEBUG(DEBUG_INFO,("ctdb chose network address %s\n", ctdb->name));
-
-       if (listen(ctcp->listen_fd, 10) == -1) {
-               goto failed;
+               DBG_ERR("Memory allocation error\n");
+               return -1;
        }
 
-       fde = tevent_add_fd(ctdb->ev, ctcp, ctcp->listen_fd, TEVENT_FD_READ,
-                           ctdb_listen_event, ctdb);
-       tevent_fd_set_auto_close(fde);
-
-       close(lock_fd);
-
+       D_INFO("ctdb chose network address %s\n", ctdb->name);
        return 0;
-
-failed:
-       close(lock_fd);
-       if (ctcp->listen_fd != -1) {
-               close(ctcp->listen_fd);
-               ctcp->listen_fd = -1;
-       }
-       return -1;
 }
 
 
@@ -531,67 +559,15 @@ failed:
 */
 int ctdb_tcp_listen(struct ctdb_context *ctdb)
 {
-       struct ctdb_tcp *ctcp = talloc_get_type(ctdb->transport_data,
-                                               struct ctdb_tcp);
-        ctdb_sock_addr sock;
-       int sock_size;
-       int one = 1;
-       struct tevent_fd *fde;
+       int ret;
 
        /* we can either auto-bind to the first available address, or we can
           use a specified address */
        if (!ctdb->address) {
-               return ctdb_tcp_listen_automatic(ctdb);
-       }
-
-       sock = *ctdb->address;
-
-       switch (sock.sa.sa_family) {
-       case AF_INET:
-               sock_size = sizeof(sock.ip);
-               break;
-       case AF_INET6:
-               sock_size = sizeof(sock.ip6);
-               break;
-       default:
-               DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
-                       sock.sa.sa_family));
-               goto failed;
-       }
-
-       ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
-       if (ctcp->listen_fd == -1) {
-               ctdb_set_error(ctdb, "socket failed\n");
-               return -1;
-       }
-
-       set_close_on_exec(ctcp->listen_fd);
-
-        if (setsockopt(ctcp->listen_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)) == -1) {
-               DEBUG(DEBUG_WARNING, ("Failed to set REUSEADDR on fd - %s\n",
-                                     strerror(errno)));
+               ret = ctdb_tcp_listen_automatic(ctdb);
+               return ret;
        }
 
-       if (bind(ctcp->listen_fd, (struct sockaddr * )&sock, sock_size) != 0) {
-               DEBUG(DEBUG_ERR,(__location__ " Failed to bind() to socket. %s(%d)\n", strerror(errno), errno));
-               goto failed;
-       }
-
-       if (listen(ctcp->listen_fd, 10) == -1) {
-               goto failed;
-       }
-
-       fde = tevent_add_fd(ctdb->ev, ctcp, ctcp->listen_fd, TEVENT_FD_READ,
-                           ctdb_listen_event, ctdb);
-       tevent_fd_set_auto_close(fde);
-
-       return 0;
-
-failed:
-       if (ctcp->listen_fd != -1) {
-               close(ctcp->listen_fd);
-       }
-       ctcp->listen_fd = -1;
-       return -1;
+       ret = ctdb_tcp_listen_addr(ctdb, ctdb->address, true);
+       return ret;
 }
-