Merge branch 'master' of ssh://git.samba.org/data/git/samba into displaysec
[sfrench/samba-autobuild/.git] / source4 / torture / ldap / cldapbench.c
index c57ed6d48a25feacadd2016b095b48c44601d07c..a422732b039100dc62975f6badd4b3b29eb10abb 100644 (file)
 */
 
 #include "includes.h"
-#include "lib/events/events.h"
+#include <tevent.h>
 #include "libcli/cldap/cldap.h"
 #include "libcli/resolve/resolve.h"
 #include "torture/torture.h"
 #include "param/param.h"
 
 struct bench_state {
+       struct torture_context *tctx;
        int pass_count, fail_count;
 };
 
-static void request_handler(struct cldap_request *req)
+static void request_netlogon_handler(struct tevent_req *req)
 {
        struct cldap_netlogon io;
-       struct bench_state *state = talloc_get_type(req->async.private, struct bench_state);
+       struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
        NTSTATUS status;
        TALLOC_CTX *tmp_ctx = talloc_new(NULL);
        io.in.version = 6;
-       status = cldap_netlogon_recv(req, tmp_ctx, &io);
+       status = cldap_netlogon_recv(req,
+                                    lp_iconv_convenience(state->tctx->lp_ctx),
+                                    tmp_ctx, &io);
+       talloc_free(req);
        if (NT_STATUS_IS_OK(status)) {
                state->pass_count++;
        } else {
@@ -47,19 +51,24 @@ static void request_handler(struct cldap_request *req)
 }
 
 /*
-  benchmark cldap calls
+  benchmark cldap netlogon calls
 */
-static bool bench_cldap(struct torture_context *tctx, const char *address)
+static bool bench_cldap_netlogon(struct torture_context *tctx, const char *address)
 {
-       struct cldap_socket *cldap = cldap_socket_init(tctx, NULL);
+       struct cldap_socket *cldap;
        int num_sent=0;
        struct timeval tv = timeval_current();
        bool ret = true;
        int timelimit = torture_setting_int(tctx, "timelimit", 10);
        struct cldap_netlogon search;
        struct bench_state *state;
+       NTSTATUS status;
+
+       status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap);
+       torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
 
        state = talloc_zero(tctx, struct bench_state);
+       state->tctx = tctx;
 
        ZERO_STRUCT(search);
        search.in.dest_address = address;
@@ -67,14 +76,14 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
        search.in.acct_control = -1;
        search.in.version = 6;
 
-       printf("Running for %d seconds\n", timelimit);
+       printf("Running CLDAP/netlogon for %d seconds\n", timelimit);
        while (timeval_elapsed(&tv) < timelimit) {
                while (num_sent - (state->pass_count+state->fail_count) < 10) {
-                       struct cldap_request *req;
-                       req = cldap_netlogon_send(cldap, &search);
+                       struct tevent_req *req;
+                       req = cldap_netlogon_send(state, cldap, &search);
+
+                       tevent_req_set_callback(req, request_netlogon_handler, state);
 
-                       req->async.private = state;
-                       req->async.fn = request_handler;
                        num_sent++;
                        if (num_sent % 50 == 0) {
                                if (torture_setting_bool(tctx, "progress", true)) {
@@ -86,11 +95,11 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
                        }
                }
 
-               event_loop_once(cldap->event_ctx);
+               tevent_loop_once(tctx->ev);
        }
 
        while (num_sent != (state->pass_count + state->fail_count)) {
-               event_loop_once(cldap->event_ctx);
+               tevent_loop_once(tctx->ev);
        }
 
        printf("%.1f queries per second (%d failures)  \n", 
@@ -101,6 +110,81 @@ static bool bench_cldap(struct torture_context *tctx, const char *address)
        return ret;
 }
 
+static void request_rootdse_handler(struct tevent_req *req)
+{
+       struct cldap_search io;
+       struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
+       NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+       status = cldap_search_recv(req, tmp_ctx, &io);
+       talloc_free(req);
+       if (NT_STATUS_IS_OK(status)) {
+               state->pass_count++;
+       } else {
+               state->fail_count++;
+       }
+       talloc_free(tmp_ctx);
+}
+
+/*
+  benchmark cldap netlogon calls
+*/
+static bool bench_cldap_rootdse(struct torture_context *tctx, const char *address)
+{
+       struct cldap_socket *cldap;
+       int num_sent=0;
+       struct timeval tv = timeval_current();
+       bool ret = true;
+       int timelimit = torture_setting_int(tctx, "timelimit", 10);
+       struct cldap_search search;
+       struct bench_state *state;
+       NTSTATUS status;
+
+       status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap);
+       torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
+
+       state = talloc_zero(tctx, struct bench_state);
+
+       ZERO_STRUCT(search);
+       search.in.dest_address  = address;
+       search.in.dest_port     = lp_cldap_port(tctx->lp_ctx);
+       search.in.filter        = "(objectClass=*)";
+       search.in.timeout       = 2;
+       search.in.retries       = 1;
+
+       printf("Running CLDAP/rootdse for %d seconds\n", timelimit);
+       while (timeval_elapsed(&tv) < timelimit) {
+               while (num_sent - (state->pass_count+state->fail_count) < 10) {
+                       struct tevent_req *req;
+                       req = cldap_search_send(state, cldap, &search);
+
+                       tevent_req_set_callback(req, request_rootdse_handler, state);
+
+                       num_sent++;
+                       if (num_sent % 50 == 0) {
+                               if (torture_setting_bool(tctx, "progress", true)) {
+                                       printf("%.1f queries per second (%d failures)  \r",
+                                              state->pass_count / timeval_elapsed(&tv),
+                                              state->fail_count);
+                                       fflush(stdout);
+                               }
+                       }
+               }
+
+               tevent_loop_once(tctx->ev);
+       }
+
+       while (num_sent != (state->pass_count + state->fail_count)) {
+               tevent_loop_once(tctx->ev);
+       }
+
+       printf("%.1f queries per second (%d failures)  \n",
+              state->pass_count / timeval_elapsed(&tv),
+              state->fail_count);
+
+       talloc_free(cldap);
+       return ret;
+}
 
 /*
   benchmark how fast a CLDAP server can respond to a series of parallel
@@ -116,14 +200,15 @@ bool torture_bench_cldap(struct torture_context *torture)
        make_nbt_name_server(&name, torture_setting_string(torture, "host", NULL));
 
        /* do an initial name resolution to find its IP */
-       status = resolve_name(lp_resolve_context(torture->lp_ctx), &name, torture, &address, event_context_find(torture));
+       status = resolve_name(lp_resolve_context(torture->lp_ctx), &name, torture, &address, torture->ev);
        if (!NT_STATUS_IS_OK(status)) {
                printf("Failed to resolve %s - %s\n",
                       name.name, nt_errstr(status));
                return false;
        }
 
-       ret &= bench_cldap(torture, address);
+       ret &= bench_cldap_netlogon(torture, address);
+       ret &= bench_cldap_rootdse(torture, address);
 
        return ret;
 }