summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
Diffstat (limited to 'source4')
-rw-r--r--source4/lib/socket/connect.c140
1 files changed, 72 insertions, 68 deletions
diff --git a/source4/lib/socket/connect.c b/source4/lib/socket/connect.c
index 244fdcbb06..1a29667d1c 100644
--- a/source4/lib/socket/connect.c
+++ b/source4/lib/socket/connect.c
@@ -37,7 +37,7 @@ struct connect_state {
const char *server_address;
int server_port;
uint32_t flags;
- struct fd_event *connect_ev;
+ struct fd_event *fde;
};
static void socket_connect_handler(struct event_context *ev,
@@ -46,6 +46,44 @@ static void socket_connect_handler(struct event_context *ev,
static void socket_connect_recv_addr(struct composite_context *ctx);
static void socket_connect_recv_conn(struct composite_context *ctx);
+/*
+ call the real socket_connect() call, and setup event handler
+*/
+static void socket_send_connect(struct connect_state *state)
+{
+ struct composite_context *ctx;
+
+ ctx = talloc_zero(state, struct composite_context);
+ if (composite_nomem(ctx, state->ctx)) return;
+ ctx->state = COMPOSITE_STATE_IN_PROGRESS;
+ ctx->event_ctx = state->ctx->event_ctx;
+ ctx->async.fn = socket_connect_recv_conn;
+ ctx->async.private_data = state;
+
+ state->ctx->status = socket_connect(state->sock,
+ state->my_address,
+ state->my_port,
+ state->server_address,
+ state->server_port,
+ state->flags);
+ if (NT_STATUS_IS_ERR(state->ctx->status) &&
+ !NT_STATUS_EQUAL(state->ctx->status,
+ NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+ composite_error(state->ctx, state->ctx->status);
+ return;
+ }
+
+ state->fde = event_add_fd(ctx->event_ctx, state,
+ socket_get_fd(state->sock),
+ EVENT_FD_WRITE,
+ socket_connect_handler, ctx);
+ composite_nomem(state->fde, state->ctx);
+}
+
+
+/*
+ send a socket connect, potentially doing some name resolution first
+*/
struct composite_context *socket_connect_send(struct socket_context *sock,
const char *my_address,
int my_port,
@@ -57,24 +95,29 @@ struct composite_context *socket_connect_send(struct socket_context *sock,
struct composite_context *result, *ctx;
struct connect_state *state;
- result = talloc_zero(NULL, struct composite_context);
- if (result == NULL) goto failed;
+ result = talloc_zero(sock, struct composite_context);
+ if (result == NULL) return NULL;
result->state = COMPOSITE_STATE_IN_PROGRESS;
result->async.fn = NULL;
result->event_ctx = event_ctx;
- state = talloc(result, struct connect_state);
- if (state == NULL) goto failed;
+ state = talloc_zero(result, struct connect_state);
+ if (composite_nomem(state, result)) goto failed;
state->ctx = result;
result->private_data = state;
state->sock = talloc_reference(state, sock);
- if (state->sock == NULL) goto failed;
- state->my_address = talloc_strdup(state, my_address);
- if (state->sock == NULL) goto failed;
+ if (composite_nomem(state->sock, result)) goto failed;
+
+ if (my_address) {
+ state->my_address = talloc_strdup(state, my_address);
+ if (composite_nomem(state->my_address, result)) goto failed;
+ }
state->my_port = my_port;
+
state->server_address = talloc_strdup(state, server_address);
- if (state->sock == NULL) goto failed;
+ if (composite_nomem(state->server_address, result)) goto failed;
+
state->server_port = server_port;
state->flags = flags;
@@ -91,37 +134,13 @@ struct composite_context *socket_connect_send(struct socket_context *sock,
return result;
}
- ctx = talloc_zero(state, struct composite_context);
- if (ctx == NULL) goto failed;
- ctx->state = COMPOSITE_STATE_IN_PROGRESS;
- ctx->event_ctx = event_ctx;
- ctx->async.fn = socket_connect_recv_conn;
- ctx->async.private_data = state;
-
- state->ctx->status = socket_connect(sock, my_address, my_port,
- server_address, server_port,
- flags);
- if (NT_STATUS_IS_ERR(state->ctx->status) &&
- !NT_STATUS_EQUAL(state->ctx->status,
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- composite_trigger_error(state->ctx);
- return result;
- }
-
- state->connect_ev = event_add_fd(state->ctx->event_ctx, state,
- socket_get_fd(sock), EVENT_FD_WRITE,
- socket_connect_handler, ctx);
- if (state->connect_ev == NULL) {
- state->ctx->status = NT_STATUS_NO_MEMORY;
- composite_trigger_error(state->ctx);
- return result;
- }
+ socket_send_connect(state);
return result;
- failed:
- talloc_free(result);
- return NULL;
+failed:
+ composite_trigger_error(result);
+ return result;
}
/*
@@ -143,6 +162,9 @@ static void socket_connect_handler(struct event_context *ev,
composite_done(ctx);
}
+/*
+ recv name resolution reply then send the connect
+*/
static void socket_connect_recv_addr(struct composite_context *ctx)
{
struct connect_state *state =
@@ -152,35 +174,14 @@ static void socket_connect_recv_addr(struct composite_context *ctx)
state->ctx->status = resolve_name_recv(ctx, state, &addr);
if (!composite_is_ok(state->ctx)) return;
- ctx = talloc_zero(state, struct composite_context);
- if (composite_nomem(ctx, state->ctx)) return;
- ctx->state = COMPOSITE_STATE_IN_PROGRESS;
- ctx->event_ctx = state->ctx->event_ctx;
- ctx->async.fn = socket_connect_recv_conn;
- ctx->async.private_data = state;
-
- state->ctx->status = socket_connect(state->sock,
- state->my_address,
- state->my_port,
- state->server_address,
- state->server_port,
- state->flags);
- if (NT_STATUS_IS_ERR(state->ctx->status) &&
- !NT_STATUS_EQUAL(state->ctx->status,
- NT_STATUS_MORE_PROCESSING_REQUIRED)) {
- composite_error(state->ctx, state->ctx->status);
- return;
- }
-
- state->connect_ev = event_add_fd(ctx->event_ctx, state,
- socket_get_fd(state->sock),
- EVENT_FD_WRITE,
- socket_connect_handler, ctx);
- if (composite_nomem(state->connect_ev, state->ctx)) return;
+ state->server_address = addr;
- return;
+ socket_send_connect(state);
}
+/*
+ called when a connect has finished. Complete the top level composite context
+*/
static void socket_connect_recv_conn(struct composite_context *ctx)
{
struct connect_state *state =
@@ -188,14 +189,13 @@ static void socket_connect_recv_conn(struct composite_context *ctx)
state->ctx->status = ctx->status;
if (!composite_is_ok(state->ctx)) return;
-
- /* We have to free the event context here because the continuation
- * function might add an event for this socket directly. */
- talloc_free(state->connect_ev);
-
composite_done(state->ctx);
}
+
+/*
+ wait for a socket_connect_send() to finish
+*/
NTSTATUS socket_connect_recv(struct composite_context *ctx)
{
NTSTATUS status = composite_wait(ctx);
@@ -203,6 +203,10 @@ NTSTATUS socket_connect_recv(struct composite_context *ctx)
return status;
}
+
+/*
+ like socket_connect() but takes an event context, doing a semi-async connect
+*/
NTSTATUS socket_connect_ev(struct socket_context *sock,
const char *my_address, int my_port,
const char *server_address, int server_port,