diff options
-rw-r--r-- | source4/libcli/wrepl/winsrepl.c | 111 | ||||
-rw-r--r-- | source4/wrepl_server/wrepl_out_helpers.c | 23 |
2 files changed, 97 insertions, 37 deletions
diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 907a7b9709..4fd21aaf06 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -721,49 +721,87 @@ NTSTATUS wrepl_associate(struct wrepl_socket *wrepl_socket, return NT_STATUS_OK; } -/* - stop an association - send -*/ -struct wrepl_request *wrepl_associate_stop_send(struct wrepl_socket *wrepl_socket, - struct wrepl_associate_stop *io) -{ - struct wrepl_packet *packet; - struct wrepl_request *req; +struct wrepl_associate_stop_state { + struct wrepl_packet packet; struct wrepl_send_ctrl ctrl; +}; + +static void wrepl_associate_stop_done(struct wrepl_request *subreq); + +struct tevent_req *wrepl_associate_stop_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wrepl_socket *wrepl_socket, + const struct wrepl_associate_stop *io) +{ + struct tevent_req *req; + struct wrepl_associate_stop_state *state; + struct wrepl_request *subreq; + + if (wrepl_socket->event.ctx != ev) { + /* TODO: remove wrepl_socket->event.ctx !!! */ + smb_panic("wrepl_associate_stop_send event context mismatch!"); + return NULL; + } - packet = talloc_zero(wrepl_socket, struct wrepl_packet); - if (packet == NULL) return NULL; + req = tevent_req_create(mem_ctx, &state, + struct wrepl_associate_stop_state); + if (req == NULL) { + return NULL; + }; - packet->opcode = WREPL_OPCODE_BITS; - packet->assoc_ctx = io->in.assoc_ctx; - packet->mess_type = WREPL_STOP_ASSOCIATION; - packet->message.stop.reason = io->in.reason; + state->packet.opcode = WREPL_OPCODE_BITS; + state->packet.assoc_ctx = io->in.assoc_ctx; + state->packet.mess_type = WREPL_STOP_ASSOCIATION; + state->packet.message.stop.reason = io->in.reason; - ZERO_STRUCT(ctrl); if (io->in.reason == 0) { - ctrl.send_only = true; - ctrl.disconnect_after_send = true; + state->ctrl.send_only = true; + state->ctrl.disconnect_after_send = true; + } + + subreq = wrepl_request_send(wrepl_socket, &state->packet, &state->ctrl); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); } + subreq->async.fn = wrepl_associate_stop_done; + subreq->async.private_data = req; + + return req; +} - req = wrepl_request_send(wrepl_socket, packet, &ctrl); +static void wrepl_associate_stop_done(struct wrepl_request *subreq) +{ + struct tevent_req *req = talloc_get_type_abort(subreq->async.private_data, + struct tevent_req); + struct wrepl_associate_stop_state *state = tevent_req_data(req, + struct wrepl_associate_stop_state); + NTSTATUS status; - talloc_free(packet); + /* currently we don't care about a possible response */ + status = wrepl_request_recv(subreq, state, NULL); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } - return req; + tevent_req_done(req); } /* stop an association - recv */ -NTSTATUS wrepl_associate_stop_recv(struct wrepl_request *req, +NTSTATUS wrepl_associate_stop_recv(struct tevent_req *req, struct wrepl_associate_stop *io) { - struct wrepl_packet *packet=NULL; NTSTATUS status; - status = wrepl_request_recv(req, req->wrepl_socket, &packet); - NT_STATUS_NOT_OK_RETURN(status); - talloc_free(packet); - return status; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; + } + + tevent_req_received(req); + return NT_STATUS_OK; } /* @@ -772,8 +810,25 @@ NTSTATUS wrepl_associate_stop_recv(struct wrepl_request *req, NTSTATUS wrepl_associate_stop(struct wrepl_socket *wrepl_socket, struct wrepl_associate_stop *io) { - struct wrepl_request *req = wrepl_associate_stop_send(wrepl_socket, io); - return wrepl_associate_stop_recv(req, io); + struct tevent_req *subreq; + bool ok; + NTSTATUS status; + + subreq = wrepl_associate_stop_send(wrepl_socket, wrepl_socket->event.ctx, + wrepl_socket, io); + 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_associate_stop_recv(subreq, io); + TALLOC_FREE(subreq); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; } struct wrepl_pull_table_state { diff --git a/source4/wrepl_server/wrepl_out_helpers.c b/source4/wrepl_server/wrepl_out_helpers.c index 9a299c2818..de3fb72318 100644 --- a/source4/wrepl_server/wrepl_out_helpers.c +++ b/source4/wrepl_server/wrepl_out_helpers.c @@ -572,11 +572,11 @@ struct wreplsrv_pull_cycle_state { struct wreplsrv_pull_names_io names_io; struct composite_context *creq; struct wrepl_associate_stop assoc_stop_io; - struct wrepl_request *req; + struct tevent_req *subreq; }; static void wreplsrv_pull_cycle_handler_creq(struct composite_context *creq); -static void wreplsrv_pull_cycle_handler_req(struct wrepl_request *req); +static void wreplsrv_pull_cycle_handler_treq(struct tevent_req *subreq); static NTSTATUS wreplsrv_pull_cycle_next_owner_do_work(struct wreplsrv_pull_cycle_state *state) { @@ -654,11 +654,15 @@ static NTSTATUS wreplsrv_pull_cycle_next_owner_wrapper(struct wreplsrv_pull_cycl if (state->stage == WREPLSRV_PULL_CYCLE_STAGE_DONE && state->io->in.wreplconn) { state->assoc_stop_io.in.assoc_ctx = state->io->in.wreplconn->assoc_ctx.peer_ctx; state->assoc_stop_io.in.reason = 0; - state->req = wrepl_associate_stop_send(state->io->in.wreplconn->sock, &state->assoc_stop_io); - NT_STATUS_HAVE_NO_MEMORY(state->req); + state->subreq = wrepl_associate_stop_send(state, + state->io->in.wreplconn->service->task->event_ctx, + state->io->in.wreplconn->sock, + &state->assoc_stop_io); + NT_STATUS_HAVE_NO_MEMORY(state->subreq); - state->req->async.fn = wreplsrv_pull_cycle_handler_req; - state->req->async.private_data = state; + tevent_req_set_callback(state->subreq, + wreplsrv_pull_cycle_handler_treq, + state); state->stage = WREPLSRV_PULL_CYCLE_STAGE_WAIT_STOP_ASSOC; } @@ -731,7 +735,8 @@ static NTSTATUS wreplsrv_pull_cycle_wait_stop_assoc(struct wreplsrv_pull_cycle_s { NTSTATUS status; - status = wrepl_associate_stop_recv(state->req, &state->assoc_stop_io); + status = wrepl_associate_stop_recv(state->subreq, &state->assoc_stop_io); + TALLOC_FREE(state->subreq); NT_STATUS_NOT_OK_RETURN(status); state->stage = WREPLSRV_PULL_CYCLE_STAGE_DONE; @@ -778,9 +783,9 @@ static void wreplsrv_pull_cycle_handler_creq(struct composite_context *creq) return; } -static void wreplsrv_pull_cycle_handler_req(struct wrepl_request *req) +static void wreplsrv_pull_cycle_handler_treq(struct tevent_req *subreq) { - struct wreplsrv_pull_cycle_state *state = talloc_get_type(req->async.private_data, + struct wreplsrv_pull_cycle_state *state = tevent_req_callback_data(subreq, struct wreplsrv_pull_cycle_state); wreplsrv_pull_cycle_handler(state); return; |