1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-24 13:57:43 +03:00

s3-prefork: Return tsocket_address for client and server

Signed-off-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Simo Sorce 2011-07-19 15:07:42 -04:00 committed by Andreas Schneider
parent 2b33b438ba
commit 227551a07b
3 changed files with 68 additions and 32 deletions

View 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++;
}

View 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);

View 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);