summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/server_prefork.c67
-rw-r--r--source3/lib/server_prefork.h21
-rw-r--r--source3/printing/spoolssd.c12
3 files changed, 68 insertions, 32 deletions
diff --git a/source3/lib/server_prefork.c b/source3/lib/server_prefork.c
index bc0f4c725e..47020b2740 100644
--- a/source3/lib/server_prefork.c
+++ b/source3/lib/server_prefork.c
@@ -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++;
}
diff --git a/source3/lib/server_prefork.h b/source3/lib/server_prefork.h
index 2f25e557fa..d3ba919950 100644
--- a/source3/lib/server_prefork.h
+++ b/source3/lib/server_prefork.h
@@ -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);
+
diff --git a/source3/printing/spoolssd.c b/source3/printing/spoolssd.c
index 81bf7f876c..1297b58129 100644
--- a/source3/printing/spoolssd.c
+++ b/source3/printing/spoolssd.c
@@ -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);