]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
Add start_time to reply callbacks so modules can compute the response time. 391/head
authorFrank Riley <fhriley@gmail.com>
Fri, 1 Jan 2021 22:29:32 +0000 (15:29 -0700)
committerFrank Riley <fhriley@gmail.com>
Fri, 1 Jan 2021 22:44:21 +0000 (15:44 -0700)
12 files changed:
daemon/worker.c
dynlibmod/dynlibmod.c
dynlibmod/dynlibmod.h
dynlibmod/examples/helloworld.c
pythonmod/interface.i
pythonmod/pythonmod.h
services/authzone.c
services/localzone.c
services/mesh.c
util/data/msgreply.c
util/data/msgreply.h
util/module.h

index 76c4bb5b1e76702912dd17bb887d17d369497378..edf96988a3067926c10a377bacd6a9db75465c54 100644 (file)
@@ -513,7 +513,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
                        edns->ext_rcode = 0;
                        edns->bits &= EDNS_DO;
                        if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL,
-                               msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
+                               msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
+                               *worker->env.now_tv))
                                        return 0;
                        error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, 
                                &msg->qinfo, id, flags, edns);
@@ -544,7 +545,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
        edns->ext_rcode = 0;
        edns->bits &= EDNS_DO;
        if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, msg->rep,
-               (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
+               (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad,
+        *worker->env.now_tv))
                        return 0;
        msg->rep->flags |= BIT_QR|BIT_RA;
        if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
@@ -553,7 +555,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
                repinfo->c->buffer, 0, 1, worker->scratchpad,
                udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
                if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
-                       LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
+                       LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
+                       *worker->env.now_tv))
                                edns->opt_list = NULL;
                error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, 
                        &msg->qinfo, id, flags, edns);
@@ -684,7 +687,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
                edns->ext_rcode = 0;
                edns->bits &= EDNS_DO;
                if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
-                       LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
+                       LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
+           *worker->env.now_tv))
                        goto bail_out;
                error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
                        qinfo, id, flags, edns);
@@ -718,7 +722,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
        edns->ext_rcode = 0;
        edns->bits &= EDNS_DO;
        if(!inplace_cb_reply_cache_call(&worker->env, qinfo, NULL, rep,
-               (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad))
+               (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad,
+               *worker->env.now_tv))
                goto bail_out;
        *alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
        if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
@@ -754,7 +759,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
                repinfo->c->buffer, timenow, 1, worker->scratchpad,
                udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) {
                if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
-                       LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad))
+                       LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
+           *worker->env.now_tv))
                                edns->opt_list = NULL;
                error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, 
                        qinfo, id, flags, edns);
@@ -842,7 +848,8 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
        edns->udp_size = EDNS_ADVERTISED_SIZE;
        edns->bits &= EDNS_DO;
        if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
-               LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad))
+               LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad,
+        *worker->env.now_tv))
                        edns->opt_list = NULL;
        if(sldns_buffer_capacity(pkt) >=
                sldns_buffer_limit(pkt)+calc_edns_field_size(edns))
index 3f148ebb64871c85ab5e97028d1a42ad4c88c993..e842c9d8a2d1b8ad7a04736fc40ebb0637a78a1a 100644 (file)
@@ -212,10 +212,10 @@ size_t dynlibmod_get_mem(struct module_env* env, int id) {
 int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
     struct module_qstate* qstate, struct reply_info* rep, int rcode,
     struct edns_data* edns, struct edns_option** opt_list_out,
-    struct comm_reply* repinfo, struct regional* region, int id,
-    void* callback) {
+    struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time, int id, void* callback) {
     struct cb_pair* cb_pair = (struct cb_pair*) callback;
-    return ((inplace_cb_reply_func_type*) cb_pair->cb)(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, region, id, cb_pair->cb_arg);
+    return ((inplace_cb_reply_func_type*) cb_pair->cb)(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, region, start_time, id, cb_pair->cb_arg);
 }
 
 int dynlib_inplace_cb_query_generic(struct query_info* qinfo, uint16_t flags,
index c34cf0e88d922a5bb7bd19d40a3c7fc797313fb1..f35dafa1a1d1fb466b931968879d8f1a2f700448 100644 (file)
@@ -70,8 +70,8 @@ size_t dynlibmod_get_mem(struct module_env* env, int id);
 int dynlib_inplace_cb_reply_generic(struct query_info* qinfo,
     struct module_qstate* qstate, struct reply_info* rep, int rcode,
     struct edns_data* edns, struct edns_option** opt_list_out,
-    struct comm_reply* repinfo, struct regional* region, int id,
-    void* callback);
+    struct comm_reply* repinfo, struct regional* region,
+       struct timeval start_time, int id, void* callback);
 
 int dynlib_inplace_cb_query_generic(struct query_info* qinfo, uint16_t flags,
     struct module_qstate* qstate, struct sockaddr_storage* addr,
index acb6b5d9bda6a128d871f9b3e61a85713f22b7bb..5ea9c51bea6e7204181d936b12e344136e285113 100644 (file)
@@ -30,8 +30,8 @@
 int reply_callback(struct query_info* qinfo,
     struct module_qstate* qstate, struct reply_info* rep, int rcode,
     struct edns_data* edns, struct edns_option** opt_list_out,
-    struct comm_reply* repinfo, struct regional* region, int id,
-    void* callback);
+    struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time, int id, void* callback);
 
 /* Init is called when the module is first loaded. It should be used to set up
  * the environment for this module and do any other initialisation required. */
@@ -116,8 +116,8 @@ EXPORT size_t get_mem(struct module_env* env, int id) {
 int reply_callback(struct query_info* qinfo,
     struct module_qstate* qstate, struct reply_info* rep, int rcode,
     struct edns_data* edns, struct edns_option** opt_list_out,
-    struct comm_reply* repinfo, struct regional* region, int id,
-    void* callback) {
+    struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time, int id, void* callback) {
     log_info("dynlib: hello world from callback");
     struct dynlibmod_env* env = qstate->env->modinfo[id];
     if (env->dyn_env != NULL) {
index cbee4f7147643ca4cc31e6f432fae11f589f2038..8f44e52b6631f3569c8d60e1d7ef3f13a3e38f36 100644 (file)
@@ -20,6 +20,7 @@
  * called to perform operations on queries.
  */
    #include <sys/types.h>
+   #include <time.h>
    #ifdef HAVE_SYS_SOCKET_H
    #include <sys/socket.h>
    #endif
@@ -696,6 +697,8 @@ struct edns_data {
 /* ************************************************************************************ *
    Structure module_env
  * ************************************************************************************ */
+%rename(_now) module_env::now;
+%rename(_now_tv) module_env::now_tv;
 struct module_env {
     struct config_file* cfg;
     struct slabhash* msg_cache;
@@ -739,6 +742,19 @@ struct module_env {
     size_t edns_known_options_num;
 };
 
+%inline %{
+    PyObject* _module_env_now_get(struct module_env* env) {
+        double ts = env->now_tv->tv_sec + env->now_tv->tv_usec / 1e6;
+        return PyFloat_FromDouble(ts);
+    }
+%}
+%extend module_env {
+    %pythoncode %{
+        def _now_get(self): return _module_env_now_get(self)
+        now = property(_now_get)
+    %}
+}
+
 /* ************************************************************************************ *
    Structure module_qstate
  * ************************************************************************************ */
@@ -1525,13 +1541,14 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
     int python_inplace_cb_reply_generic(struct query_info* qinfo,
         struct module_qstate* qstate, struct reply_info* rep, int rcode,
         struct edns_data* edns, struct edns_option** opt_list_out,
-        struct comm_reply* repinfo, struct regional* region, int id,
-        void* python_callback)
+        struct comm_reply* repinfo, struct regional* region,
+        struct timeval start_time, int id, void* python_callback)
     {
         PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo;
         PyObject *py_rep, *py_repinfo, *py_region;
         PyObject *py_args, *py_kwargs, *result;
         int res = 0;
+        double py_start_time = start_time.tv_sec + start_time.tv_usec / 1e6;
 
         PyGILState_STATE gstate = PyGILState_Ensure();
         func = (PyObject *) python_callback;
@@ -1546,7 +1563,8 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
         py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0);
         py_args = Py_BuildValue("(OOOiOOO)", py_qinfo, py_qstate, py_rep,
             rcode, py_edns, py_opt_list_out, py_region);
-        py_kwargs = Py_BuildValue("{s:O}", "repinfo", py_repinfo);
+        py_kwargs = Py_BuildValue("{s:O,s:d}", "repinfo", py_repinfo, "start_time",
+                                  py_start_time);
         result = PyObject_Call(func, py_args, py_kwargs);
         Py_XDECREF(py_edns);
         Py_XDECREF(py_qstate);
index ae8af27eb22b4d6342a5a4836e128cc39b37d186..222ebd71e6616d5899b3a633d8488ed84858db5c 100644 (file)
@@ -72,8 +72,8 @@ size_t pythonmod_get_mem(struct module_env* env, int id);
 int python_inplace_cb_reply_generic(struct query_info* qinfo,
        struct module_qstate* qstate, struct reply_info* rep, int rcode,
        struct edns_data* edns, struct edns_option** opt_list_out,
-       struct comm_reply* repinfo, struct regional* region, int id,
-       void* python_callback);
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time, int id, void* python_callback);
 
 /** Declared here for fptr_wlist access. The definition is in interface.i. */
 int python_inplace_cb_query_generic(
index e59548fc3198aedb42c2725a2a11111d73d9f693..0f6d691a26241704ede4cea22243b7d305aa924f 100644 (file)
@@ -3286,7 +3286,7 @@ auth_answer_encode(struct query_info* qinfo, struct module_env* env,
        edns->bits &= EDNS_DO;
 
        if(!inplace_cb_reply_local_call(env, qinfo, NULL, msg->rep,
-               (int)FLAGS_GET_RCODE(msg->rep->flags), edns, repinfo, temp)
+               (int)FLAGS_GET_RCODE(msg->rep->flags), edns, repinfo, temp, *env->now_tv)
                || !reply_info_answer_encode(qinfo, msg->rep,
                *(uint16_t*)sldns_buffer_begin(buf),
                sldns_buffer_read_u16_at(buf, 2),
@@ -3310,7 +3310,7 @@ auth_error_encode(struct query_info* qinfo, struct module_env* env,
        edns->bits &= EDNS_DO;
 
        if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
-               rcode, edns, repinfo, temp))
+               rcode, edns, repinfo, temp, *env->now_tv))
                edns->opt_list = NULL;
        error_encode(buf, rcode|BIT_AA, qinfo,
                *(uint16_t*)sldns_buffer_begin(buf),
index cad46066334c90bd8f22308de10420b3dbec6d5f..308150a00b3593219dfa3fa164aaff95d9a23749 100644 (file)
@@ -1215,7 +1215,7 @@ local_encode(struct query_info* qinfo, struct module_env* env,
        edns->ext_rcode = 0;
        edns->bits &= EDNS_DO;
        if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns,
-               repinfo, temp) || !reply_info_answer_encode(qinfo, &rep,
+               repinfo, temp, *env->now_tv) || !reply_info_answer_encode(qinfo, &rep,
                *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2),
                buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) {
                error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo,
@@ -1237,7 +1237,7 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
        edns->bits &= EDNS_DO;
 
        if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
-               rcode, edns, repinfo, temp))
+               rcode, edns, repinfo, temp, *env->now_tv))
                edns->opt_list = NULL;
        error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
                sldns_buffer_read_u16_at(buf, 2), edns);
index cd90509366f29249336d93bec64053a590252425..de481c0d5e5bdbded6eeef342e6993ae42035789 100644 (file)
@@ -498,7 +498,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
                if(!s) {
                        log_err("mesh_state_create: out of memory; SERVFAIL");
                        if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
-                               LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
+                               LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, *s->s.env->now_tv))
                                        edns->opt_list = NULL;
                        error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
                                qinfo, qid, qflags, edns);
@@ -514,7 +514,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
                        if(!s->s.edns_opts_front_in) {
                                log_err("mesh_state_create: out of memory; SERVFAIL");
                                if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL,
-                                       NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
+                                       NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, *s->s.env->now_tv))
                                                edns->opt_list = NULL;
                                error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
                                        qinfo, qid, qflags, edns);
@@ -587,7 +587,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
 
 servfail_mem:
        if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
-               NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
+               NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, *s->s.env->now_tv))
                        edns->opt_list = NULL;
        error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
                qinfo, qid, qflags, edns);
@@ -1115,7 +1115,7 @@ int mesh_state_attachment(struct mesh_state* super, struct mesh_state* sub)
  */
 static void
 mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
-       struct mesh_cb* r)
+       struct mesh_cb* r, struct timeval start_time)
 {
        int secure;
        char* reason = NULL;
@@ -1136,11 +1136,11 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
        if(rcode) {
                if(rcode == LDNS_RCODE_SERVFAIL) {
                        if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
-                               rep, rcode, &r->edns, NULL, m->s.region))
+                               rep, rcode, &r->edns, NULL, m->s.region, start_time))
                                        r->edns.opt_list = NULL;
                } else {
                        if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
-                               &r->edns, NULL, m->s.region))
+                               &r->edns, NULL, m->s.region, start_time))
                                        r->edns.opt_list = NULL;
                }
                fptr_ok(fptr_whitelist_mesh_cb(r->cb));
@@ -1155,7 +1155,7 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
                r->edns.bits &= EDNS_DO;
 
                if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
-                       LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) ||
+                       LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region, start_time) ||
                        !reply_info_answer_encode(&m->s.qinfo, rep, r->qid, 
                        r->qflags, r->buf, 0, 1, 
                        m->s.env->scratch, udp_size, &r->edns, 
@@ -1256,11 +1256,11 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                m->s.qinfo.local_alias = r->local_alias;
                if(rcode == LDNS_RCODE_SERVFAIL) {
                        if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
-                               rep, rcode, &r->edns, &r->query_reply, m->s.region))
+                               rep, rcode, &r->edns, &r->query_reply, m->s.region, r->start_time))
                                        r->edns.opt_list = NULL;
                } else { 
                        if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
-                               &r->edns, &r->query_reply, m->s.region))
+                               &r->edns, &r->query_reply, m->s.region, r->start_time))
                                        r->edns.opt_list = NULL;
                }
                error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
@@ -1277,7 +1277,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                m->s.qinfo.qname = r->qname;
                m->s.qinfo.local_alias = r->local_alias;
                if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
-                       LDNS_RCODE_NOERROR, &r->edns, &r->query_reply, m->s.region) ||
+                       LDNS_RCODE_NOERROR, &r->edns, &r->query_reply, m->s.region, r->start_time) ||
                        !apply_edns_options(&r->edns, &edns_bak,
                                m->s.env->cfg, r->query_reply.c,
                                m->s.region) ||
@@ -1287,7 +1287,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                        secure)) 
                {
                        if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
-                       rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region))
+                       rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, r->start_time))
                                r->edns.opt_list = NULL;
                        error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
                                &m->s.qinfo, r->qid, r->qflags, &r->edns);
@@ -1330,6 +1330,7 @@ void mesh_query_done(struct mesh_state* mstate)
        struct mesh_cb* c;
        struct reply_info* rep = (mstate->s.return_msg?
                mstate->s.return_msg->rep:NULL);
+       struct timeval tv = {0, 0};
        /* No need for the serve expired timer anymore; we are going to reply. */
        if(mstate->s.serve_expired_data) {
                comm_timer_delete(mstate->s.serve_expired_data->timer);
@@ -1349,6 +1350,8 @@ void mesh_query_done(struct mesh_state* mstate)
                }
        }
        for(r = mstate->reply_list; r; r = r->next) {
+           tv = r->start_time;
+
                /* if a response-ip address block has been stored the
                 *  information should be logged for each client. */
                if(mstate->s.respip_action_info &&
@@ -1421,7 +1424,7 @@ void mesh_query_done(struct mesh_state* mstate)
                if(!mstate->reply_list && !mstate->cb_list &&
                        mstate->super_set.count == 0)
                        mstate->s.env->mesh->num_detached_states++;
-               mesh_do_callback(mstate, mstate->s.return_rcode, rep, c);
+               mesh_do_callback(mstate, mstate->s.return_rcode, rep, c, tv);
        }
 }
 
@@ -1917,6 +1920,7 @@ mesh_serve_expired_callback(void* arg)
        struct respip_action_info actinfo;
        struct query_info* lookup_qinfo = &qstate->qinfo;
        struct query_info qinfo_tmp;
+       struct timeval tv = {0, 0};
        int must_validate = (!(qstate->query_flags&BIT_CD)
                || qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
        if(!qstate->serve_expired_data) return;
@@ -1988,6 +1992,8 @@ mesh_serve_expired_callback(void* arg)
                log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
 
        for(r = mstate->reply_list; r; r = r->next) {
+           tv = r->start_time;
+
                /* If address info is returned, it means the action should be an
                * 'inform' variant and the information should be logged. */
                if(actinfo.addrinfo) {
@@ -2042,6 +2048,6 @@ mesh_serve_expired_callback(void* arg)
                if(!mstate->reply_list && !mstate->cb_list &&
                        mstate->super_set.count == 0)
                        qstate->env->mesh->num_detached_states++;
-               mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c);
+               mesh_do_callback(mstate, LDNS_RCODE_NOERROR, msg->rep, c, tv);
        }
 }
index 927bf09a29d8f8372e19c700966c2cdef2a1e4fd..3f7eb5fc9af1ada4b9a53264aa6aa3323e954246 100644 (file)
@@ -1035,7 +1035,8 @@ static int inplace_cb_reply_call_generic(
     struct inplace_cb* callback_list, enum inplace_cb_list_type type,
        struct query_info* qinfo, struct module_qstate* qstate,
        struct reply_info* rep, int rcode, struct edns_data* edns,
-       struct comm_reply* repinfo, struct regional* region)
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time)
 {
        struct inplace_cb* cb;
        struct edns_option* opt_list_out = NULL;
@@ -1048,7 +1049,7 @@ static int inplace_cb_reply_call_generic(
                fptr_ok(fptr_whitelist_inplace_cb_reply_generic(
                        (inplace_cb_reply_func_type*)cb->cb, type));
                (void)(*(inplace_cb_reply_func_type*)cb->cb)(qinfo, qstate, rep,
-                       rcode, edns, &opt_list_out, repinfo, region, cb->id, cb->cb_arg);
+                       rcode, edns, &opt_list_out, repinfo, region, start_time, cb->id, cb->cb_arg);
        }
        edns->opt_list = opt_list_out;
        return 1;
@@ -1056,37 +1057,41 @@ static int inplace_cb_reply_call_generic(
 
 int inplace_cb_reply_call(struct module_env* env, struct query_info* qinfo,
        struct module_qstate* qstate, struct reply_info* rep, int rcode,
-       struct edns_data* edns, struct comm_reply* repinfo, struct regional* region)
+       struct edns_data* edns, struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time)
 {
        return inplace_cb_reply_call_generic(
                env->inplace_cb_lists[inplace_cb_reply], inplace_cb_reply, qinfo,
-               qstate, rep, rcode, edns, repinfo, region);
+               qstate, rep, rcode, edns, repinfo, region, start_time);
 }
 
 int inplace_cb_reply_cache_call(struct module_env* env,
        struct query_info* qinfo, struct module_qstate* qstate,
        struct reply_info* rep, int rcode, struct edns_data* edns,
-       struct comm_reply* repinfo, struct regional* region)
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time)
 {
        return inplace_cb_reply_call_generic(
                env->inplace_cb_lists[inplace_cb_reply_cache], inplace_cb_reply_cache,
-               qinfo, qstate, rep, rcode, edns, repinfo, region);
+               qinfo, qstate, rep, rcode, edns, repinfo, region, start_time);
 }
 
 int inplace_cb_reply_local_call(struct module_env* env,
        struct query_info* qinfo, struct module_qstate* qstate,
        struct reply_info* rep, int rcode, struct edns_data* edns,
-       struct comm_reply* repinfo, struct regional* region)
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time)
 {
        return inplace_cb_reply_call_generic(
                env->inplace_cb_lists[inplace_cb_reply_local], inplace_cb_reply_local,
-               qinfo, qstate, rep, rcode, edns, repinfo, region);
+               qinfo, qstate, rep, rcode, edns, repinfo, region, start_time);
 }
 
 int inplace_cb_reply_servfail_call(struct module_env* env,
        struct query_info* qinfo, struct module_qstate* qstate,
        struct reply_info* rep, int rcode, struct edns_data* edns,
-       struct comm_reply* repinfo, struct regional* region)
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time)
 {
        /* We are going to servfail. Remove any potential edns options. */
        if(qstate)
@@ -1094,7 +1099,7 @@ int inplace_cb_reply_servfail_call(struct module_env* env,
        return inplace_cb_reply_call_generic(
                env->inplace_cb_lists[inplace_cb_reply_servfail],
                inplace_cb_reply_servfail, qinfo, qstate, rep, rcode, edns, repinfo,
-               region);
+               region, start_time);
 }
 
 int inplace_cb_query_call(struct module_env* env, struct query_info* qinfo,
index 385780268a3ca28e6fe0c15e0aed4a83dac81647..b7706b023a0e73cb7e753f26359c7b6d19ef0046 100644 (file)
@@ -558,7 +558,8 @@ struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
  */
 int inplace_cb_reply_call(struct module_env* env, struct query_info* qinfo,
        struct module_qstate* qstate, struct reply_info* rep, int rcode,
-       struct edns_data* edns, struct comm_reply* repinfo, struct regional* region);
+       struct edns_data* edns, struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time);
 
 /**
  * Call the registered functions in the inplace_cb_reply_cache linked list.
@@ -576,7 +577,8 @@ int inplace_cb_reply_call(struct module_env* env, struct query_info* qinfo,
 int inplace_cb_reply_cache_call(struct module_env* env,
        struct query_info* qinfo, struct module_qstate* qstate,
        struct reply_info* rep, int rcode, struct edns_data* edns,
-       struct comm_reply* repinfo, struct regional* region);
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time);
 
 /**
  * Call the registered functions in the inplace_cb_reply_local linked list.
@@ -594,7 +596,8 @@ int inplace_cb_reply_cache_call(struct module_env* env,
 int inplace_cb_reply_local_call(struct module_env* env,
        struct query_info* qinfo, struct module_qstate* qstate,
        struct reply_info* rep, int rcode, struct edns_data* edns,
-       struct comm_reply* repinfo, struct regional* region);
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time);
 
 /**
  * Call the registered functions in the inplace_cb_reply linked list.
@@ -613,7 +616,8 @@ int inplace_cb_reply_local_call(struct module_env* env,
 int inplace_cb_reply_servfail_call(struct module_env* env,
        struct query_info* qinfo, struct module_qstate* qstate,
        struct reply_info* rep, int rcode, struct edns_data* edns,
-       struct comm_reply* repinfo, struct regional* region);
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time);
 
 /**
  * Call the registered functions in the inplace_cb_query linked list.
index 7b833f8ade19fbaf6f8270d0800c456317fccc2c..d29b6f31845412b9dbb92adcd60d112b9b35901c 100644 (file)
@@ -257,8 +257,8 @@ struct inplace_cb {
 typedef int inplace_cb_reply_func_type(struct query_info* qinfo,
        struct module_qstate* qstate, struct reply_info* rep, int rcode,
        struct edns_data* edns, struct edns_option** opt_list_out,
-       struct comm_reply* repinfo, struct regional* region, int id,
-       void* callback);
+       struct comm_reply* repinfo, struct regional* region,
+    struct timeval start_time, int id, void* callback);
 
 /**
  * Inplace callback function called before sending the query to a nameserver.