krb5 commit: Remove struct socksetup from net-server.c

Greg Hudson <[email protected]>
Newsgroups gmane.comp.encryption.kerberos.cvs
Message-ID <[email protected]>
https://github.com/krb5/krb5/commit/d3db37a8d6d88a09a3c1fc73a2501cc0aec1fea1
commit d3db37a8d6d88a09a3c1fc73a2501cc0aec1fea1
Author: Greg Hudson <[email protected]>
Date:   Mon Jan 2 14:10:12 2017 -0500

    Remove struct socksetup from net-server.c
    
    struct socksetup was required when we iterated over local addresses
    using foreach_localaddr.  Since we no longer do that (ticket 8348),
    the functions which use it can simply accept the parameters they
    require and return error codes.

 src/lib/apputils/net-server.c |  183 ++++++++++++++++-------------------------
 1 files changed, 70 insertions(+), 113 deletions(-)

diff --git a/src/lib/apputils/net-server.c b/src/lib/apputils/net-server.c
index 92192d2..c707a4e 100644
--- a/src/lib/apputils/net-server.c
+++ b/src/lib/apputils/net-server.c
@@ -440,14 +440,6 @@ loop_add_rpc_service(int default_port, const char *addresses, u_long prognum,
 #define SOCKET_ERRNO errno
 #include "foreachaddr.h"
 
-struct socksetup {
-    verto_ctx *ctx;
-    void *handle;
-    const char *prog;
-    krb5_error_code retval;
-    int listen_backlog;
-};
-
 static void
 free_connection(struct connection *conn)
 {
@@ -545,33 +537,34 @@ make_event(verto_ctx *ctx, verto_ev_flag flags, verto_callback callback,
     return ev;
 }
 
-static verto_ev *
-add_fd(struct socksetup *data, int sock, enum conn_type conntype,
-       verto_ev_flag flags, verto_callback callback, int addevent)
+static krb5_error_code
+add_fd(int sock, enum conn_type conntype, verto_ev_flag flags, void *handle,
+       const char *prog, verto_ctx *ctx, verto_callback callback, int addevent,
+       verto_ev **ev_out)
 {
     struct connection *newconn;
 
+    *ev_out = NULL;
+
 #ifndef _WIN32
     if (sock >= FD_SETSIZE) {
-        data->retval = EMFILE;  /* XXX */
-        com_err(data->prog, 0,
-                _("file descriptor number %d too high"), sock);
-        return 0;
+        com_err(prog, 0, _("file descriptor number %d too high"), sock);
+        return EMFILE;
     }
 #endif
     newconn = malloc(sizeof(*newconn));
     if (newconn == NULL) {
-        data->retval = ENOMEM;
-        com_err(data->prog, ENOMEM,
+        com_err(prog, ENOMEM,
                 _("cannot allocate storage for connection info"));
-        return 0;
+        return ENOMEM;
     }
     memset(newconn, 0, sizeof(*newconn));
-    newconn->handle = data->handle;
-    newconn->prog = data->prog;
+    newconn->handle = handle;
+    newconn->prog = prog;
     newconn->type = conntype;
 
-    return make_event(data->ctx, flags, callback, sock, newconn, addevent);
+    *ev_out = make_event(ctx, flags, callback, sock, newconn, addevent);
+    return 0;
 }
 
 static void process_packet(verto_ctx *ctx, verto_ev *ev);
@@ -581,77 +574,62 @@ static void process_tcp_connection_write(verto_ctx *ctx, verto_ev *ev);
 static void accept_rpc_connection(verto_ctx *ctx, verto_ev *ev);
 static void process_rpc_connection(verto_ctx *ctx, verto_ev *ev);
 
-static verto_ev *
-add_tcp_read_fd(struct socksetup *data, int sock)
-{
-    return add_fd(data, sock, CONN_TCP,
-                  VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
-                  process_tcp_connection_read, 1);
-}
-
 /*
  * Create a socket and bind it to addr.  Ensure the socket will work with
  * select().  Set the socket cloexec, reuseaddr, and if applicable v6-only.
- * Does not call listen().  Returns -1 on failure after logging an error.
+ * Does not call listen().  On failure, log an error and return an error code.
  */
-static int
-create_server_socket(struct socksetup *data, struct sockaddr *addr, int type)
+static krb5_error_code
+create_server_socket(struct sockaddr *addr, int type, const char *prog,
+                     int *fd_out)
 {
-    int sock;
+    int sock, e;
+
+    *fd_out = -1;
 
     sock = socket(addr->sa_family, type, 0);
     if (sock == -1) {
-        data->retval = errno;
-        com_err(data->prog, errno, _("Cannot create TCP server socket on %s"),
+        e = errno;
+        com_err(prog, e, _("Cannot create TCP server socket on %s"),
                 paddr(addr));
-        return -1;
+        return e;
     }
     set_cloexec_fd(sock);
 
 #ifndef _WIN32                  /* Windows FD_SETSIZE is a count. */
     if (sock >= FD_SETSIZE) {
         close(sock);
-        com_err(data->prog, 0, _("TCP socket fd number %d (for %s) too high"),
+        com_err(prog, 0, _("TCP socket fd number %d (for %s) too high"),
                 sock, paddr(addr));
-        return -1;
+        return EMFILE;
     }
 #endif
 
-    if (setreuseaddr(sock, 1) < 0) {
-        com_err(data->prog, errno,
-                _("Cannot enable SO_REUSEADDR on fd %d"), sock);
-    }
+    if (setreuseaddr(sock, 1) < 0)
+        com_err(prog, errno, _("Cannot enable SO_REUSEADDR on fd %d"), sock);
 
     if (addr->sa_family == AF_INET6) {
 #ifdef IPV6_V6ONLY
-        if (setv6only(sock, 1))
-            com_err(data->prog, errno,
-                    _("setsockopt(%d,IPV6_V6ONLY,1) failed"), sock);
-        else
-            com_err(data->prog, 0, _("setsockopt(%d,IPV6_V6ONLY,1) worked"),
+        if (setv6only(sock, 1)) {
+            com_err(prog, errno, _("setsockopt(%d,IPV6_V6ONLY,1) failed"),
                     sock);
+        } else {
+            com_err(prog, 0, _("setsockopt(%d,IPV6_V6ONLY,1) worked"), sock);
+        }
 #else
         krb5_klog_syslog(LOG_INFO, _("no IPV6_V6ONLY socket option support"));
 #endif /* IPV6_V6ONLY */
     }
 
     if (bind(sock, addr, sa_socklen(addr)) == -1) {
-        data->retval = errno;
-        com_err(data->prog, errno, _("Cannot bind server socket on %s"),
-                paddr(addr));
+        e = errno;
+        com_err(prog, e, _("Cannot bind server socket on %s"), paddr(addr));
         close(sock);
-        return -1;
+        return e;
     }
 
-    return sock;
-}
-
-static verto_ev *
-add_rpc_data_fd(struct socksetup *data, int sock)
-{
-    return add_fd(data, sock, CONN_RPC,
-                  VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST,
-                  process_rpc_connection, 1);
+    *fd_out = sock;
+    return 0;
 }
 
 static const int one = 1;
@@ -705,12 +683,13 @@ static const enum conn_type bind_conn_types[] =
  *      The conn_type of this socket.
  */
 static krb5_error_code
-setup_socket(struct socksetup *data, struct bind_address *ba,
-             struct sockaddr *sock_address, verto_callback vcb,
-             enum conn_type ctype)
+setup_socket(struct bind_address *ba, struct sockaddr *sock_address,
+             void *handle, const char *prog, verto_ctx *ctx,
+             int tcp_listen_backlog, verto_callback vcb, enum conn_type ctype)
 {
     krb5_error_code ret;
     struct connection *conn;
+    verto_ev_flag flags;
     verto_ev *ev = NULL;
     int sock = -1;
 
@@ -718,18 +697,16 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
                      bind_type_names[ba->type], paddr(sock_address));
 
     /* Create the socket. */
-    sock = create_server_socket(data, sock_address, bind_socktypes[ba->type]);
-    if (sock == -1) {
-        ret = data->retval;
+    ret = create_server_socket(sock_address, bind_socktypes[ba->type], prog,
+                               &sock);
+    if (ret)
         goto cleanup;
-    }
 
     /* Listen for backlogged connections on TCP sockets.  (For RPC sockets this
      * will be done by svc_register().) */
-    if (ba->type == TCP && listen(sock, data->listen_backlog) != 0) {
+    if (ba->type == TCP && listen(sock, tcp_listen_backlog) != 0) {
         ret = errno;
-        com_err(data->prog, errno,
-                _("Cannot listen on %s server socket on %s"),
+        com_err(prog, errno, _("Cannot listen on %s server socket on %s"),
                 bind_type_names[ba->type], paddr(sock_address));
         goto cleanup;
     }
@@ -737,7 +714,7 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
     /* Set non-blocking I/O for UDP and TCP listener sockets. */
     if (ba->type != RPC && setnbio(sock) != 0) {
         ret = errno;
-        com_err(data->prog, errno,
+        com_err(prog, errno,
                 _("cannot set listening %s socket on %s non-blocking"),
                 bind_type_names[ba->type], paddr(sock_address));
         goto cleanup;
@@ -746,8 +723,7 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
     /* Turn off the linger option for TCP sockets. */
     if (ba->type == TCP && setnolinger(sock) != 0) {
         ret = errno;
-        com_err(data->prog, errno,
-                _("cannot set SO_LINGER on %s socket on %s"),
+        com_err(prog, errno, _("cannot set SO_LINGER on %s socket on %s"),
                 bind_type_names[ba->type], paddr(sock_address));
         goto cleanup;
     }
@@ -758,7 +734,7 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
                          paddr(sock_address));
         ret = set_pktinfo(sock, sock_address->sa_family);
         if (ret) {
-            com_err(data->prog, ret,
+            com_err(prog, ret,
                     _("Cannot request packet info for UDP socket address "
                       "%s port %d"), paddr(sock_address), ba->port);
             krb5_klog_syslog(LOG_INFO, _("System does not support pktinfo yet "
@@ -769,13 +745,11 @@ setup_socket(struct socksetup *data, struct bind_address *ba,
     }
 
     /* Add the socket to the event loop. */
-    ev = add_fd(data, sock, ctype,
-                VERTO_EV_FLAG_IO_READ |
-                VERTO_EV_FLAG_PERSIST |
-                VERTO_EV_FLAG_REINITIABLE, vcb, 1);
-    if (ev == NULL) {
+    flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST |
+        VERTO_EV_FLAG_REINITIABLE;
+    ret = add_fd(sock, ctype, flags, handle, prog, ctx, vcb, 1, &ev);
+    if (ret) {
         krb5_klog_syslog(LOG_ERR, _("Error attempting to add verto event"));
-        ret = data->retval;
         goto cleanup;
     }
 
@@ -818,13 +792,10 @@ cleanup:
  * This function uses getaddrinfo to figure out all the addresses. This will
  * automatically figure out which socket families that should be used on the
  * host making it useful even for wildcard addresses.
- *
- * Arguments:
- * - data
- *      A pointer to the socksetup data.
  */
 static krb5_error_code
-setup_addresses(struct socksetup *data)
+setup_addresses(verto_ctx *ctx, void *handle, const char *prog,
+                int tcp_listen_backlog)
 {
     /* An bind_type enum map for the verto callback functions. */
     static verto_callback *const verto_callbacks[] = {
@@ -885,8 +856,8 @@ setup_addresses(struct socksetup *data)
             /* Set the real port number. */
             sa_setport(ai->ai_addr, addr.port);
 
-            ret = setup_socket(data, &addr, ai->ai_addr,
-                               verto_callbacks[addr.type],
+            ret = setup_socket(&addr, ai->ai_addr, handle, prog, ctx,
+                               tcp_listen_backlog, verto_callbacks[addr.type],
                                bind_conn_types[addr.type]);
             if (ret) {
                 krb5_klog_syslog(LOG_ERR,
@@ -918,9 +889,9 @@ krb5_error_code
 loop_setup_network(verto_ctx *ctx, void *handle, const char *prog,
                    int tcp_listen_backlog)
 {
-    struct socksetup setup_data;
+    krb5_error_code ret;
     verto_ev *ev;
-    int i, ret;
+    int i;
 
     /* Check to make sure that at least one address was added to the loop. */
     if (bind_addresses.n == 0)
@@ -931,15 +902,9 @@ loop_setup_network(verto_ctx *ctx, void *handle, const char *prog,
         verto_del(ev);
     events.n = 0;
 
-    setup_data.ctx = ctx;
-    setup_data.handle = handle;
-    setup_data.prog = prog;
-    setup_data.retval = 0;
-    setup_data.listen_backlog = tcp_listen_backlog;
-
     krb5_klog_syslog(LOG_INFO, _("setting up network..."));
-    ret = setup_addresses(&setup_data);
-    if (ret != 0) {
+    ret = setup_addresses(ctx, handle, prog, tcp_listen_backlog);
+    if (ret) {
         com_err(prog, ret, _("Error setting up network"));
         exit(1);
     }
@@ -1175,9 +1140,9 @@ accept_tcp_connection(verto_ctx *ctx, verto_ev *ev)
     struct sockaddr_storage addr_s;
     struct sockaddr *addr = (struct sockaddr *)&addr_s;
     socklen_t addrlen = sizeof(addr_s);
-    struct socksetup sockdata;
     struct connection *newconn, *conn;
     char tmpbuf[10];
+    verto_ev_flag flags;
     verto_ev *newev;
 
     conn = verto_get_private(ev);
@@ -1193,13 +1158,9 @@ accept_tcp_connection(verto_ctx *ctx, verto_ev *ev)
 #endif
     setnbio(s), setnolinger(s), setkeepalive(s);
 
-    sockdata.ctx = ctx;
-    sockdata.handle = conn->handle;
-    sockdata.prog = conn->prog;
-    sockdata.retval = 0;
-
-    newev = add_tcp_read_fd(&sockdata, s);
-    if (newev == NULL) {
+    flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST;
+    if (add_fd(s, CONN_TCP, flags, conn->handle, conn->prog, ctx,
+               process_tcp_connection_read, 1, &newev) != 0) {
         close(s);
         return;
     }
@@ -1478,18 +1439,13 @@ have_event_for_fd(int fd)
 static void
 accept_rpc_connection(verto_ctx *ctx, verto_ev *ev)
 {
-    struct socksetup sockdata;
+    verto_ev_flag flags;
     struct connection *conn;
     fd_set fds;
     register int s;
 
     conn = verto_get_private(ev);
 
-    sockdata.ctx = ctx;
-    sockdata.handle = conn->handle;
-    sockdata.prog = conn->prog;
-    sockdata.retval = 0;
-
     /* Service the woken RPC listener descriptor. */
     FD_ZERO(&fds);
     FD_SET(verto_get_fd(ev), &fds);
@@ -1508,8 +1464,9 @@ accept_rpc_connection(verto_ctx *ctx, verto_ev *ev)
         if (!FD_ISSET(s, &svc_fdset) || have_event_for_fd(s))
             continue;
 
-        newev = add_rpc_data_fd(&sockdata, s);
-        if (newev == NULL)
+        flags = VERTO_EV_FLAG_IO_READ | VERTO_EV_FLAG_PERSIST;
+        if (add_fd(s, CONN_RPC, flags, conn->handle, conn->prog, ctx,
+                   process_rpc_connection, 1, &newev) != 0)
             continue;
         newconn = verto_get_private(newev);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.