From 95145fe4f230a7193ff0f58f62a84954c38f0b16 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 3 Apr 2009 16:12:21 +0200 Subject: [PATCH] TODO:better name? tsocket: add tsocket_context infrastructure This one only takes care accept_send/recv(). metze --- lib/tsocket/tsocket.c | 200 +++++++++++++++++++++++++++++++++ lib/tsocket/tsocket.h | 24 ++++ lib/tsocket/tsocket_internal.h | 35 ++++++ 3 files changed, 259 insertions(+) diff --git a/lib/tsocket/tsocket.c b/lib/tsocket/tsocket.c index 674858de0a5a..86736e21e827 100644 --- a/lib/tsocket/tsocket.c +++ b/lib/tsocket/tsocket.c @@ -810,3 +810,203 @@ int tstream_disconnect_recv(struct tevent_req *req, return ret; } +struct tsocket_context { + const char *location; + const struct tsocket_context_ops *ops; + void *private_data; +}; + +struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx, + const struct tsocket_context_ops *ops, + void *pstate, + size_t psize, + const char *type, + const char *location) +{ + struct tsocket_context *sock; + void **ppstate = (void **)pstate; + void *state; + + sock = talloc(mem_ctx, struct tsocket_context); + if (sock == NULL) { + return NULL; + } + sock->location = location; + sock->ops = ops; + + state = talloc_size(sock, psize); + if (state == NULL) { + talloc_free(sock); + return NULL; + } + talloc_set_name_const(state, type); + + sock->private_data = state; + + *ppstate = state; + return sock; +} + +void *_tsocket_context_data(struct tsocket_context *sock) +{ + return sock->private_data; +} + +struct tsocket_accept_state { + const struct tsocket_context_ops *ops; + struct tsocket_address *local; + struct tsocket_address *remote; + struct tstream_context *stream; +}; + +static void tsocket_accept_done(struct tevent_req *subreq); + +struct tevent_req *tsocket_accept_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tsocket_context *sock) +{ + struct tevent_req *req; + struct tsocket_accept_state *state; + struct tevent_req *subreq; + + req = tevent_req_create(mem_ctx, &state, + struct tsocket_accept_state); + if (req == NULL) { + return NULL; + } + + state->ops = sock->ops; + state->local = NULL; + state->remote = NULL; + state->stream = NULL; + + subreq = state->ops->accept_send(state, ev, sock); + if (tevent_req_nomem(subreq, req)) { + goto post; + } + tevent_req_set_callback(subreq, tsocket_accept_done, req); + + return req; + + post: + tevent_req_post(req, ev); + return req; +} + +static void tsocket_accept_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct tsocket_accept_state *state = tevent_req_data(req, + struct tsocket_accept_state); + ssize_t ret; + int sys_errno; + + ret = state->ops->accept_recv(subreq, &sys_errno, + state, + &state->local, + &state->remote, + &state->stream, + "tsocket_accept_done"); + if (ret == -1) { + tevent_req_error(req, sys_errno); + return; + } + + tevent_req_done(req); +} + +int _tsocket_accept_recv(struct tevent_req *req, + int *perrno, + TALLOC_CTX *mem_ctx, + struct tsocket_address **local, + struct tsocket_address **remote, + struct tstream_context **stream, + const char *location) +{ + struct tsocket_accept_state *state = tevent_req_data(req, + struct tsocket_accept_state); + int ret; + + ret = tsocket_simple_int_recv(req, perrno); + if (ret == 0) { + if (local) { + state->local->location = location; + *local = talloc_move(mem_ctx, &state->local); + } + if (remote) { + state->remote->location = location; + *remote = talloc_move(mem_ctx, &state->remote); + } + state->stream->location = location; + *stream = talloc_move(mem_ctx, &state->stream); + } + + tevent_req_received(req); + return ret; +} + +struct tsocket_shutdown_state { + const struct tsocket_context_ops *ops; +}; + +static void tsocket_shutdown_done(struct tevent_req *subreq); + +struct tevent_req *tsocket_shutdown_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tsocket_context *sock) +{ + struct tevent_req *req; + struct tsocket_shutdown_state *state; + struct tevent_req *subreq; + + req = tevent_req_create(mem_ctx, &state, + struct tsocket_shutdown_state); + if (req == NULL) { + return NULL; + } + + state->ops = sock->ops; + + subreq = state->ops->shutdown_send(state, ev, sock); + if (tevent_req_nomem(subreq, req)) { + goto post; + } + tevent_req_set_callback(subreq, tsocket_shutdown_done, req); + + return req; + + post: + tevent_req_post(req, ev); + return req; +} + +static void tsocket_shutdown_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct tsocket_shutdown_state *state = tevent_req_data(req, + struct tsocket_shutdown_state); + int ret; + int sys_errno; + + ret = state->ops->shutdown_recv(subreq, &sys_errno); + if (ret == -1) { + tevent_req_error(req, sys_errno); + return; + } + + tevent_req_done(req); +} + +int tsocket_shutdown_recv(struct tevent_req *req, + int *perrno) +{ + int ret; + + ret = tsocket_simple_int_recv(req, perrno); + + tevent_req_received(req); + return ret; +} + diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h index 98f864e6a570..c231fff7a588 100644 --- a/lib/tsocket/tsocket.h +++ b/lib/tsocket/tsocket.h @@ -30,6 +30,7 @@ struct tsocket_address; struct tdgram_context; struct tstream_context; +struct tsocket_context; struct iovec; /** @@ -1153,5 +1154,28 @@ int tstream_writev_queue_recv(struct tevent_req *req, int *perrno); * @} */ +/* + * tsocket_context related functions + */ +struct tevent_req *tsocket_accept_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tsocket_context *sock); +int _tsocket_accept_recv(struct tevent_req *req, + int *perrno, + TALLOC_CTX *mem_ctx, + struct tsocket_address **local, + struct tsocket_address **remote, + struct tstream_context **stream, + const char *location); +#define tsocket_accept_recv(req, perrno, mem_ctx, local, remote, stream) \ + _tsocket_accept_recv(req, perrno, mem_ctx, local, remote, stream, \ + __location__) + +struct tevent_req *tsocket_shutdown_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tsocket_context *sock); +int tsocket_shutdown_recv(struct tevent_req *req, + int *perrno); + #endif /* _TSOCKET_H */ diff --git a/lib/tsocket/tsocket_internal.h b/lib/tsocket/tsocket_internal.h index 154b2ce6f890..952615ac4138 100644 --- a/lib/tsocket/tsocket_internal.h +++ b/lib/tsocket/tsocket_internal.h @@ -138,6 +138,41 @@ void *_tstream_context_data(struct tstream_context *stream); #define tstream_context_data(_req, _type) \ talloc_get_type_abort(_tstream_context_data(_req), _type) +struct tsocket_context_ops { + const char *name; + + struct tevent_req *(*accept_send)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tsocket_context *sock); + int (*accept_recv)(struct tevent_req *req, + int *perrno, + TALLOC_CTX *mem_ctx, + struct tsocket_address **local, + struct tsocket_address **remote, + struct tstream_context **stream, + const char *location); + + struct tevent_req *(*shutdown_send)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tsocket_context *sock); + int (*shutdown_recv)(struct tevent_req *req, + int *perrno); +}; + +struct tsocket_context *_tsocket_context_create(TALLOC_CTX *mem_ctx, + const struct tsocket_context_ops *ops, + void *pstate, + size_t psize, + const char *type, + const char *location); +#define tsocket_context_create(mem_ctx, ops, state, type, location) \ + _tsocket_context_create(mem_ctx, ops, state, sizeof(type), \ + #type, location) + +void *_tsocket_context_data(struct tsocket_context *sock); +#define tsocket_context_data(_req, _type) \ + talloc_get_type_abort(_tstream_server_data(_req), _type) + int tsocket_simple_int_recv(struct tevent_req *req, int *perrno); #endif /* _TSOCKET_H */ -- 2.34.1