summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/messaging/irpc.h5
-rw-r--r--source4/lib/messaging/messaging.c21
-rw-r--r--source4/torture/local/irpc.c76
3 files changed, 91 insertions, 11 deletions
diff --git a/source4/lib/messaging/irpc.h b/source4/lib/messaging/irpc.h
index a483c78c70..93cadddd34 100644
--- a/source4/lib/messaging/irpc.h
+++ b/source4/lib/messaging/irpc.h
@@ -28,7 +28,7 @@ struct irpc_message {
};
/* don't allow calls to take too long */
-#define IRPC_CALL_TIMEOUT 10
+#define IRPC_CALL_TIMEOUT 20
/* the server function type */
@@ -44,6 +44,9 @@ typedef NTSTATUS (*irpc_function_t)(struct irpc_message *, void *r);
#define IRPC_CALL(msg_ctx, server_id, pipename, funcname, ptr) \
irpc_call(msg_ctx, server_id, &dcerpc_table_ ## pipename, DCERPC_ ## funcname, ptr)
+#define IRPC_CALL_SEND(msg_ctx, server_id, pipename, funcname, ptr) \
+ irpc_call_send(msg_ctx, server_id, &dcerpc_table_ ## pipename, DCERPC_ ## funcname, ptr)
+
/*
a pending irpc call
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index b605fa0494..be89c97e5b 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -315,7 +315,7 @@ NTSTATUS messaging_send(struct messaging_context *msg, uint32_t server,
if (msg->pending == NULL) {
EVENT_FD_WRITEABLE(msg->event.fde);
}
- DLIST_ADD(msg->pending, rec);
+ DLIST_ADD_END(msg->pending, rec, struct messaging_rec *);
return NT_STATUS_OK;
}
@@ -426,20 +426,27 @@ struct irpc_list {
*/
NTSTATUS irpc_register(struct messaging_context *msg_ctx,
const struct dcerpc_interface_table *table,
- int call, irpc_function_t fn)
+ int callnum, irpc_function_t fn)
{
struct irpc_list *irpc;
- irpc = talloc(msg_ctx, struct irpc_list);
- NT_STATUS_HAVE_NO_MEMORY(irpc);
+ /* override an existing handler, if any */
+ for (irpc=msg_ctx->irpc; irpc; irpc=irpc->next) {
+ if (irpc->table == table && irpc->callnum == callnum) {
+ break;
+ }
+ }
+ if (irpc == NULL) {
+ irpc = talloc(msg_ctx, struct irpc_list);
+ NT_STATUS_HAVE_NO_MEMORY(irpc);
+ DLIST_ADD(msg_ctx->irpc, irpc);
+ }
irpc->table = table;
- irpc->callnum = call;
+ irpc->callnum = callnum;
irpc->fn = fn;
GUID_from_string(irpc->table->uuid, &irpc->uuid);
- DLIST_ADD(msg_ctx->irpc, irpc);
-
return NT_STATUS_OK;
}
diff --git a/source4/torture/local/irpc.c b/source4/torture/local/irpc.c
index 3dc8c01da8..65564fc7b7 100644
--- a/source4/torture/local/irpc.c
+++ b/source4/torture/local/irpc.c
@@ -46,9 +46,6 @@ static BOOL test_addone(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx)
NTSTATUS status;
uint32_t res;
- /* register the server side function */
- IRPC_REGISTER(msg_ctx, rpcecho, ECHO_ADDONE, irpc_AddOne);
-
/* make the call */
r.in.in_data = random();
r.out.out_data = &res;
@@ -71,6 +68,75 @@ static BOOL test_addone(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx)
return True;
}
+
+static void irpc_callback(struct irpc_request *irpc)
+{
+ int *pong_count = (int *)irpc->async.private;
+ NTSTATUS status = irpc_call_recv(irpc);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("irpc call failed - %s\n", nt_errstr(status));
+ }
+ (*pong_count)++;
+}
+
+/*
+ test echo speed
+*/
+static BOOL test_speed(TALLOC_CTX *mem_ctx,
+ struct messaging_context *msg_ctx,
+ struct event_context *ev)
+{
+ int ping_count = 0;
+ int pong_count = 0;
+ BOOL ret = True;
+ struct timeval tv;
+ struct echo_AddOne r;
+ uint32_t res;
+
+ tv = timeval_current();
+
+ r.in.in_data = 0;
+ r.out.out_data = &res;
+
+ printf("Sending echo for 10 seconds\n");
+ while (timeval_elapsed(&tv) < 10.0) {
+ struct irpc_request *irpc;
+
+ irpc = IRPC_CALL_SEND(msg_ctx, MSG_ID, rpcecho, ECHO_ADDONE, &r);
+ if (irpc == NULL) {
+ printf("AddOne send failed\n");
+ return False;
+ }
+
+ irpc->async.fn = irpc_callback;
+ irpc->async.private = &pong_count;
+
+ ping_count++;
+
+ while (ping_count > pong_count + 20) {
+ event_loop_once(ev);
+ }
+ }
+
+ printf("waiting for %d remaining replies (done %d)\n",
+ ping_count - pong_count, pong_count);
+ while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) {
+ event_loop_once(ev);
+ }
+
+ if (ping_count != pong_count) {
+ printf("ping test failed! received %d, sent %d\n",
+ pong_count, ping_count);
+ ret = False;
+ }
+
+ printf("echo rate of %.0f messages/sec\n",
+ (ping_count+pong_count)/timeval_elapsed(&tv));
+
+ return ret;
+}
+
+
BOOL torture_local_irpc(void)
{
TALLOC_CTX *mem_ctx = talloc_init("torture_local_irpc");
@@ -83,7 +149,11 @@ BOOL torture_local_irpc(void)
ev = event_context_init(mem_ctx);
msg_ctx = messaging_init(mem_ctx, MSG_ID, ev);
+ /* register the server side function */
+ IRPC_REGISTER(msg_ctx, rpcecho, ECHO_ADDONE, irpc_AddOne);
+
ret &= test_addone(mem_ctx, msg_ctx);
+ ret &= test_speed(mem_ctx, msg_ctx, ev);
talloc_free(mem_ctx);