diff options
-rw-r--r-- | source4/lib/messaging/irpc.h | 5 | ||||
-rw-r--r-- | source4/lib/messaging/messaging.c | 21 | ||||
-rw-r--r-- | source4/torture/local/irpc.c | 76 |
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); |