summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-09-02 12:03:16 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:58:30 -0500
commiteaab3ed2d25fbd9beb2675eb8a45fcb1821fc520 (patch)
tree1551d4be5ba707150eb1c3350a80f9bdbddb744e
parentb990e9a97b02cec9f012bacc6bb266a0403f6792 (diff)
downloadsamba-eaab3ed2d25fbd9beb2675eb8a45fcb1821fc520.tar.gz
samba-eaab3ed2d25fbd9beb2675eb8a45fcb1821fc520.tar.bz2
samba-eaab3ed2d25fbd9beb2675eb8a45fcb1821fc520.zip
r2185: add a callback function to the dcerpc async API
also add a demonstration of its use in the netlogon async example (This used to be commit f2a0438c66b999189c1a2ad726e91efd0748eb90)
-rw-r--r--source4/librpc/rpc/dcerpc.c20
-rw-r--r--source4/librpc/rpc/dcerpc.h5
-rw-r--r--source4/torture/rpc/netlogon.c24
3 files changed, 45 insertions, 4 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index ec22696419..55acf4625c 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -631,6 +631,9 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
req->state = RPC_REQUEST_DONE;
req->status = status;
DLIST_REMOVE(p->pending, req);
+ if (req->async.callback) {
+ req->async.callback(req);
+ }
}
return;
}
@@ -655,6 +658,9 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
req->status = status;
req->state = RPC_REQUEST_DONE;
DLIST_REMOVE(p->pending, req);
+ if (req->async.callback) {
+ req->async.callback(req);
+ }
return;
}
@@ -664,6 +670,9 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
req->status = NT_STATUS_NET_WRITE_FAULT;
req->state = RPC_REQUEST_DONE;
DLIST_REMOVE(p->pending, req);
+ if (req->async.callback) {
+ req->async.callback(req);
+ }
return;
}
@@ -674,6 +683,9 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
req->status = NT_STATUS_NET_WRITE_FAULT;
req->state = RPC_REQUEST_DONE;
DLIST_REMOVE(p->pending, req);
+ if (req->async.callback) {
+ req->async.callback(req);
+ }
return;
}
@@ -686,6 +698,9 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
req->status = NT_STATUS_NO_MEMORY;
req->state = RPC_REQUEST_DONE;
DLIST_REMOVE(p->pending, req);
+ if (req->async.callback) {
+ req->async.callback(req);
+ }
return;
}
memcpy(req->payload.data+req->payload.length,
@@ -707,6 +722,10 @@ static void dcerpc_request_recv_data(struct dcerpc_pipe *p,
} else {
req->flags &= ~DCERPC_PULL_BIGENDIAN;
}
+
+ if (req->async.callback) {
+ req->async.callback(req);
+ }
}
@@ -737,6 +756,7 @@ struct rpc_request *dcerpc_request_send(struct dcerpc_pipe *p,
req->payload = data_blob(NULL, 0);
req->flags = 0;
req->fault_code = 0;
+ req->async.callback = NULL;
init_dcerpc_hdr(p, &pkt);
diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h
index 1443e10927..0ec1abf55d 100644
--- a/source4/librpc/rpc/dcerpc.h
+++ b/source4/librpc/rpc/dcerpc.h
@@ -166,4 +166,9 @@ struct rpc_request {
size_t struct_size;
TALLOC_CTX *mem_ctx;
} ndr;
+
+ struct {
+ void (*callback)(struct rpc_request *);
+ void *private;
+ } async;
};
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index d5acfa8c36..5cb4caa942 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -1625,6 +1625,14 @@ static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
}
+static void async_callback(struct rpc_request *req)
+{
+ int *counter = req->async.private;
+ if (NT_STATUS_IS_OK(req->status)) {
+ (*counter)++;
+ }
+}
+
static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
@@ -1636,6 +1644,7 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct creds_CredentialState creds_async[ASYNC_COUNT];
struct rpc_request *req[ASYNC_COUNT];
int i;
+ int async_counter = 0;
if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS, &creds)) {
return False;
@@ -1670,6 +1679,13 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
creds_async[i] = creds;
req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
+
+ req[i]->async.callback = async_callback;
+ req[i]->async.private = &async_counter;
+
+ /* even with this flush per request a w2k3 server seems to
+ clag with multiple outstanding requests. bleergh. */
+ event_loop_once(dcerpc_event_context(p));
}
for (i=0;i<ASYNC_COUNT;i++) {
@@ -1677,18 +1693,18 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
if (!NT_STATUS_IS_OK(status) || !NT_STATUS_IS_OK(r.out.result)) {
printf("netr_LogonGetDomainInfo_async(%d) - %s/%s\n",
i, nt_errstr(status), nt_errstr(r.out.result));
- return False;
+ break;
}
if (!creds_client_check(&creds_async[i], &a.cred)) {
printf("Credential chaining failed at async %d\n", i);
- return False;
+ break;
}
}
- printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", ASYNC_COUNT);
+ printf("Testing netr_LogonGetDomainInfo - async count %d OK\n", async_counter);
- return True;
+ return async_counter == ASYNC_COUNT;
}