mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- #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
This commit is contained in:
parent
4daf8f5bdb
commit
0171d06aa2
15 changed files with 297 additions and 145 deletions
|
|
@ -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)
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue