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;
+}
+
struct tsocket_address;
struct tdgram_context;
struct tstream_context;
+struct tsocket_context;
struct iovec;
/**
* @}
*/
+/*
+ * 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 */
#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 */