s3-prefork: Return tsocket_address for client and server
authorSimo Sorce <idra@samba.org>
Tue, 19 Jul 2011 19:07:42 +0000 (15:07 -0400)
committerAndreas Schneider <asn@samba.org>
Wed, 10 Aug 2011 16:14:04 +0000 (18:14 +0200)
Signed-off-by: Andreas Schneider <asn@samba.org>
source3/lib/server_prefork.c
source3/lib/server_prefork.h
source3/printing/spoolssd.c

index bc0f4c725ea12d5aeede6dce1298067f18893dbd..47020b274064ff14bba913b1063dd9027cff6ff7 100644 (file)
@@ -716,11 +716,11 @@ struct pf_listen_state {
 
        int lock_fd;
 
-       struct sockaddr *addr;
-       socklen_t *addrlen;
-
        int accept_fd;
 
+       struct tsocket_address *srv_addr;
+       struct tsocket_address *cli_addr;
+
        int error;
 };
 
@@ -735,9 +735,7 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx,
                                        struct pf_worker_data *pf,
                                        int listen_fd_size,
                                        int *listen_fds,
-                                       int lock_fd,
-                                       struct sockaddr *addr,
-                                       socklen_t *addrlen)
+                                       int lock_fd)
 {
        struct tevent_req *req, *subreq;
        struct pf_listen_state *state;
@@ -752,8 +750,6 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx,
        state->lock_fd = lock_fd;
        state->listen_fd_size = listen_fd_size;
        state->listen_fds = listen_fds;
-       state->addr = addr;
-       state->addrlen = addrlen;
        state->accept_fd = -1;
        state->error = 0;
 
@@ -823,13 +819,18 @@ static void prefork_listen_accept_handler(struct tevent_context *ev,
        struct pf_listen_state *state;
        struct tevent_req *req, *subreq;
        struct pf_listen_ctx *ctx;
+       struct sockaddr_storage addr;
+       socklen_t addrlen;
        int err = 0;
        int sd = -1;
+       int ret;
 
        ctx = talloc_get_type_abort(pvt, struct pf_listen_ctx);
        state = tevent_req_data(ctx->req, struct pf_listen_state);
 
-       sd = accept(ctx->listen_fd, state->addr, state->addrlen);
+       ZERO_STRUCT(addr);
+       addrlen = sizeof(addr);
+       sd = accept(ctx->listen_fd, (struct sockaddr *)&addr, &addrlen);
        if (sd == -1) {
                if (errno == EINTR) {
                        /* keep trying */
@@ -837,7 +838,6 @@ static void prefork_listen_accept_handler(struct tevent_context *ev,
                }
                err = errno;
                DEBUG(6, ("Accept failed! (%d, %s)\n", err, strerror(err)));
-
        }
 
        /* do not track the listen fds anymore */
@@ -845,12 +845,37 @@ static void prefork_listen_accept_handler(struct tevent_context *ev,
        talloc_free(ctx->fde_ctx);
        ctx = NULL;
        if (err) {
-               tevent_req_error(req, err);
-               return;
+               state->error = err;
+               goto done;
        }
 
        state->accept_fd = sd;
 
+       ret = tsocket_address_bsd_from_sockaddr(state,
+                                       (struct sockaddr *)(void *)&addr,
+                                       addrlen, &state->cli_addr);
+       if (ret < 0) {
+               state->error = errno;
+               goto done;
+       }
+
+       ZERO_STRUCT(addr);
+       addrlen = sizeof(addr);
+       ret = getsockname(sd, (struct sockaddr *)(void *)&addr, &addrlen);
+       if (ret < 0) {
+               state->error = errno;
+               goto done;
+       }
+
+       ret = tsocket_address_bsd_from_sockaddr(state,
+                                       (struct sockaddr *)(void *)&addr,
+                                       addrlen, &state->srv_addr);
+       if (ret < 0) {
+               state->error = errno;
+               goto done;
+       }
+
+done:
        /* release lock now */
        subreq = prefork_lock_send(state, state->ev, state->pf,
                                   state->lock_fd, PF_ASYNC_LOCK_RELEASE);
@@ -876,20 +901,30 @@ static void prefork_listen_release_done(struct tevent_req *subreq)
        tevent_req_done(req);
 }
 
-int prefork_listen_recv(struct tevent_req *req, int *fd)
+int prefork_listen_recv(struct tevent_req *req,
+                       TALLOC_CTX *mem_ctx, int *fd,
+                       struct tsocket_address **srv_addr,
+                       struct tsocket_address **cli_addr)
 {
        struct pf_listen_state *state;
-       int ret;
+       int ret = 0;
 
        state = tevent_req_data(req, struct pf_listen_state);
 
-       if (tevent_req_is_unix_error(req, &ret)) {
+       if (state->error) {
+               ret = state->error;
+       } else {
+               tevent_req_is_unix_error(req, &ret);
+       }
+
+       if (ret) {
                if (state->accept_fd != -1) {
                        close(state->accept_fd);
                }
        } else {
                *fd = state->accept_fd;
-               ret = 0;
+               *srv_addr = talloc_move(mem_ctx, &state->srv_addr);
+               *cli_addr = talloc_move(mem_ctx, &state->cli_addr);
                state->pf->status = PF_WORKER_BUSY;
                state->pf->num_clients++;
        }
index 2f25e557fab6a7e921f635a895ece4d515e48cb8..d3ba919950fa7028351bd10a1ba875c34a32087a 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "system/network.h"
 #include <tevent.h>
+#include "lib/tsocket/tsocket.h"
 
 struct prefork_pool;
 
@@ -238,9 +239,6 @@ void prefork_set_sigchld_callback(struct prefork_pool *pfp,
 * @param listen_fd_size        The number of listening file descriptors
 * @param listen_fds    The array of listening file descriptors
 * @param lock_fd       The locking file descriptor
-* @param addr          The structure that will hold the client address on
-*                      return
-* @param addrlen       The structure length on return.
 *
 * @return The tevent request pointer or NULL on allocation errors.
 */
@@ -249,16 +247,21 @@ struct tevent_req *prefork_listen_send(TALLOC_CTX *mem_ctx,
                                        struct pf_worker_data *pf,
                                        int listen_fd_size,
                                        int *listen_fds,
-                                       int lock_fd,
-                                       struct sockaddr *addr,
-                                       socklen_t *addrlen);
+                                       int lock_fd);
 /**
 * @brief Returns the file descriptor after the new client connection has
 *       been accepted.
 *
-* @param req   The request
-* @param fd    The new file descriptor.
+* @param req           The request
+* @param mem_ctx       The memory context for cli_addr and srv_addr
+* @param fd            The new file descriptor.
+* @param srv_addr      The server address in tsocket_address format
+* @param cli_addr      The client address in tsocket_address format
 *
 * @return      The error in case the operation failed.
 */
-int prefork_listen_recv(struct tevent_req *req, int *fd);
+int prefork_listen_recv(struct tevent_req *req,
+                       TALLOC_CTX *mem_ctx, int *fd,
+                       struct tsocket_address **srv_addr,
+                       struct tsocket_address **cli_addr);
+
index 81bf7f876c001b27c30b60695b91121b00fd7dc0..1297b581293382a3177ad1ab37e407d6f851a753 100644 (file)
@@ -420,8 +420,8 @@ static void spoolss_client_terminated(void *pvt)
 
 struct spoolss_new_client {
        struct spoolss_children_data *data;
-       struct sockaddr_un sunaddr;
-       socklen_t addrlen;
+       struct tsocket_address *srv_addr;
+       struct tsocket_address *cli_addr;
 };
 
 static void spoolss_handle_client(struct tevent_req *req);
@@ -457,14 +457,11 @@ static void spoolss_next_client(void *pvt)
                return;
        }
        next->data = data;
-       next->addrlen = sizeof(next->sunaddr);
 
        req = prefork_listen_send(next, data->ev_ctx, data->pf,
                                  data->listen_fd_size,
                                  data->listen_fds,
-                                 data->lock_fd,
-                                 (struct sockaddr *)&next->sunaddr,
-                                 &next->addrlen);
+                                 data->lock_fd);
        if (!req) {
                DEBUG(1, ("Failed to make listening request!?\n"));
                talloc_free(next);
@@ -485,7 +482,8 @@ static void spoolss_handle_client(struct tevent_req *req)
        client = tevent_req_callback_data(req, struct spoolss_new_client);
        data = client->data;
 
-       ret = prefork_listen_recv(req, &sd);
+       ret = prefork_listen_recv(req, client, &sd,
+                                 &client->srv_addr, &client->cli_addr);
 
        /* this will free the request too */
        talloc_free(client);