]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
Add open_socket_out_defer_send/recv
authorVolker Lendecke <vl@samba.org>
Sun, 4 Jan 2009 00:45:06 +0000 (01:45 +0100)
committerVolker Lendecke <vl@samba.org>
Sun, 4 Jan 2009 15:42:40 +0000 (16:42 +0100)
source3/include/proto.h
source3/lib/util_sock.c

index 957302c378fd218a95a58f85ccff5d18daa29bb2..6238ba3d008c3670efaefe92d21e1cf39ed9ef3e 100644 (file)
@@ -1465,6 +1465,13 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
                                       uint16_t port,
                                       int timeout);
 NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd);
+struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+                                            struct event_context *ev,
+                                            struct timeval wait_time,
+                                            const struct sockaddr_storage *pss,
+                                            uint16_t port,
+                                            int timeout);
+NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd);
 bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
                         int timeout, int *fd_index, int *fd);
 int open_udp_socket(const char *host, int port);
index 3356318c88a99f47f09a2289a38f4db60ea33027..518bb78f65b0f6ba1693c33b0aaac2036f66f62e 100644 (file)
@@ -1152,6 +1152,117 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
        return status;
 }
 
+struct open_socket_out_defer_state {
+       struct event_context *ev;
+       struct sockaddr_storage ss;
+       uint16_t port;
+       int timeout;
+       int fd;
+};
+
+static void open_socket_out_defer_waited(struct async_req *subreq);
+static void open_socket_out_defer_connected(struct async_req *subreq);
+
+struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
+                                            struct event_context *ev,
+                                            struct timeval wait_time,
+                                            const struct sockaddr_storage *pss,
+                                            uint16_t port,
+                                            int timeout)
+{
+       struct async_req *result, *subreq;
+       struct open_socket_out_defer_state *state;
+       NTSTATUS status;
+
+       result = async_req_new(mem_ctx);
+       if (result == NULL) {
+               return NULL;
+       }
+       state = talloc(result, struct open_socket_out_defer_state);
+       if (state == NULL) {
+               goto fail;
+       }
+       result->private_data = state;
+
+       state->ev = ev;
+       state->ss = *pss;
+       state->port = port;
+       state->timeout = timeout;
+
+       subreq = async_wait_send(state, ev, wait_time);
+       if (subreq == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto post_status;
+       }
+       subreq->async.fn = open_socket_out_defer_waited;
+       subreq->async.priv = result;
+       return result;
+
+ post_status:
+       if (!async_post_status(result, ev, status)) {
+               goto fail;
+       }
+       return result;
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
+
+static void open_socket_out_defer_waited(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct open_socket_out_defer_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_defer_state);
+       NTSTATUS status;
+
+       status = async_wait_recv(subreq);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       subreq = open_socket_out_send(state, state->ev, &state->ss,
+                                     state->port, state->timeout);
+       if (async_req_nomem(subreq, req)) {
+               return;
+       }
+       subreq->async.fn = open_socket_out_defer_connected;
+       subreq->async.priv = req;
+}
+
+static void open_socket_out_defer_connected(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct open_socket_out_defer_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_defer_state);
+       NTSTATUS status;
+
+       status = open_socket_out_recv(subreq, &state->fd);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+       async_req_done(req);
+}
+
+NTSTATUS open_socket_out_defer_recv(struct async_req *req, int *pfd)
+{
+       struct open_socket_out_defer_state *state = talloc_get_type_abort(
+               req->private_data, struct open_socket_out_defer_state);
+       NTSTATUS status;
+
+       if (async_req_is_error(req, &status)) {
+               return status;
+       }
+       *pfd = state->fd;
+       state->fd = -1;
+       return NT_STATUS_OK;
+}
+
 /*******************************************************************
  Create an outgoing TCP socket to the first addr that connects.