diff options
| author | Simo Sorce <idra@samba.org> | 2011-07-19 15:07:42 -0400 | 
|---|---|---|
| committer | Andreas Schneider <asn@samba.org> | 2011-08-10 18:14:04 +0200 | 
| commit | 227551a07bc1af29ff2e24d889ea7dd45d575773 (patch) | |
| tree | 5a8b272ea593c53152ac2c358883e6172f4ce3e3 | |
| parent | 2b33b438ba8cc6f89bf91e5a63bf0168d48be670 (diff) | |
| download | samba-227551a07bc1af29ff2e24d889ea7dd45d575773.tar.gz samba-227551a07bc1af29ff2e24d889ea7dd45d575773.tar.bz2 samba-227551a07bc1af29ff2e24d889ea7dd45d575773.zip  | |
s3-prefork: Return tsocket_address for client and server
Signed-off-by: Andreas Schneider <asn@samba.org>
| -rw-r--r-- | source3/lib/server_prefork.c | 67 | ||||
| -rw-r--r-- | source3/lib/server_prefork.h | 21 | ||||
| -rw-r--r-- | source3/printing/spoolssd.c | 12 | 
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);  | 
