From 0171d06aa242f1e79af59a6cc124bc3f067aded6 Mon Sep 17 00:00:00 2001 From: George Thessalonikefs Date: Wed, 22 Aug 2018 10:51:13 +0000 Subject: [PATCH] - #4140: Expose repinfo (comm_reply) to the inplace_callbacks. This gives access to reply information for the client's communication point when the callback is called before the mesh state (modules). Changes to C and Python's inplace_callback signatures were also necessary. git-svn-id: file:///svn/unbound/trunk@4870 be551aaa-1e26-0410-a405-d3ace91eadb9 --- daemon/worker.c | 50 ++++++------ doc/Changelog | 7 ++ libunbound/libworker.c | 6 +- pythonmod/doc/examples/example6.rst | 61 ++++++++++++-- pythonmod/examples/inplace_callbacks.py | 103 ++++++++++++++++++++---- pythonmod/examples/resip.py | 20 ++--- pythonmod/interface.i | 17 ++-- pythonmod/pythonmod.h | 3 +- services/authzone.c | 20 ++--- services/authzone.h | 5 +- services/localzone.c | 67 +++++++-------- services/mesh.c | 20 ++--- util/data/msgreply.c | 21 ++--- util/data/msgreply.h | 12 ++- util/module.h | 30 ++++--- 15 files changed, 297 insertions(+), 145 deletions(-) diff --git a/daemon/worker.c b/daemon/worker.c index 84193bdab..5ce5ef3a9 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -511,7 +511,7 @@ 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, worker->scratchpad)) + msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) return 0; error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, &msg->qinfo, id, flags, edns); @@ -542,7 +542,7 @@ 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, worker->scratchpad)) + (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) return 0; msg->rep->flags |= BIT_QR|BIT_RA; if(!apply_edns_options(edns, &edns_bak, worker->env.cfg, @@ -551,7 +551,7 @@ 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, worker->scratchpad)) + LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) edns->opt_list = NULL; error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, &msg->qinfo, id, flags, edns); @@ -673,7 +673,7 @@ 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, worker->scratchpad)) + LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) goto bail_out; error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, id, flags, edns); @@ -707,7 +707,7 @@ 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, worker->scratchpad)) + (int)(flags&LDNS_RCODE_MASK), edns, repinfo, worker->scratchpad)) goto bail_out; *alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */ if(worker->daemon->use_response_ip && !partial_rep && @@ -741,7 +741,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, repinfo->c->buffer, timenow, 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, worker->scratchpad)) + LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad)) edns->opt_list = NULL; error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, id, flags, edns); @@ -788,10 +788,11 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo, * @param num: number of strings in array. * @param edns: edns reply information. * @param worker: worker with scratch region. + * @param repinfo: reply information for a communication point. */ static void chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns, - struct worker* worker) + struct worker* worker, struct comm_reply* repinfo) { int i; unsigned int rd = LDNS_RD_WIRE(sldns_buffer_begin(pkt)); @@ -824,7 +825,7 @@ 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, worker->scratchpad)) + LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad)) edns->opt_list = NULL; if(sldns_buffer_capacity(pkt) >= sldns_buffer_limit(pkt)+calc_edns_field_size(edns)) @@ -834,9 +835,9 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns, /** Reply with one string */ static void chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns, - struct worker* worker) + struct worker* worker, struct comm_reply* repinfo) { - chaos_replystr(pkt, (char**)&str, 1, edns, worker); + chaos_replystr(pkt, (char**)&str, 1, edns, worker, repinfo); } /** @@ -844,9 +845,11 @@ chaos_replyonestr(sldns_buffer* pkt, const char* str, struct edns_data* edns, * @param pkt: buffer * @param edns: edns reply information. * @param w: worker with scratch region. + * @param repinfo: reply information for a communication point. */ static void -chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w) +chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w, + struct comm_reply* repinfo) { #define TA_RESPONSE_MAX_TXT 16 /* max number of TXT records */ #define TA_RESPONSE_MAX_TAGS 32 /* max number of tags printed per zone */ @@ -857,7 +860,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w) if(!w->env.need_to_validate) { /* no validator module, reply no trustanchors */ - chaos_replystr(pkt, NULL, 0, edns, w); + chaos_replystr(pkt, NULL, 0, edns, w, repinfo); return; } @@ -891,7 +894,7 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w) } lock_basic_unlock(&w->env.anchors->lock); - chaos_replystr(pkt, str_array, num, edns, w); + chaos_replystr(pkt, str_array, num, edns, w, repinfo); regional_free_all(w->scratchpad); } @@ -900,12 +903,13 @@ chaos_trustanchor(sldns_buffer* pkt, struct edns_data* edns, struct worker* w) * @param w: worker * @param qinfo: query info. Pointer into packet buffer. * @param edns: edns info from query. + * @param repinfo: reply information for a communication point. * @param pkt: packet buffer. * @return: true if a reply is to be sent. */ static int -answer_chaos(struct worker* w, struct query_info* qinfo, - struct edns_data* edns, sldns_buffer* pkt) +answer_chaos(struct worker* w, struct query_info* qinfo, + struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* pkt) { struct config_file* cfg = w->env.cfg; if(qinfo->qtype != LDNS_RR_TYPE_ANY && qinfo->qtype != LDNS_RR_TYPE_TXT) @@ -921,13 +925,13 @@ answer_chaos(struct worker* w, struct query_info* qinfo, char buf[MAXHOSTNAMELEN+1]; if (gethostname(buf, MAXHOSTNAMELEN) == 0) { buf[MAXHOSTNAMELEN] = 0; - chaos_replyonestr(pkt, buf, edns, w); + chaos_replyonestr(pkt, buf, edns, w, repinfo); } else { log_err("gethostname: %s", strerror(errno)); - chaos_replyonestr(pkt, "no hostname", edns, w); + chaos_replyonestr(pkt, "no hostname", edns, w, repinfo); } } - else chaos_replyonestr(pkt, cfg->identity, edns, w); + else chaos_replyonestr(pkt, cfg->identity, edns, w, repinfo); return 1; } if(query_dname_compare(qinfo->qname, @@ -938,8 +942,8 @@ answer_chaos(struct worker* w, struct query_info* qinfo, if(cfg->hide_version) return 0; if(cfg->version==NULL || cfg->version[0]==0) - chaos_replyonestr(pkt, PACKAGE_STRING, edns, w); - else chaos_replyonestr(pkt, cfg->version, edns, w); + chaos_replyonestr(pkt, PACKAGE_STRING, edns, w, repinfo); + else chaos_replyonestr(pkt, cfg->version, edns, w, repinfo); return 1; } if(query_dname_compare(qinfo->qname, @@ -947,7 +951,7 @@ answer_chaos(struct worker* w, struct query_info* qinfo, { if(cfg->hide_trustanchor) return 0; - chaos_trustanchor(pkt, edns, w); + chaos_trustanchor(pkt, edns, w, repinfo); return 1; } @@ -1330,7 +1334,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, if(c->type != comm_udp) edns.udp_size = 65535; /* max size for TCP replies */ if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo, - &edns, c->buffer)) { + &edns, repinfo, c->buffer)) { server_stats_insrcode(&worker->stats, c->buffer); regional_free_all(worker->scratchpad); goto send_reply; @@ -1357,7 +1361,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, } if(worker->env.auth_zones && auth_zones_answer(worker->env.auth_zones, &worker->env, - &qinfo, &edns, c->buffer, worker->scratchpad)) { + &qinfo, &edns, repinfo, c->buffer, worker->scratchpad)) { regional_free_all(worker->scratchpad); if(sldns_buffer_limit(c->buffer) == 0) { comm_point_drop_reply(repinfo); diff --git a/doc/Changelog b/doc/Changelog index a98ce05b5..8d6ca34b4 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,10 @@ +22 August 2018: George + - #4140: Expose repinfo (comm_reply) to the inplace_callbacks. This + gives access to reply information for the client's communication + point when the callback is called before the mesh state (modules). + Changes to C and Python's inplace_callback signatures were also + necessary. + 21 August 2018: Wouter - log-local-actions: yes option for unbound.conf that logs all the local zone actions, a patch from Saksham Manchanda (Secure64). diff --git a/libunbound/libworker.c b/libunbound/libworker.c index d984b3f39..05006a0ec 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -610,7 +610,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q) return UB_NOERROR; } if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones, - w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) { + w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); libworker_fillup_fg(q, LDNS_RCODE_NOERROR, w->back->udp_buff, sec_status_insecure, NULL, 0); @@ -689,7 +689,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q, return UB_NOERROR; } if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones, - w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) { + w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); free(qinfo.qname); libworker_event_done_cb(q, LDNS_RCODE_NOERROR, @@ -827,7 +827,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len) return; } if(w->ctx->env->auth_zones && auth_zones_answer(w->ctx->env->auth_zones, - w->env, &qinfo, &edns, w->back->udp_buff, w->env->scratch)) { + w->env, &qinfo, &edns, NULL, w->back->udp_buff, w->env->scratch)) { regional_free_all(w->env->scratch); q->msg_security = sec_status_insecure; add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0); diff --git a/pythonmod/doc/examples/example6.rst b/pythonmod/doc/examples/example6.rst index eb3254022..d294fb8be 100644 --- a/pythonmod/doc/examples/example6.rst +++ b/pythonmod/doc/examples/example6.rst @@ -40,9 +40,12 @@ The callback function's prototype is the following: .. code-block:: python - def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region): - """Function that will be registered as an inplace callback function. + def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering with a resolved query. + :param qinfo: query_info struct; :param qstate: module qstate. It contains the available opt_lists; It SHOULD NOT be altered; @@ -54,7 +57,13 @@ The callback function's prototype is the following: reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh states. + :return: True on success, False on failure. + """ .. note:: The function's name is irrelevant. @@ -76,9 +85,12 @@ The callback function's prototype is the following: .. code-block:: python - def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region): - """Function that will be registered as an inplace callback function. + def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering from the cache. + :param qinfo: query_info struct; :param qstate: module qstate. None; :param rep: reply_info struct; @@ -90,7 +102,17 @@ The callback function's prototype is the following: reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh + states(modules). + :return: True on success, False on failure. + + For demonstration purposes we want to see if EDNS option 65002 is present + and reply with a new value. + """ .. note:: The function's name is irrelevant. @@ -112,9 +134,12 @@ The callback function's prototype is the following: .. code-block:: python - def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region): - """Function that will be registered as an inplace callback function. + def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering from local data. + :param qinfo: query_info struct; :param qstate: module qstate. None; :param rep: reply_info struct; @@ -126,7 +151,14 @@ The callback function's prototype is the following: reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh + states(modules). + :return: True on success, False on failure. + """ .. note:: The function's name is irrelevant. @@ -148,9 +180,12 @@ The callback function's prototype is the following: .. code-block:: python - def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, region): - """Function that will be registered as an inplace callback function. + def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering with SERVFAIL. + :param qinfo: query_info struct; :param qstate: module qstate. If not None the relevant opt_lists are available here; @@ -163,7 +198,17 @@ The callback function's prototype is the following: reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh + states(modules). + :return: True on success, False on failure. + + For demonstration purposes we want to reply with an empty EDNS code '65003' + and log the IP address(es) of the client(s). + """ .. note:: The function's name is irrelevant. diff --git a/pythonmod/examples/inplace_callbacks.py b/pythonmod/examples/inplace_callbacks.py index 02ee56e36..e47fc8292 100644 --- a/pythonmod/examples/inplace_callbacks.py +++ b/pythonmod/examples/inplace_callbacks.py @@ -6,18 +6,18 @@ Copyright (c) 2016, NLnet Labs. This software is open source. - + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - + * Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. @@ -43,6 +43,8 @@ # This query returns SERVFAIL as the txt record of bogus.nlnetlabs.nl is # intentionally bogus. The reply will contain an empty EDNS option # with option code 65003. +# Unbound will also log the source address(es) of the client(s) that made +# the request. # (unbound needs to be validating for this example to work) # Useful functions: @@ -70,9 +72,11 @@ def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, - region): - """Function that will be registered as an inplace callback function. + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering with a resolved query. + :param qinfo: query_info struct; :param qstate: module qstate. It contains the available opt_lists; It SHOULD NOT be altered; @@ -84,16 +88,25 @@ def inplace_reply_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh + states(modules). + :return: True on success, False on failure. + """ log_info("python: called back while replying.") return True def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, - region): - """Function that will be registered as an inplace callback function. + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering from the cache. + :param qinfo: query_info struct; :param qstate: module qstate. None; :param rep: reply_info struct; @@ -105,10 +118,17 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh + states(modules). + :return: True on success, False on failure. For demonstration purposes we want to see if EDNS option 65002 is present and reply with a new value. + """ log_info("python: called back while answering from cache.") # Inspect the incoming EDNS options. @@ -134,9 +154,11 @@ def inplace_cache_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, - region): - """Function that will be registered as an inplace callback function. + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering from local data. + :param qinfo: query_info struct; :param qstate: module qstate. None; :param rep: reply_info struct; @@ -148,7 +170,14 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh + states(modules). + :return: True on success, False on failure. + """ log_info("python: called back while replying with local data or chaos" " reply.") @@ -156,9 +185,11 @@ def inplace_local_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, - region): - """Function that will be registered as an inplace callback function. + region, **kwargs): + """ + Function that will be registered as an inplace callback function. It will be called when answering with SERVFAIL. + :param qinfo: query_info struct; :param qstate: module qstate. If not None the relevant opt_lists are available here; @@ -171,23 +202,62 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out, reply. It can be populated with EDNS options; :param region: region to allocate temporary data. Needs to be used when we want to append a new option to opt_list_out. + :param **kwargs: Dictionary that may contain parameters added in a future + release. Current parameters: + ``repinfo``: Reply information for a communication point (comm_reply). + It is None when the callback happens in the mesh + states(modules). + :return: True on success, False on failure. - For demonstration purposes we want to reply with an empty EDNS code '65003'. + For demonstration purposes we want to reply with an empty EDNS code '65003' + and log the IP address(es) of the client(s). + """ log_info("python: called back while servfail.") + # Append the example ENDS option b = bytearray.fromhex("") edns_opt_list_append(opt_list_out, 65003, b, region) + + # Log the client(s) IP address(es) + comm_reply = kwargs['repinfo'] + if comm_reply: + # If it is not None this callback was called before the query reached + # the mesh states(modules). There is only one client associated with + # this query. + addr = comm_reply.addr + port = comm_reply.port + addr_family = comm_reply.family + log_info("python: Client IP: {}({}), port: {}" + "".format(addr, addr_family, port)) + else: + # If it is not None this callback was called while the query is in the + # mesh states(modules). In this case they may be multiple clients + # waiting for this query. + # The following code is the same as with the resip.py example. + rl = qstate.mesh_info.reply_list + while (rl): + if rl.query_reply: + q = rl.query_reply + log_info("python: Client IP: {}({}), port: {}" + "".format(q.addr, q.family, q.port)) + rl = rl.next + + return True def init_standard(id, env): - """New version of the init function. + """ + New version of the init function. + The function's signature is the same as the C counterpart and allows for extra functionality during init. + ..note:: This function is preferred by unbound over the old init function. ..note:: The previously accessible configuration options can now be found in env.cgf. + """ log_info("python: inited script {}".format(env.cfg.python_script)) @@ -215,11 +285,14 @@ def init_standard(id, env): def init(id, cfg): - """Previous version init function. + """ + Previous version of the init function. + ..note:: This function is still supported for backwards compatibility when the init_standard function is missing. When init_standard is present this function SHOULD be omitted to avoid confusion to the reader. + """ return True diff --git a/pythonmod/examples/resip.py b/pythonmod/examples/resip.py index 6bcac7252..4a9f24fc6 100644 --- a/pythonmod/examples/resip.py +++ b/pythonmod/examples/resip.py @@ -47,7 +47,7 @@ def deinit(id): return True def inform_super(id, qstate, superqstate, qdata): return True def operate(id, event, qstate, qdata): - print "Operate", event,"state:",qstate + print("Operate {} state: {}".format(event, qstate)) # Please note that if this module blocks, by moving to the validator # to validate or iterator to lookup or spawn a subquery to look up, @@ -61,14 +61,14 @@ def operate(id, event, qstate, qdata): msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #append RR if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY): - rl = qstate.mesh_info.reply_list - while (rl): - if rl.query_reply: - q = rl.query_reply - # The TTL of 0 is mandatory, otherwise it ends up in - # the cache, and is returned to other IP addresses. - msg.answer.append("%s 0 IN TXT \"%s %d (%s)\"" % (qstate.qinfo.qname_str, q.addr,q.port,q.family)) - rl = rl.next + rl = qstate.mesh_info.reply_list + while (rl): + if rl.query_reply: + q = rl.query_reply + # The TTL of 0 is mandatory, otherwise it ends up in + # the cache, and is returned to other IP addresses. + msg.answer.append("%s 0 IN TXT \"%s %d (%s)\"" % (qstate.qinfo.qname_str, q.addr,q.port,q.family)) + rl = rl.next #set qstate.return_msg if not msg.set_return_msg(qstate): @@ -90,7 +90,7 @@ def operate(id, event, qstate, qdata): log_info("pythonmod: iterator module done") qstate.ext_state[id] = MODULE_FINISHED return True - + log_err("pythonmod: bad event") qstate.ext_state[id] = MODULE_ERROR return True diff --git a/pythonmod/interface.i b/pythonmod/interface.i index df06d1064..96accb69c 100644 --- a/pythonmod/interface.i +++ b/pythonmod/interface.i @@ -1365,11 +1365,12 @@ 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 regional* region, int id, void* python_callback) + struct comm_reply* repinfo, struct regional* region, int id, + void* python_callback) { PyObject *func, *py_edns, *py_qstate, *py_opt_list_out, *py_qinfo; - PyObject *py_rep, *py_region; - PyObject *result; + PyObject *py_rep, *py_repinfo, *py_region; + PyObject *py_args, *py_kwargs, *result; int res = 0; PyGILState_STATE gstate = PyGILState_Ensure(); @@ -1381,15 +1382,21 @@ int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len, SWIGTYPE_p_p_edns_option, 0); py_qinfo = SWIG_NewPointerObj((void*) qinfo, SWIGTYPE_p_query_info, 0); py_rep = SWIG_NewPointerObj((void*) rep, SWIGTYPE_p_reply_info, 0); + py_repinfo = SWIG_NewPointerObj((void*) repinfo, SWIGTYPE_p_comm_reply, 0); py_region = SWIG_NewPointerObj((void*) region, SWIGTYPE_p_regional, 0); - result = PyObject_CallFunction(func, "OOOiOOO", py_qinfo, py_qstate, - py_rep, rcode, py_edns, py_opt_list_out, py_region); + 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); + result = PyObject_Call(func, py_args, py_kwargs); Py_XDECREF(py_edns); Py_XDECREF(py_qstate); Py_XDECREF(py_opt_list_out); Py_XDECREF(py_qinfo); Py_XDECREF(py_rep); + Py_XDECREF(py_repinfo); Py_XDECREF(py_region); + Py_XDECREF(py_args); + Py_XDECREF(py_kwargs); if (result) { res = PyInt_AsLong(result); } diff --git a/pythonmod/pythonmod.h b/pythonmod/pythonmod.h index 7c7c0e751..991ae51a2 100644 --- a/pythonmod/pythonmod.h +++ b/pythonmod/pythonmod.h @@ -72,5 +72,6 @@ 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 regional* region, int id, void* python_callback); + struct comm_reply* repinfo, struct regional* region, int id, + void* python_callback); #endif /* PYTHONMOD_H */ diff --git a/services/authzone.c b/services/authzone.c index e8c99077d..9a4fb5a50 100644 --- a/services/authzone.c +++ b/services/authzone.c @@ -3169,8 +3169,8 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo, /** encode auth answer */ static void auth_answer_encode(struct query_info* qinfo, struct module_env* env, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp, - struct dns_msg* msg) + struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, + struct regional* temp, struct dns_msg* msg) { uint16_t udpsize; udpsize = edns->udp_size; @@ -3180,7 +3180,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, temp) + (int)FLAGS_GET_RCODE(msg->rep->flags), edns, repinfo, temp) || !reply_info_answer_encode(qinfo, msg->rep, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), @@ -3195,8 +3195,8 @@ auth_answer_encode(struct query_info* qinfo, struct module_env* env, /** encode auth error answer */ static void auth_error_encode(struct query_info* qinfo, struct module_env* env, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp, - int rcode) + struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, + struct regional* temp, int rcode) { edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; @@ -3204,7 +3204,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, temp)) + rcode, edns, repinfo, temp)) edns->opt_list = NULL; error_encode(buf, rcode|BIT_AA, qinfo, *(uint16_t*)sldns_buffer_begin(buf), @@ -3212,8 +3212,8 @@ auth_error_encode(struct query_info* qinfo, struct module_env* env, } int auth_zones_answer(struct auth_zones* az, struct module_env* env, - struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf, - struct regional* temp) + struct query_info* qinfo, struct edns_data* edns, + struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp) { struct dns_msg* msg = NULL; struct auth_zone* z; @@ -3261,9 +3261,9 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env, /* encode answer */ if(!r) - auth_error_encode(qinfo, env, edns, buf, temp, + auth_error_encode(qinfo, env, edns, repinfo, buf, temp, LDNS_RCODE_SERVFAIL); - else auth_answer_encode(qinfo, env, edns, buf, temp, msg); + else auth_answer_encode(qinfo, env, edns, repinfo, buf, temp, msg); return 1; } diff --git a/services/authzone.h b/services/authzone.h index 39a16966c..8c636eaa4 100644 --- a/services/authzone.h +++ b/services/authzone.h @@ -512,12 +512,13 @@ int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo, * @param qinfo: query info (parsed). * @param edns: edns info (parsed). * @param buf: buffer with query ID and flags, also for reply. + * @param repinfo: reply information for a communication point. * @param temp: temporary storage region. * @return false if not answered */ int auth_zones_answer(struct auth_zones* az, struct module_env* env, - struct query_info* qinfo, struct edns_data* edns, struct sldns_buffer* buf, - struct regional* temp); + struct query_info* qinfo, struct edns_data* edns, + struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp); /** * Find the auth zone that is above the given qname. diff --git a/services/localzone.c b/services/localzone.c index b9acc642a..e4c574f07 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -1146,8 +1146,9 @@ void local_zones_print(struct local_zones* zones) /** encode answer consisting of 1 rrset */ static int local_encode(struct query_info* qinfo, struct module_env* env, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp, - struct ub_packed_rrset_key* rrset, int ansec, int rcode) + struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, + struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, + int rcode) { struct reply_info rep; uint16_t udpsize; @@ -1165,23 +1166,22 @@ local_encode(struct query_info* qinfo, struct module_env* env, edns->udp_size = EDNS_ADVERTISED_SIZE; edns->ext_rcode = 0; edns->bits &= EDNS_DO; - if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, temp) - || !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)) + if(!inplace_cb_reply_local_call(env, qinfo, NULL, &rep, rcode, edns, + repinfo, temp) || !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, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), edns); + } return 1; } /** encode local error answer */ static void local_error_encode(struct query_info* qinfo, struct module_env* env, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp, - int rcode, int r) + struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf, + struct regional* temp, int rcode, int r) { edns->edns_version = EDNS_ADVERTISED_VERSION; edns->udp_size = EDNS_ADVERTISED_SIZE; @@ -1189,7 +1189,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, temp)) + rcode, edns, repinfo, temp)) edns->opt_list = NULL; error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf), sldns_buffer_read_u16_at(buf, 2), edns); @@ -1310,7 +1310,8 @@ find_tag_datas(struct query_info* qinfo, struct config_strlist* list, /** answer local data match */ static int local_data_answer(struct local_zone* z, struct module_env* env, - struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, + struct query_info* qinfo, struct edns_data* edns, + struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp, int labs, struct local_data** ldp, enum localzone_type lz_type, int tag, struct config_strlist** tag_datas, size_t tag_datas_size, char** tagname, int num_tags) @@ -1339,7 +1340,7 @@ local_data_answer(struct local_zone* z, struct module_env* env, * chain. */ if(qinfo->local_alias) return 1; - return local_encode(qinfo, env, edns, buf, temp, + return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1, LDNS_RCODE_NOERROR); } } @@ -1374,29 +1375,31 @@ local_data_answer(struct local_zone* z, struct module_env* env, struct ub_packed_rrset_key r = *lr->rrset; r.rk.dname = qinfo->qname; r.rk.dname_len = qinfo->qname_len; - return local_encode(qinfo, env, edns, buf, temp, &r, 1, + return local_encode(qinfo, env, edns, repinfo, buf, temp, &r, 1, LDNS_RCODE_NOERROR); } - return local_encode(qinfo, env, edns, buf, temp, lr->rrset, 1, + return local_encode(qinfo, env, edns, repinfo, buf, temp, lr->rrset, 1, LDNS_RCODE_NOERROR); } /** - * answer in case where no exact match is found - * @param z: zone for query - * @param env: module environment - * @param qinfo: query - * @param edns: edns from query + * Answer in case where no exact match is found. + * @param z: zone for query. + * @param env: module environment. + * @param qinfo: query. + * @param edns: edns from query. + * @param repinfo: source address for checks. may be NULL. * @param buf: buffer for answer. - * @param temp: temp region for encoding + * @param temp: temp region for encoding. * @param ld: local data, if NULL, no such name exists in localdata. - * @param lz_type: type of the local zone + * @param lz_type: type of the local zone. * @return 1 if a reply is to be sent, 0 if not. */ static int lz_zone_answer(struct local_zone* z, struct module_env* env, - struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf, - struct regional* temp, struct local_data* ld, enum localzone_type lz_type) + struct query_info* qinfo, struct edns_data* edns, + struct comm_reply* repinfo, sldns_buffer* buf, struct regional* temp, + struct local_data* ld, enum localzone_type lz_type) { if(lz_type == local_zone_deny || lz_type == local_zone_inform_deny) { /** no reply at all, signal caller by clearing buffer. */ @@ -1405,7 +1408,7 @@ lz_zone_answer(struct local_zone* z, struct module_env* env, return 1; } else if(lz_type == local_zone_refuse || lz_type == local_zone_always_refuse) { - local_error_encode(qinfo, env, edns, buf, temp, + local_error_encode(qinfo, env, edns, repinfo, buf, temp, LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA)); return 1; } else if(lz_type == local_zone_static || @@ -1421,9 +1424,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env, int rcode = (ld || lz_type == local_zone_redirect)? LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; if(z->soa) - return local_encode(qinfo, env, edns, buf, temp, + return local_encode(qinfo, env, edns, repinfo, buf, temp, z->soa, 0, rcode); - local_error_encode(qinfo, env, edns, buf, temp, rcode, + local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, (rcode|BIT_AA)); return 1; } else if(lz_type == local_zone_typetransparent @@ -1438,9 +1441,9 @@ lz_zone_answer(struct local_zone* z, struct module_env* env, if(ld && ld->rrsets) { int rcode = LDNS_RCODE_NOERROR; if(z->soa) - return local_encode(qinfo, env, edns, buf, temp, + return local_encode(qinfo, env, edns, repinfo, buf, temp, z->soa, 0, rcode); - local_error_encode(qinfo, env, edns, buf, temp, rcode, + local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode, (rcode|BIT_AA)); return 1; } @@ -1584,14 +1587,14 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, if(lzt != local_zone_always_refuse && lzt != local_zone_always_transparent && lzt != local_zone_always_nxdomain - && local_data_answer(z, env, qinfo, edns, buf, temp, labs, &ld, lzt, - tag, tag_datas, tag_datas_size, tagname, num_tags)) { + && local_data_answer(z, env, qinfo, edns, repinfo, buf, temp, labs, + &ld, lzt, tag, tag_datas, tag_datas_size, tagname, num_tags)) { lock_rw_unlock(&z->lock); /* We should tell the caller that encode is deferred if we found * a local alias. */ return !qinfo->local_alias; } - r = lz_zone_answer(z, env, qinfo, edns, buf, temp, ld, lzt); + r = lz_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ld, lzt); lock_rw_unlock(&z->lock); return r && !qinfo->local_alias; /* see above */ } diff --git a/services/mesh.c b/services/mesh.c index 6688d9c2c..c6bb9ef2b 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -386,7 +386,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, mesh->env->scratch)) + LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch)) edns->opt_list = NULL; error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, qid, qflags, edns); @@ -402,7 +402,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, mesh->env->scratch)) + NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch)) edns->opt_list = NULL; error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, qid, qflags, edns); @@ -430,7 +430,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) { log_err("mesh_new_client: out of memory; SERVFAIL"); if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s, - NULL, LDNS_RCODE_SERVFAIL, edns, mesh->env->scratch)) + NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch)) edns->opt_list = NULL; error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL, qinfo, qid, qflags, edns); @@ -987,11 +987,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, m->s.region)) + rep, rcode, &r->edns, NULL, m->s.region)) r->edns.opt_list = NULL; } else { if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode, - &r->edns, m->s.region)) + &r->edns, NULL, m->s.region)) r->edns.opt_list = NULL; } fptr_ok(fptr_whitelist_mesh_cb(r->cb)); @@ -1006,7 +1006,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, m->s.region) || + LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) || !reply_info_answer_encode(&m->s.qinfo, rep, r->qid, r->qflags, r->buf, 0, 1, m->s.env->scratch, udp_size, &r->edns, @@ -1084,11 +1084,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, m->s.region)) + rep, rcode, &r->edns, NULL, m->s.region)) r->edns.opt_list = NULL; } else { if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode, - &r->edns, m->s.region)) + &r->edns, NULL, m->s.region)) r->edns.opt_list = NULL; } error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo, @@ -1103,7 +1103,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, m->s.region) || + LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) || !apply_edns_options(&r->edns, &edns_bak, m->s.env->cfg, r->query_reply.c, m->s.region) || @@ -1113,7 +1113,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep, (int)(r->edns.bits & EDNS_DO), secure)) { if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s, - rep, LDNS_RCODE_SERVFAIL, &r->edns, m->s.region)) + rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region)) r->edns.opt_list = NULL; error_encode(r->query_reply.c->buffer, LDNS_RCODE_SERVFAIL, &m->s.qinfo, r->qid, diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 1e16d912c..248ecb8eb 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -1014,7 +1014,7 @@ 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 regional* region) + struct comm_reply* repinfo, struct regional* region) { struct inplace_cb* cb; struct edns_option* opt_list_out = NULL; @@ -1027,7 +1027,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, region, cb->id, cb->cb_arg); + rcode, edns, &opt_list_out, repinfo, region, cb->id, cb->cb_arg); } edns->opt_list = opt_list_out; return 1; @@ -1035,44 +1035,45 @@ 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 regional* region) + struct edns_data* edns, struct comm_reply* repinfo, struct regional* region) { return inplace_cb_reply_call_generic( env->inplace_cb_lists[inplace_cb_reply], inplace_cb_reply, qinfo, - qstate, rep, rcode, edns, region); + qstate, rep, rcode, edns, repinfo, region); } 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 regional* region) + struct comm_reply* repinfo, struct regional* region) { return inplace_cb_reply_call_generic( env->inplace_cb_lists[inplace_cb_reply_cache], inplace_cb_reply_cache, - qinfo, qstate, rep, rcode, edns, region); + qinfo, qstate, rep, rcode, edns, repinfo, region); } 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 regional* region) + struct comm_reply* repinfo, struct regional* region) { return inplace_cb_reply_call_generic( env->inplace_cb_lists[inplace_cb_reply_local], inplace_cb_reply_local, - qinfo, qstate, rep, rcode, edns, region); + qinfo, qstate, rep, rcode, edns, repinfo, region); } 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 regional* region) + struct comm_reply* repinfo, struct regional* region) { /* We are going to servfail. Remove any potential edns options. */ if(qstate) qstate->edns_opts_front_out = NULL; return inplace_cb_reply_call_generic( env->inplace_cb_lists[inplace_cb_reply_servfail], - inplace_cb_reply_servfail, qinfo, qstate, rep, rcode, edns, region); + inplace_cb_reply_servfail, qinfo, qstate, rep, rcode, edns, repinfo, + region); } int inplace_cb_query_call(struct module_env* env, struct query_info* qinfo, diff --git a/util/data/msgreply.h b/util/data/msgreply.h index 60e6438a8..73103b7c0 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -545,12 +545,13 @@ struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code); * @param rep: Reply info. Could be NULL. * @param rcode: return code. * @param edns: edns data of the reply. + * @param repinfo: comm_reply. NULL. * @param region: region to store data. * @return false on failure (a callback function returned an error). */ 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 regional* region); + struct edns_data* edns, struct comm_reply* repinfo, struct regional* region); /** * Call the registered functions in the inplace_cb_reply_cache linked list. @@ -561,13 +562,14 @@ int inplace_cb_reply_call(struct module_env* env, struct query_info* qinfo, * @param rep: Reply info. * @param rcode: return code. * @param edns: edns data of the reply. Edns input can be found here. + * @param repinfo: comm_reply. Reply information for a communication point. * @param region: region to store data. * @return false on failure (a callback function returned an error). */ 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 regional* region); + struct comm_reply* repinfo, struct regional* region); /** * Call the registered functions in the inplace_cb_reply_local linked list. @@ -578,13 +580,14 @@ int inplace_cb_reply_cache_call(struct module_env* env, * @param rep: Reply info. * @param rcode: return code. * @param edns: edns data of the reply. Edns input can be found here. + * @param repinfo: comm_reply. Reply information for a communication point. * @param region: region to store data. * @return false on failure (a callback function returned an error). */ 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 regional* region); + struct comm_reply* repinfo, struct regional* region); /** * Call the registered functions in the inplace_cb_reply linked list. @@ -596,13 +599,14 @@ int inplace_cb_reply_local_call(struct module_env* env, * @param rcode: return code. LDNS_RCODE_SERVFAIL. * @param edns: edns data of the reply. Edns input can be found here if qstate * is NULL. + * @param repinfo: comm_reply. Reply information for a communication point. * @param region: region to store data. * @return false on failure (a callback function returned an error). */ 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 regional* region); + struct comm_reply* repinfo, struct regional* region); /** * Call the registered functions in the inplace_cb_query linked list. diff --git a/util/module.h b/util/module.h index 31c531384..1b9aed216 100644 --- a/util/module.h +++ b/util/module.h @@ -236,8 +236,8 @@ struct inplace_cb { /** * Inplace callback function called before replying. - * Called as func(edns, qstate, opt_list_out, qinfo, reply_info, rcode, - * region, python_callback) + * Called as func(qinfo, qstate, rep, rcode, edns, opt_list_out, repinfo, + * region, id, python_callback) * Where: * qinfo: the query info. * qstate: the module state. NULL when calling before the query reaches the @@ -247,18 +247,23 @@ struct inplace_cb { * edns: the edns_data of the reply. When qstate is NULL, it is also used as * the edns input. * opt_list_out: the edns options list for the reply. + * repinfo: reply information for a communication point. NULL when calling + * during the mesh states; the same could be found from + * qstate->mesh_info->reply_list. * region: region to store data. + * id: module id. * python_callback: only used for registering a python callback function. */ 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 regional* region, int id, void* callback); + struct edns_data* edns, struct edns_option** opt_list_out, + struct comm_reply* repinfo, struct regional* region, int id, + void* callback); /** * Inplace callback function called before sending the query to a nameserver. * Called as func(qinfo, flags, qstate, addr, addrlen, zone, zonelen, region, - * python_callback) + * id, python_callback) * Where: * qinfo: query info. * flags: flags of the query. @@ -270,6 +275,7 @@ typedef int inplace_cb_reply_func_type(struct query_info* qinfo, * authoritative. * zonelen: length of zone. * region: region to store data. + * id: module id. * python_callback: only used for registering a python callback function. */ typedef int inplace_cb_query_func_type(struct query_info* qinfo, uint16_t flags, @@ -279,10 +285,10 @@ typedef int inplace_cb_query_func_type(struct query_info* qinfo, uint16_t flags, /** * Inplace callback function called after parsing edns on query reply. - * Called as func(qstate, cb_args) + * Called as func(qstate, id, cb_args) * Where: - * qstate: the query state - * id: module id + * qstate: the query state. + * id: module id. * cb_args: argument passed when registering callback. */ typedef int inplace_cb_edns_back_parsed_func_type(struct module_qstate* qstate, @@ -290,11 +296,11 @@ typedef int inplace_cb_edns_back_parsed_func_type(struct module_qstate* qstate, /** * Inplace callback function called after parsing query response. - * Called as func(qstate, id, cb_args) + * Called as func(qstate, response, id, cb_args) * Where: - * qstate: the query state - * response: query response - * id: module id + * qstate: the query state. + * response: query response. + * id: module id. * cb_args: argument passed when registering callback. */ typedef int inplace_cb_query_response_func_type(struct module_qstate* qstate, -- 2.47.3