libcli/nbt: convert nbt_name_register_wins_send/recv to tevent_req
authorStefan Metzmacher <metze@samba.org>
Mon, 11 Oct 2010 19:58:29 +0000 (21:58 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 18 Oct 2010 15:36:15 +0000 (15:36 +0000)
metze

libcli/nbt/libnbt.h
libcli/nbt/nameregister.c
source4/nbt_server/wins/winsclient.c

index 91bef5858ff0533b58cb6710d492994e24ca8aa1..dfc3b92f962592c6229d88aa3bcca0ea491d0f2c 100644 (file)
@@ -343,13 +343,16 @@ struct composite_context;
 struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock,
                                                       struct nbt_name_register_bcast *io);
 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_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_register_wins_send(TALLOC_CTX *mem_ctx,
+                                              struct tevent_context *ev,
+                                              struct nbt_name_socket *nbtsock,
+                                              struct nbt_name_register_wins *io);
+NTSTATUS nbt_name_register_wins_recv(struct tevent_req *req,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct nbt_name_register_wins *io);
 struct tevent_req *nbt_name_refresh_wins_send(TALLOC_CTX *mem_ctx,
                                              struct tevent_context *ev,
                                              struct nbt_name_socket *nbtsock,
index 12a56b564c18156263eb13e4fc4f990956a07d34..4d307d9564b01d40442e8c5342ca6abe54aac3bd 100644 (file)
 */
 
 #include "includes.h"
+#include <tevent.h>
 #include "../libcli/nbt/libnbt.h"
 #include "../libcli/nbt/nbt_proto.h"
 #include "libcli/composite/composite.h"
 #include "lib/socket/socket.h"
 #include "librpc/gen_ndr/ndr_nbt.h"
+#include "../lib/util/tevent_ntstatus.h"
 
 /*
   send a nbt name registration request
@@ -282,152 +284,172 @@ NTSTATUS nbt_name_register_bcast(struct nbt_name_socket *nbtsock,
 */
 struct nbt_name_register_wins_state {
        struct nbt_name_socket *nbtsock;
-       struct nbt_name_register *io;
-       const char **wins_servers;
+       struct nbt_name_register io;
+       char **wins_servers;
        uint16_t wins_port;
-       const char **addresses;
-       int address_idx;
-       struct nbt_name_request *req;
+       char **addresses;
+       uint32_t address_idx;
 };
 
-static void nbt_name_register_wins_handler(struct nbt_name_request *req);
+static void nbt_name_register_wins_handler(struct nbt_name_request *subreq);
 
 /*
   the async send call for a multi-server WINS register
 */
-_PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock,
-                                                     struct nbt_name_register_wins *io)
+_PUBLIC_ struct tevent_req *nbt_name_register_wins_send(TALLOC_CTX *mem_ctx,
+                                               struct tevent_context *ev,
+                                               struct nbt_name_socket *nbtsock,
+                                               struct nbt_name_register_wins *io)
 {
-       struct composite_context *c;
+       struct tevent_req *req;
        struct nbt_name_register_wins_state *state;
+       struct nbt_name_request *subreq;
 
-       c = talloc_zero(nbtsock, struct composite_context);
-       if (c == NULL) goto failed;
+       req = tevent_req_create(mem_ctx, &state,
+                               struct nbt_name_register_wins_state);
+       if (req == NULL) {
+               return NULL;
+       }
 
-       state = talloc(c, struct nbt_name_register_wins_state);
-       if (state == NULL) goto failed;
+       if (io->in.wins_servers == NULL) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return tevent_req_post(req, ev);
+       }
 
-       state->io = talloc(state, struct nbt_name_register);
-       if (state->io == NULL) goto failed;
+       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];
-       state->io->in.dest_port       = state->wins_port;
-       state->io->in.address         = io->in.addresses[0];
-       state->io->in.nb_flags        = io->in.nb_flags;
-       state->io->in.broadcast       = false;
-       state->io->in.register_demand = false;
-       state->io->in.multi_homed     = (io->in.nb_flags & NBT_NM_GROUP)?false:true;
-       state->io->in.ttl             = io->in.ttl;
-       state->io->in.timeout         = 3;
-       state->io->in.retries         = 2;
+       state->io.in.name            = io->in.name;
+       state->io.in.dest_addr       = state->wins_servers[0];
+       state->io.in.dest_port       = state->wins_port;
+       state->io.in.address         = io->in.addresses[0];
+       state->io.in.nb_flags        = io->in.nb_flags;
+       state->io.in.broadcast       = false;
+       state->io.in.register_demand = false;
+       state->io.in.multi_homed     = (io->in.nb_flags & NBT_NM_GROUP)?false:true;
+       state->io.in.ttl             = io->in.ttl;
+       state->io.in.timeout         = 3;
+       state->io.in.retries         = 2;
 
        state->nbtsock     = nbtsock;
        state->address_idx = 0;
 
-       state->req = nbt_name_register_send(nbtsock, state->io);
-       if (state->req == NULL) goto failed;
-
-       state->req->async.fn = nbt_name_register_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_register_send(nbtsock, &state->io);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
 
-       return c;
+       subreq->async.fn = nbt_name_register_wins_handler;
+       subreq->async.private_data = req;
 
-failed:
-       talloc_free(c);
-       return NULL;
+       return req;
 }
 
 /*
   state handler for WINS multi-homed multi-server name register
 */
-static void nbt_name_register_wins_handler(struct nbt_name_request *req)
+static void nbt_name_register_wins_handler(struct nbt_name_request *subreq)
 {
-       struct composite_context *c = talloc_get_type(req->async.private_data,
-                                                     struct composite_context);
-       struct nbt_name_register_wins_state *state = talloc_get_type(c->private_data,
-                                                           struct nbt_name_register_wins_state);
+       struct tevent_req *req =
+               talloc_get_type_abort(subreq->async.private_data,
+               struct tevent_req);
+       struct nbt_name_register_wins_state *state =
+               tevent_req_data(req,
+               struct nbt_name_register_wins_state);
        NTSTATUS status;
 
-       status = nbt_name_register_recv(state->req, state, state->io);
+       status = nbt_name_register_recv(subreq, state, &state->io);
        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
                /* the register 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;
-               }
-               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_register_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_register_wins_handler;
-                       state->req->async.private_data = c;
+                       tevent_req_nterror(req, status);
+                       return;
                }
-       } 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) {
-                       /* register our next address */
-                       state->io->in.address = state->addresses[++(state->address_idx)];
-                       state->req = nbt_name_register_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_register_wins_handler;
-                               state->req->async.private_data = c;
-                       }
-               } else {
-                       c->state = COMPOSITE_STATE_DONE;
-                       c->status = NT_STATUS_OK;
+
+               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];
+
+               subreq = nbt_name_register_send(state->nbtsock, &state->io);
+               if (tevent_req_nomem(subreq, req)) {
+                       return;
                }
+
+               subreq->async.fn = nbt_name_register_wins_handler;
+               subreq->async.private_data = req;
+               return;
        }
 
-done:
-       if (c->state >= COMPOSITE_STATE_DONE &&
-           c->async.fn) {
-               c->async.fn(c);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+
+       if (state->io.out.rcode == 0 &&
+           state->addresses[state->address_idx+1] != NULL) {
+               /* register our next address */
+               state->io.in.address = state->addresses[++(state->address_idx)];
+
+               subreq = nbt_name_register_send(state->nbtsock, &state->io);
+               if (tevent_req_nomem(subreq, req)) {
+                       return;
+               }
+
+               subreq->async.fn = nbt_name_register_wins_handler;
+               subreq->async.private_data = req;
+               return;
        }
+
+       tevent_req_done(req);
 }
 
 /*
   multi-homed WINS name register - recv side
 */
-_PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
-                                    struct nbt_name_register_wins *io)
+_PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct tevent_req *req,
+                                             TALLOC_CTX *mem_ctx,
+                                             struct nbt_name_register_wins *io)
 {
+       struct nbt_name_register_wins_state *state =
+               tevent_req_data(req,
+               struct nbt_name_register_wins_state);
        NTSTATUS status;
-       status = composite_wait(c);
-       if (NT_STATUS_IS_OK(status)) {
-               struct nbt_name_register_wins_state *state =
-                       talloc_get_type(c->private_data, struct nbt_name_register_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;
 }
 
 /*
@@ -437,6 +459,34 @@ _PUBLIC_ NTSTATUS nbt_name_register_wins(struct nbt_name_socket *nbtsock,
                                TALLOC_CTX *mem_ctx,
                                struct nbt_name_register_wins *io)
 {
-       struct composite_context *c = nbt_name_register_wins_send(nbtsock, io);
-       return nbt_name_register_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_register_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_register_wins_recv(subreq, mem_ctx, io);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(frame);
+               return status;
+       }
+
+       TALLOC_FREE(frame);
+       return NT_STATUS_OK;
 }
index d406a10002c4260f28188e184dc6c9bfc42d05a6..60d2b94dec5ff253299521542c36ef5ff078d935 100644 (file)
@@ -180,15 +180,16 @@ struct nbtd_wins_register_state {
 /*
   called when a wins name register has completed
 */
-static void nbtd_wins_register_handler(struct composite_context *subreq)
+static void nbtd_wins_register_handler(struct tevent_req *subreq)
 {
        NTSTATUS status;
        struct nbtd_wins_register_state *state =
-               talloc_get_type_abort(subreq->async.private_data,
+               tevent_req_callback_data(subreq,
                struct nbtd_wins_register_state);
        struct nbtd_iface_name *iname = state->iname;
 
        status = nbt_name_register_wins_recv(subreq, state, &state->io);
+       TALLOC_FREE(subreq);
        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
                /* none of the WINS servers responded - try again 
                   periodically */
@@ -248,7 +249,7 @@ void nbtd_winsclient_register(struct nbtd_iface_name *iname)
        struct nbtd_interface *iface = iname->iface;
        struct nbt_name_socket *nbtsock = wins_socket(iface);
        struct nbtd_wins_register_state *state;
-       struct composite_context *subreq;
+       struct tevent_req *subreq;
 
        state = talloc_zero(iname, struct nbtd_wins_register_state);
        if (state == NULL) {
@@ -270,12 +271,12 @@ void nbtd_winsclient_register(struct nbtd_iface_name *iname)
                return;
        }
 
-       subreq = nbt_name_register_wins_send(nbtsock, &state->io);
+       subreq = nbt_name_register_wins_send(state, iface->nbtsrv->task->event_ctx,
+                                            nbtsock, &state->io);
        if (subreq == NULL) {
                talloc_free(state);
                return;
        }
 
-       subreq->async.fn = nbtd_wins_register_handler;
-       subreq->async.private_data = state;
+       tevent_req_set_callback(subreq, nbtd_wins_register_handler, state);
 }