diff options
-rw-r--r-- | source4/libcli/wrepl/winsrepl.c | 137 | ||||
-rw-r--r-- | source4/wrepl_server/wrepl_out_helpers.c | 22 |
2 files changed, 111 insertions, 48 deletions
diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 2e1d1d8987..4bd9b653b9 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -684,65 +684,107 @@ NTSTATUS wrepl_associate_stop(struct wrepl_socket *wrepl_socket, return wrepl_associate_stop_recv(req, io); } -/* - fetch the partner tables - send -*/ -struct wrepl_request *wrepl_pull_table_send(struct wrepl_socket *wrepl_socket, - struct wrepl_pull_table *io) +struct wrepl_pull_table_state { + struct wrepl_packet packet; + uint32_t num_partners; + struct wrepl_wins_owner *partners; +}; + +static void wrepl_pull_table_done(struct wrepl_request *subreq); + +struct tevent_req *wrepl_pull_table_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wrepl_socket *wrepl_socket, + const struct wrepl_pull_table *io) { - struct wrepl_packet *packet; - struct wrepl_request *req; + struct tevent_req *req; + struct wrepl_pull_table_state *state; + struct wrepl_request *subreq; - packet = talloc_zero(wrepl_socket, struct wrepl_packet); - if (packet == NULL) return NULL; + if (wrepl_socket->event.ctx != ev) { + /* TODO: remove wrepl_socket->event.ctx !!! */ + smb_panic("wrepl_pull_table_send event context mismatch!"); + return NULL; + } - packet->opcode = WREPL_OPCODE_BITS; - packet->assoc_ctx = io->in.assoc_ctx; - packet->mess_type = WREPL_REPLICATION; - packet->message.replication.command = WREPL_REPL_TABLE_QUERY; + req = tevent_req_create(mem_ctx, &state, + struct wrepl_pull_table_state); + if (req == NULL) { + return NULL; + }; - req = wrepl_request_send(wrepl_socket, packet, NULL); + state->packet.opcode = WREPL_OPCODE_BITS; + state->packet.assoc_ctx = io->in.assoc_ctx; + state->packet.mess_type = WREPL_REPLICATION; + state->packet.message.replication.command = WREPL_REPL_TABLE_QUERY; - talloc_free(packet); + subreq = wrepl_request_send(wrepl_socket, &state->packet, NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + subreq->async.fn = wrepl_pull_table_done; + subreq->async.private_data = req; - return req; + return req; } +static void wrepl_pull_table_done(struct wrepl_request *subreq) +{ + struct tevent_req *req = talloc_get_type_abort(subreq->async.private_data, + struct tevent_req); + struct wrepl_pull_table_state *state = tevent_req_data(req, + struct wrepl_pull_table_state); + NTSTATUS status; + struct wrepl_packet *packet; + struct wrepl_table *table; + + status = wrepl_request_recv(subreq, state, &packet); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + + if (packet->mess_type != WREPL_REPLICATION) { + tevent_req_nterror(req, NT_STATUS_NETWORK_ACCESS_DENIED); + return; + } + + if (packet->message.replication.command != WREPL_REPL_TABLE_REPLY) { + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + table = &packet->message.replication.info.table; + + state->num_partners = table->partner_count; + state->partners = talloc_move(state, &table->partners); + + tevent_req_done(req); +} /* fetch the partner tables - recv */ -NTSTATUS wrepl_pull_table_recv(struct wrepl_request *req, +NTSTATUS wrepl_pull_table_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct wrepl_pull_table *io) { - struct wrepl_packet *packet=NULL; + struct wrepl_pull_table_state *state = tevent_req_data(req, + struct wrepl_pull_table_state); NTSTATUS status; - struct wrepl_table *table; - int i; - status = wrepl_request_recv(req, req->wrepl_socket, &packet); - NT_STATUS_NOT_OK_RETURN(status); - if (packet->mess_type != WREPL_REPLICATION) { - status = NT_STATUS_NETWORK_ACCESS_DENIED; - } else if (packet->message.replication.command != WREPL_REPL_TABLE_REPLY) { - status = NT_STATUS_UNEXPECTED_NETWORK_ERROR; + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; } - if (!NT_STATUS_IS_OK(status)) goto failed; - table = &packet->message.replication.info.table; - io->out.num_partners = table->partner_count; - io->out.partners = talloc_steal(mem_ctx, table->partners); - for (i=0;i<io->out.num_partners;i++) { - talloc_steal(io->out.partners, io->out.partners[i].address); - } + io->out.num_partners = state->num_partners; + io->out.partners = talloc_move(mem_ctx, &state->partners); -failed: - talloc_free(packet); - return status; + tevent_req_received(req); + return NT_STATUS_OK; } - /* fetch the partner table - sync api */ @@ -750,8 +792,25 @@ NTSTATUS wrepl_pull_table(struct wrepl_socket *wrepl_socket, TALLOC_CTX *mem_ctx, struct wrepl_pull_table *io) { - struct wrepl_request *req = wrepl_pull_table_send(wrepl_socket, io); - return wrepl_pull_table_recv(req, mem_ctx, io); + struct tevent_req *subreq; + bool ok; + NTSTATUS status; + + subreq = wrepl_pull_table_send(mem_ctx, 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_pull_table_recv(subreq, mem_ctx, io); + 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 08d0fa4c30..9745761436 100644 --- a/source4/wrepl_server/wrepl_out_helpers.c +++ b/source4/wrepl_server/wrepl_out_helpers.c @@ -255,14 +255,14 @@ enum wreplsrv_pull_table_stage { struct wreplsrv_pull_table_state { enum wreplsrv_pull_table_stage stage; struct composite_context *c; - struct wrepl_request *req; struct wrepl_pull_table table_io; struct wreplsrv_pull_table_io *io; struct composite_context *creq; struct wreplsrv_out_connection *wreplconn; + struct tevent_req *subreq; }; -static void wreplsrv_pull_table_handler_req(struct wrepl_request *req); +static void wreplsrv_pull_table_handler_treq(struct tevent_req *subreq); static NTSTATUS wreplsrv_pull_table_wait_connection(struct wreplsrv_pull_table_state *state) { @@ -272,11 +272,14 @@ static NTSTATUS wreplsrv_pull_table_wait_connection(struct wreplsrv_pull_table_s NT_STATUS_NOT_OK_RETURN(status); state->table_io.in.assoc_ctx = state->wreplconn->assoc_ctx.peer_ctx; - state->req = wrepl_pull_table_send(state->wreplconn->sock, &state->table_io); - NT_STATUS_HAVE_NO_MEMORY(state->req); + state->subreq = wrepl_pull_table_send(state, + state->wreplconn->service->task->event_ctx, + state->wreplconn->sock, &state->table_io); + NT_STATUS_HAVE_NO_MEMORY(state->subreq); - state->req->async.fn = wreplsrv_pull_table_handler_req; - state->req->async.private_data = state; + tevent_req_set_callback(state->subreq, + wreplsrv_pull_table_handler_treq, + state); state->stage = WREPLSRV_PULL_TABLE_STAGE_WAIT_TABLE_REPLY; @@ -287,7 +290,8 @@ static NTSTATUS wreplsrv_pull_table_wait_table_reply(struct wreplsrv_pull_table_ { NTSTATUS status; - status = wrepl_pull_table_recv(state->req, state, &state->table_io); + status = wrepl_pull_table_recv(state->subreq, state, &state->table_io); + TALLOC_FREE(state->subreq); NT_STATUS_NOT_OK_RETURN(status); state->stage = WREPLSRV_PULL_TABLE_STAGE_DONE; @@ -328,9 +332,9 @@ static void wreplsrv_pull_table_handler_creq(struct composite_context *creq) return; } -static void wreplsrv_pull_table_handler_req(struct wrepl_request *req) +static void wreplsrv_pull_table_handler_treq(struct tevent_req *subreq) { - struct wreplsrv_pull_table_state *state = talloc_get_type(req->async.private_data, + struct wreplsrv_pull_table_state *state = tevent_req_callback_data(subreq, struct wreplsrv_pull_table_state); wreplsrv_pull_table_handler(state); return; |