diff options
-rw-r--r-- | source4/libcli/wrepl/winsrepl.c | 160 | ||||
-rw-r--r-- | source4/wrepl_server/wrepl_out_helpers.c | 24 |
2 files changed, 104 insertions, 80 deletions
diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index b3b1381601..907a7b9709 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -267,34 +267,89 @@ static NTSTATUS wrepl_request_wait(struct wrepl_request *req) return req->status; } +const char *wrepl_best_ip(struct loadparm_context *lp_ctx, const char *peer_ip) +{ + struct interface *ifaces; + load_interfaces(lp_ctx, lp_interfaces(lp_ctx), &ifaces); + return iface_best_ip(ifaces, peer_ip); +} + struct wrepl_connect_state { - struct composite_context *result; struct wrepl_socket *wrepl_socket; - struct composite_context *creq; }; -/* - handler for winrepl connection completion -*/ -static void wrepl_connect_handler(struct composite_context *creq) +static void wrepl_connect_handler(struct composite_context *creq); + +struct tevent_req *wrepl_connect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wrepl_socket *wrepl_socket, + const char *our_ip, const char *peer_ip) +{ + struct tevent_req *req; + struct wrepl_connect_state *state; + struct composite_context *subreq; + struct socket_address *peer, *us; + + req = tevent_req_create(mem_ctx, &state, + struct wrepl_connect_state); + if (req == NULL) { + return NULL; + } + + state->wrepl_socket = wrepl_socket; + + us = socket_address_from_strings(state, wrepl_socket->sock->backend_name, + our_ip, 0); + if (tevent_req_nomem(us, req)) { + return tevent_req_post(req, ev); + } + + peer = socket_address_from_strings(state, wrepl_socket->sock->backend_name, + peer_ip, WINS_REPLICATION_PORT); + if (tevent_req_nomem(peer, req)) { + return tevent_req_post(req, ev); + } + + subreq = socket_connect_send(wrepl_socket->sock, us, peer, + 0, wrepl_socket->event.ctx); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + subreq->async.fn = wrepl_connect_handler; + subreq->async.private_data = req; + + return req; +} + +static void wrepl_connect_handler(struct composite_context *subreq) { - struct wrepl_connect_state *state = talloc_get_type(creq->async.private_data, + struct tevent_req *req = talloc_get_type_abort(subreq->async.private_data, + struct tevent_req); + struct wrepl_connect_state *state = tevent_req_data(req, struct wrepl_connect_state); struct wrepl_socket *wrepl_socket = state->wrepl_socket; - struct composite_context *result = state->result; + NTSTATUS status; - result->status = socket_connect_recv(state->creq); - if (!composite_is_ok(result)) return; + status = socket_connect_recv(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } wrepl_socket->event.fde = event_add_fd(wrepl_socket->event.ctx, wrepl_socket, socket_get_fd(wrepl_socket->sock), EVENT_FD_READ, wrepl_handler, wrepl_socket); - if (composite_nomem(wrepl_socket->event.fde, result)) return; + if (tevent_req_nomem(wrepl_socket->event.fde, req)) { + return; + } /* setup the stream -> packet parser */ wrepl_socket->packet = packet_init(wrepl_socket); - if (composite_nomem(wrepl_socket->packet, result)) return; + if (tevent_req_nomem(wrepl_socket->packet, req)) { + return; + } packet_set_private(wrepl_socket->packet, wrepl_socket); packet_set_socket(wrepl_socket->packet, wrepl_socket->sock); packet_set_callback(wrepl_socket->packet, wrepl_finish_recv); @@ -304,69 +359,27 @@ static void wrepl_connect_handler(struct composite_context *creq) packet_set_fde(wrepl_socket->packet, wrepl_socket->event.fde); packet_set_serialise(wrepl_socket->packet); - composite_done(result); -} - -const char *wrepl_best_ip(struct loadparm_context *lp_ctx, const char *peer_ip) -{ - struct interface *ifaces; - load_interfaces(lp_ctx, lp_interfaces(lp_ctx), &ifaces); - return iface_best_ip(ifaces, peer_ip); -} - - -/* - connect a wrepl_socket to a WINS server -*/ -struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, - const char *our_ip, const char *peer_ip) -{ - struct composite_context *result; - struct wrepl_connect_state *state; - struct socket_address *peer, *us; - - result = talloc_zero(wrepl_socket, struct composite_context); - if (!result) return NULL; - - result->state = COMPOSITE_STATE_IN_PROGRESS; - result->event_ctx = wrepl_socket->event.ctx; - - state = talloc_zero(result, struct wrepl_connect_state); - if (composite_nomem(state, result)) return result; - result->private_data = state; - state->result = result; - state->wrepl_socket = wrepl_socket; - - us = socket_address_from_strings(state, wrepl_socket->sock->backend_name, - our_ip, 0); - if (composite_nomem(us, result)) return result; - - peer = socket_address_from_strings(state, wrepl_socket->sock->backend_name, - peer_ip, WINS_REPLICATION_PORT); - if (composite_nomem(peer, result)) return result; - - state->creq = socket_connect_send(wrepl_socket->sock, us, peer, - 0, wrepl_socket->event.ctx); - composite_continue(result, state->creq, wrepl_connect_handler, state); - return result; + tevent_req_done(req); } /* connect a wrepl_socket to a WINS server - recv side */ -NTSTATUS wrepl_connect_recv(struct composite_context *result) +NTSTATUS wrepl_connect_recv(struct tevent_req *req) { - struct wrepl_connect_state *state = talloc_get_type(result->private_data, + struct wrepl_connect_state *state = tevent_req_data(req, struct wrepl_connect_state); struct wrepl_socket *wrepl_socket = state->wrepl_socket; - NTSTATUS status = composite_wait(result); + NTSTATUS status; - if (!NT_STATUS_IS_OK(status)) { + if (tevent_req_is_nterror(req, &status)) { wrepl_socket_dead(wrepl_socket, status); + tevent_req_received(req); + return status; } - talloc_free(result); - return status; + tevent_req_received(req); + return NT_STATUS_OK; } /* @@ -375,8 +388,25 @@ NTSTATUS wrepl_connect_recv(struct composite_context *result) NTSTATUS wrepl_connect(struct wrepl_socket *wrepl_socket, const char *our_ip, const char *peer_ip) { - struct composite_context *c_req = wrepl_connect_send(wrepl_socket, our_ip, peer_ip); - return wrepl_connect_recv(c_req); + struct tevent_req *subreq; + bool ok; + NTSTATUS status; + + subreq = wrepl_connect_send(wrepl_socket, wrepl_socket->event.ctx, + wrepl_socket, our_ip, peer_ip); + NT_STATUS_HAVE_NO_MEMORY(subreq); + + ok = tevent_req_poll(subreq, wrepl_socket->event.ctx); + if (!ok) { + TALLOC_FREE(subreq); + return NT_STATUS_INTERNAL_ERROR; + } + + status = wrepl_connect_recv(subreq); + TALLOC_FREE(subreq); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; } /* diff --git a/source4/wrepl_server/wrepl_out_helpers.c b/source4/wrepl_server/wrepl_out_helpers.c index 352be8503d..9a299c2818 100644 --- a/source4/wrepl_server/wrepl_out_helpers.c +++ b/source4/wrepl_server/wrepl_out_helpers.c @@ -41,21 +41,20 @@ enum wreplsrv_out_connect_stage { struct wreplsrv_out_connect_state { enum wreplsrv_out_connect_stage stage; struct composite_context *c; - struct composite_context *c_req; struct wrepl_associate assoc_io; enum winsrepl_partner_type type; struct wreplsrv_out_connection *wreplconn; struct tevent_req *subreq; }; -static void wreplsrv_out_connect_handler_creq(struct composite_context *c_req); static void wreplsrv_out_connect_handler_treq(struct tevent_req *subreq); static NTSTATUS wreplsrv_out_connect_wait_socket(struct wreplsrv_out_connect_state *state) { NTSTATUS status; - status = wrepl_connect_recv(state->c_req); + status = wrepl_connect_recv(state->subreq); + TALLOC_FREE(state->subreq); NT_STATUS_NOT_OK_RETURN(status); state->subreq = wrepl_associate_send(state, @@ -125,14 +124,6 @@ static void wreplsrv_out_connect_handler(struct wreplsrv_out_connect_state *stat } } -static void wreplsrv_out_connect_handler_creq(struct composite_context *creq) -{ - struct wreplsrv_out_connect_state *state = talloc_get_type(creq->async.private_data, - struct wreplsrv_out_connect_state); - wreplsrv_out_connect_handler(state); - return; -} - static void wreplsrv_out_connect_handler_treq(struct tevent_req *subreq) { struct wreplsrv_out_connect_state *state = tevent_req_callback_data(subreq, @@ -201,13 +192,16 @@ static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partn state->stage = WREPLSRV_OUT_CONNECT_STAGE_WAIT_SOCKET; state->wreplconn= wreplconn; - state->c_req = wrepl_connect_send(wreplconn->sock, + state->subreq = wrepl_connect_send(state, + service->task->event_ctx, + wreplconn->sock, partner->our_address?partner->our_address:wrepl_best_ip(service->task->lp_ctx, partner->address), partner->address); - if (!state->c_req) goto failed; + if (!state->subreq) goto failed; - state->c_req->async.fn = wreplsrv_out_connect_handler_creq; - state->c_req->async.private_data = state; + tevent_req_set_callback(state->subreq, + wreplsrv_out_connect_handler_treq, + state); return c; failed: |