s4:libcli/wrepl: convert wrepl_associate_send to tevent_req
authorStefan Metzmacher <metze@samba.org>
Wed, 3 Mar 2010 17:38:16 +0000 (18:38 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 5 Mar 2010 13:09:02 +0000 (14:09 +0100)
metze

source4/libcli/wrepl/winsrepl.c
source4/wrepl_server/wrepl_out_helpers.c

index 4bd9b653b962b33a8641825dc30c8b0db42b8901..b3b1381601e59c956410cf5ba5634db2241dee32 100644 (file)
@@ -558,22 +558,39 @@ NTSTATUS wrepl_request(struct wrepl_socket *wrepl_socket,
 }
 
 
-/*
-  setup an association - send
-*/
-struct wrepl_request *wrepl_associate_send(struct wrepl_socket *wrepl_socket,
-                                          struct wrepl_associate *io)
+struct wrepl_associate_state {
+       struct wrepl_packet packet;
+       uint32_t assoc_ctx;
+       uint16_t major_version;
+};
+
+static void wrepl_associate_done(struct wrepl_request *subreq);
+
+struct tevent_req *wrepl_associate_send(TALLOC_CTX *mem_ctx,
+                                       struct tevent_context *ev,
+                                       struct wrepl_socket *wrepl_socket,
+                                       const struct wrepl_associate *io)
 {
-       struct wrepl_packet *packet;
-       struct wrepl_request *req;
+       struct tevent_req *req;
+       struct wrepl_associate_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_associate_send event context mismatch!");
+               return NULL;
+       }
 
-       packet->opcode                      = WREPL_OPCODE_BITS;
-       packet->mess_type                   = WREPL_START_ASSOCIATION;
-       packet->message.start.minor_version = 2;
-       packet->message.start.major_version = 5;
+       req = tevent_req_create(mem_ctx, &state,
+                               struct wrepl_associate_state);
+       if (req == NULL) {
+               return NULL;
+       };
+
+       state->packet.opcode                            = WREPL_OPCODE_BITS;
+       state->packet.mess_type                         = WREPL_START_ASSOCIATION;
+       state->packet.message.start.minor_version       = 2;
+       state->packet.message.start.major_version       = 5;
 
        /*
         * nt4 uses 41 bytes for the start_association call
@@ -583,39 +600,68 @@ struct wrepl_request *wrepl_associate_send(struct wrepl_socket *wrepl_socket,
         * if we don't do this nt4 uses an old version of the wins replication protocol
         * and that would break nt4 <-> samba replication
         */
-       packet->padding = data_blob_talloc(packet, NULL, 21);
-       if (packet->padding.data == NULL) {
-               talloc_free(packet);
-               return NULL;
+       state->packet.padding   = data_blob_talloc(state, NULL, 21);
+       if (tevent_req_nomem(state->packet.padding.data, req)) {
+               return tevent_req_post(req, ev);
        }
-       memset(packet->padding.data, 0, packet->padding.length);
+       memset(state->packet.padding.data, 0, state->packet.padding.length);
 
-       req = wrepl_request_send(wrepl_socket, packet, NULL);
+       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_associate_done;
+       subreq->async.private_data = req;
 
-       talloc_free(packet);
+       return req;
+}
 
-       return req;     
+static void wrepl_associate_done(struct wrepl_request *subreq)
+{
+       struct tevent_req *req = talloc_get_type_abort(subreq->async.private_data,
+                                struct tevent_req);
+       struct wrepl_associate_state *state = tevent_req_data(req,
+                                             struct wrepl_associate_state);
+       NTSTATUS status;
+       struct wrepl_packet *packet;
+
+       status = wrepl_request_recv(subreq, state, &packet);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+
+       if (packet->mess_type != WREPL_START_ASSOCIATION_REPLY) {
+               tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
+               return;
+       }
+
+       state->assoc_ctx = packet->message.start_reply.assoc_ctx;
+       state->major_version = packet->message.start_reply.major_version;
+
+       tevent_req_done(req);
 }
 
 /*
   setup an association - recv
 */
-NTSTATUS wrepl_associate_recv(struct wrepl_request *req,
+NTSTATUS wrepl_associate_recv(struct tevent_req *req,
                              struct wrepl_associate *io)
 {
-       struct wrepl_packet *packet=NULL;
+       struct wrepl_associate_state *state = tevent_req_data(req,
+                                             struct wrepl_associate_state);
        NTSTATUS status;
-       status = wrepl_request_recv(req, req->wrepl_socket, &packet);
-       NT_STATUS_NOT_OK_RETURN(status);
-       if (packet->mess_type != WREPL_START_ASSOCIATION_REPLY) {
-               status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
-       }
-       if (NT_STATUS_IS_OK(status)) {
-               io->out.assoc_ctx = packet->message.start_reply.assoc_ctx;
-               io->out.major_version = packet->message.start_reply.major_version;
+
+       if (tevent_req_is_nterror(req, &status)) {
+               tevent_req_received(req);
+               return status;
        }
-       talloc_free(packet);
-       return status;
+
+       io->out.assoc_ctx = state->assoc_ctx;
+       io->out.major_version = state->major_version;
+
+       tevent_req_received(req);
+       return NT_STATUS_OK;
 }
 
 /*
@@ -624,10 +670,26 @@ NTSTATUS wrepl_associate_recv(struct wrepl_request *req,
 NTSTATUS wrepl_associate(struct wrepl_socket *wrepl_socket,
                         struct wrepl_associate *io)
 {
-       struct wrepl_request *req = wrepl_associate_send(wrepl_socket, io);
-       return wrepl_associate_recv(req, io);
-}
+       struct tevent_req *subreq;
+       bool ok;
+       NTSTATUS status;
 
+       subreq = wrepl_associate_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_recv(subreq, io);
+       TALLOC_FREE(subreq);
+       NT_STATUS_NOT_OK_RETURN(status);
+
+       return NT_STATUS_OK;
+}
 
 /*
   stop an association - send
index 97457614363ced75e1580b6eabcba98c9d1e5b00..352be8503d5f1758173384bd76f65cf1eff6227c 100644 (file)
@@ -41,15 +41,15 @@ enum wreplsrv_out_connect_stage {
 struct wreplsrv_out_connect_state {
        enum wreplsrv_out_connect_stage stage;
        struct composite_context *c;
-       struct wrepl_request *req;
        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_req(struct wrepl_request *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)
 {
@@ -58,11 +58,14 @@ static NTSTATUS wreplsrv_out_connect_wait_socket(struct wreplsrv_out_connect_sta
        status = wrepl_connect_recv(state->c_req);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       state->req = wrepl_associate_send(state->wreplconn->sock, &state->assoc_io);
-       NT_STATUS_HAVE_NO_MEMORY(state->req);
+       state->subreq = wrepl_associate_send(state,
+                                            state->wreplconn->service->task->event_ctx,
+                                            state->wreplconn->sock, &state->assoc_io);
+       NT_STATUS_HAVE_NO_MEMORY(state->subreq);
 
-       state->req->async.fn            = wreplsrv_out_connect_handler_req;
-       state->req->async.private_data  = state;
+       tevent_req_set_callback(state->subreq,
+                               wreplsrv_out_connect_handler_treq,
+                               state);
 
        state->stage = WREPLSRV_OUT_CONNECT_STAGE_WAIT_ASSOC_CTX;
 
@@ -73,7 +76,8 @@ static NTSTATUS wreplsrv_out_connect_wait_assoc_ctx(struct wreplsrv_out_connect_
 {
        NTSTATUS status;
 
-       status = wrepl_associate_recv(state->req, &state->assoc_io);
+       status = wrepl_associate_recv(state->subreq, &state->assoc_io);
+       TALLOC_FREE(state->subreq);
        NT_STATUS_NOT_OK_RETURN(status);
 
        state->wreplconn->assoc_ctx.peer_ctx = state->assoc_io.out.assoc_ctx;
@@ -129,9 +133,9 @@ static void wreplsrv_out_connect_handler_creq(struct composite_context *creq)
        return;
 }
 
-static void wreplsrv_out_connect_handler_req(struct wrepl_request *req)
+static void wreplsrv_out_connect_handler_treq(struct tevent_req *subreq)
 {
-       struct wreplsrv_out_connect_state *state = talloc_get_type(req->async.private_data,
+       struct wreplsrv_out_connect_state *state = tevent_req_callback_data(subreq,
                                                   struct wreplsrv_out_connect_state);
        wreplsrv_out_connect_handler(state);
        return;