From 43fb7f1698c0c8aaa7f1e5d6a0f924396a9a12fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 11 Oct 2010 08:54:27 +0200 Subject: libcli/nbt: convert nbt_name_refresh_wins_send/recv to tevent_req metze --- libcli/nbt/libnbt.h | 13 +- libcli/nbt/namerefresh.c | 226 +++++++++++++++++++++-------------- libcli/nbt/wscript_build | 2 +- source4/nbt_server/wins/winsclient.c | 12 +- 4 files changed, 151 insertions(+), 102 deletions(-) diff --git a/libcli/nbt/libnbt.h b/libcli/nbt/libnbt.h index 6165548320..91bef5858f 100644 --- a/libcli/nbt/libnbt.h +++ b/libcli/nbt/libnbt.h @@ -345,13 +345,18 @@ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *n NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c); struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock, struct nbt_name_register_wins *io); -NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io); -struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh_wins *io); NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, struct nbt_name_register_wins *io); +struct tevent_context; +struct tevent_req; +struct tevent_req *nbt_name_refresh_wins_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct nbt_name_socket *nbtsock, + struct nbt_name_refresh_wins *io); +NTSTATUS nbt_name_refresh_wins_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct nbt_name_refresh_wins *io); XFILE *startlmhosts(const char *fname); bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, diff --git a/libcli/nbt/namerefresh.c b/libcli/nbt/namerefresh.c index 65a891353e..79c6c1f2ea 100644 --- a/libcli/nbt/namerefresh.c +++ b/libcli/nbt/namerefresh.c @@ -20,10 +20,11 @@ */ #include "includes.h" +#include #include "../libcli/nbt/libnbt.h" #include "../libcli/nbt/nbt_proto.h" -#include "libcli/composite/composite.h" #include "lib/socket/socket.h" +#include "lib/util/tevent_ntstatus.h" /* send a nbt name refresh request @@ -145,41 +146,67 @@ _PUBLIC_ NTSTATUS nbt_name_refresh(struct nbt_name_socket *nbtsock, struct nbt_name_refresh_wins_state { struct nbt_name_socket *nbtsock; struct nbt_name_refresh *io; - const char **wins_servers; + char **wins_servers; uint16_t wins_port; - const char **addresses; + char **addresses; int address_idx; - struct nbt_name_request *req; }; -static void nbt_name_refresh_wins_handler(struct nbt_name_request *req); +static void nbt_name_refresh_wins_handler(struct nbt_name_request *subreq); /** the async send call for a multi-server WINS refresh */ -_PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_socket *nbtsock, - struct nbt_name_refresh_wins *io) +_PUBLIC_ struct tevent_req *nbt_name_refresh_wins_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct nbt_name_socket *nbtsock, + struct nbt_name_refresh_wins *io) { - struct composite_context *c; + struct tevent_req *req; struct nbt_name_refresh_wins_state *state; + struct nbt_name_request *subreq; - c = talloc_zero(nbtsock, struct composite_context); - if (c == NULL) goto failed; - - state = talloc(c, struct nbt_name_refresh_wins_state); - if (state == NULL) goto failed; + req = tevent_req_create(mem_ctx, &state, + struct nbt_name_refresh_wins_state); + if (req == NULL) { + return NULL; + } state->io = talloc(state, struct nbt_name_refresh); - if (state->io == NULL) goto failed; + if (tevent_req_nomem(state->io, req)) { + return tevent_req_post(req, ev); + } + + if (io->in.wins_servers == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + if (io->in.wins_servers[0] == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + if (io->in.addresses == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + if (io->in.addresses[0] == NULL) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } state->wins_port = io->in.wins_port; - state->wins_servers = (const char **)str_list_copy(state, io->in.wins_servers); - if (state->wins_servers == NULL || - state->wins_servers[0] == NULL) goto failed; + state->wins_servers = str_list_copy(state, io->in.wins_servers); + if (tevent_req_nomem(state->wins_servers, req)) { + return tevent_req_post(req, ev); + } - state->addresses = (const char **)str_list_copy(state, io->in.addresses); - if (state->addresses == NULL || - state->addresses[0] == NULL) goto failed; + state->addresses = str_list_copy(state, io->in.addresses); + if (tevent_req_nomem(state->addresses, req)) { + return tevent_req_post(req, ev); + } state->io->in.name = io->in.name; state->io->in.dest_addr = state->wins_servers[0]; @@ -194,110 +221,127 @@ _PUBLIC_ struct composite_context *nbt_name_refresh_wins_send(struct nbt_name_so state->nbtsock = nbtsock; state->address_idx = 0; - state->req = nbt_name_refresh_send(nbtsock, state->io); - if (state->req == NULL) goto failed; - - state->req->async.fn = nbt_name_refresh_wins_handler; - state->req->async.private_data = c; - - c->private_data = state; - c->state = COMPOSITE_STATE_IN_PROGRESS; - c->event_ctx = nbtsock->event_ctx; + subreq = nbt_name_refresh_send(nbtsock, state->io); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } - return c; + subreq->async.fn = nbt_name_refresh_wins_handler; + subreq->async.private_data = req; -failed: - talloc_free(c); - return NULL; + return req; } - -/** - state handler for WINS multi-homed multi-server name refresh -*/ -static void nbt_name_refresh_wins_handler(struct nbt_name_request *req) +static void nbt_name_refresh_wins_handler(struct nbt_name_request *subreq) { - struct composite_context *c = talloc_get_type(req->async.private_data, - struct composite_context); - struct nbt_name_refresh_wins_state *state = talloc_get_type(c->private_data, - struct nbt_name_refresh_wins_state); + struct tevent_req *req = + talloc_get_type_abort(subreq->async.private_data, + struct tevent_req); + struct nbt_name_refresh_wins_state *state = + tevent_req_data(req, + struct nbt_name_refresh_wins_state); NTSTATUS status; - status = nbt_name_refresh_recv(state->req, state, state->io); + status = nbt_name_refresh_recv(subreq, state, state->io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { /* the refresh timed out - try the next WINS server */ state->wins_servers++; - state->address_idx = 0; if (state->wins_servers[0] == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - goto done; + tevent_req_nterror(req, status); + return; } + + state->address_idx = 0; state->io->in.dest_addr = state->wins_servers[0]; state->io->in.dest_port = state->wins_port; state->io->in.address = state->addresses[0]; - state->req = nbt_name_refresh_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = nbt_name_refresh_wins_handler; - state->req->async.private_data = c; + + subreq = nbt_name_refresh_send(state->nbtsock, state->io); + if (tevent_req_nomem(subreq, req)) { + return; } + subreq->async.fn = nbt_name_refresh_wins_handler; + subreq->async.private_data = req; } else if (!NT_STATUS_IS_OK(status)) { - c->state = COMPOSITE_STATE_ERROR; - c->status = status; - } else { - if (state->io->out.rcode == 0 && - state->addresses[state->address_idx+1] != NULL) { - /* refresh our next address */ - state->io->in.address = state->addresses[++(state->address_idx)]; - state->req = nbt_name_refresh_send(state->nbtsock, state->io); - if (state->req == NULL) { - c->state = COMPOSITE_STATE_ERROR; - c->status = NT_STATUS_NO_MEMORY; - } else { - state->req->async.fn = nbt_name_refresh_wins_handler; - state->req->async.private_data = c; - } - } else { - c->state = COMPOSITE_STATE_DONE; - c->status = NT_STATUS_OK; - } + tevent_req_nterror(req, status); + return; } -done: - if (c->state >= COMPOSITE_STATE_DONE && - c->async.fn) { - c->async.fn(c); + if (state->io->out.rcode == 0 && + state->addresses[state->address_idx+1] != NULL) { + /* refresh our next address */ + state->io->in.address = state->addresses[++(state->address_idx)]; + subreq = nbt_name_refresh_send(state->nbtsock, state->io); + if (tevent_req_nomem(subreq, req)) { + return; + } + subreq->async.fn = nbt_name_refresh_wins_handler; + subreq->async.private_data = req; + return; } + + tevent_req_done(req); } /* multi-homed WINS name refresh - recv side */ -_PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io) +_PUBLIC_ NTSTATUS nbt_name_refresh_wins_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + struct nbt_name_refresh_wins *io) { + struct nbt_name_refresh_wins_state *state = + tevent_req_data(req, + struct nbt_name_refresh_wins_state); NTSTATUS status; - status = composite_wait(c); - if (NT_STATUS_IS_OK(status)) { - struct nbt_name_refresh_wins_state *state = - talloc_get_type(c->private_data, struct nbt_name_refresh_wins_state); - io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]); - io->out.rcode = state->io->out.rcode; + + if (tevent_req_is_nterror(req, &status)) { + tevent_req_received(req); + return status; } - talloc_free(c); - return status; + + io->out.wins_server = talloc_move(mem_ctx, &state->wins_servers[0]); + io->out.rcode = state->io->out.rcode; + + tevent_req_received(req); + return NT_STATUS_OK; } /* multi-homed WINS refresh - sync interface */ _PUBLIC_ NTSTATUS nbt_name_refresh_wins(struct nbt_name_socket *nbtsock, - TALLOC_CTX *mem_ctx, - struct nbt_name_refresh_wins *io) + TALLOC_CTX *mem_ctx, + struct nbt_name_refresh_wins *io) { - struct composite_context *c = nbt_name_refresh_wins_send(nbtsock, io); - return nbt_name_refresh_wins_recv(c, mem_ctx, io); + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev; + struct tevent_req *subreq; + NTSTATUS status; + + /* + * TODO: create a temporary event context + */ + ev = nbtsock->event_ctx; + + subreq = nbt_name_refresh_wins_send(frame, ev, nbtsock, io); + if (subreq == NULL) { + talloc_free(frame); + return NT_STATUS_NO_MEMORY; + } + + if (!tevent_req_poll(subreq, ev)) { + status = map_nt_error_from_unix(errno); + talloc_free(frame); + return status; + } + + status = nbt_name_refresh_wins_recv(subreq, mem_ctx, io); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(frame); + return status; + } + + TALLOC_FREE(frame); + return NT_STATUS_OK; } diff --git a/libcli/nbt/wscript_build b/libcli/nbt/wscript_build index 726b4c838c..502e023211 100644 --- a/libcli/nbt/wscript_build +++ b/libcli/nbt/wscript_build @@ -9,7 +9,7 @@ bld.SAMBA_SUBSYSTEM('NDR_NBT_BUF', bld.SAMBA_SUBSYSTEM('LIBCLI_NBT', source='lmhosts.c nbtsocket.c namequery.c nameregister.c namerefresh.c namerelease.c dns_hosts_file.c', - public_deps='LIBNDR NDR_NBT LIBCLI_COMPOSITE LIBEVENTS NDR_SECURITY samba_socket LIBSAMBA-UTIL' + public_deps='LIBNDR NDR_NBT LIBCLI_COMPOSITE tevent UTIL_TEVENT NDR_SECURITY samba_socket LIBSAMBA-UTIL' ) diff --git a/source4/nbt_server/wins/winsclient.c b/source4/nbt_server/wins/winsclient.c index f6f6ff48ec..0c513d1ae0 100644 --- a/source4/nbt_server/wins/winsclient.c +++ b/source4/nbt_server/wins/winsclient.c @@ -74,15 +74,16 @@ struct nbtd_wins_refresh_state { /* called when a wins name refresh has completed */ -static void nbtd_wins_refresh_handler(struct composite_context *subreq) +static void nbtd_wins_refresh_handler(struct tevent_req *subreq) { NTSTATUS status; struct nbtd_wins_refresh_state *state = - talloc_get_type_abort(subreq->async.private_data, + tevent_req_callback_data(subreq, struct nbtd_wins_refresh_state); struct nbtd_iface_name *iname = state->iname; status = nbt_name_refresh_wins_recv(subreq, state, &state->io); + TALLOC_FREE(subreq); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { /* our WINS server is dead - start registration over from scratch */ @@ -139,7 +140,7 @@ static void nbtd_wins_refresh(struct tevent_context *ev, struct tevent_timer *te struct nbtd_iface_name *iname = talloc_get_type(private_data, struct nbtd_iface_name); struct nbtd_interface *iface = iname->iface; struct nbt_name_socket *nbtsock = wins_socket(iface); - struct composite_context *subreq; + struct tevent_req *subreq; struct nbtd_wins_refresh_state *state; state = talloc_zero(iname, struct nbtd_wins_refresh_state); @@ -162,14 +163,13 @@ static void nbtd_wins_refresh(struct tevent_context *ev, struct tevent_timer *te return; } - subreq = nbt_name_refresh_wins_send(nbtsock, &state->io); + subreq = nbt_name_refresh_wins_send(state, ev, nbtsock, &state->io); if (subreq == NULL) { talloc_free(state); return; } - subreq->async.fn = nbtd_wins_refresh_handler; - subreq->async.private_data = state; + tevent_req_set_callback(subreq, nbtd_wins_refresh_handler, state); } -- cgit