mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- Fix #628: A rpz-passthru action is not ending RPZ zone processing.
This commit is contained in:
parent
91a5cc9a08
commit
2b90181d3a
@ -553,7 +553,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||
return 1;
|
||||
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
|
||||
alias_rrset, 0, worker->scratchpad, az))
|
||||
alias_rrset, 0, worker->scratchpad, az, NULL))
|
||||
return 0;
|
||||
|
||||
/* xxx_deny actions mean dropping the reply, unless the original reply
|
||||
@ -742,7 +742,8 @@ bail_out:
|
||||
/** Reply to client and perform prefetch to keep cache up to date. */
|
||||
static void
|
||||
reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
|
||||
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply)
|
||||
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply,
|
||||
int rpz_passthru)
|
||||
{
|
||||
/* first send answer to client to keep its latency
|
||||
* as small as a cachereply */
|
||||
@ -761,7 +762,7 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
|
||||
* the cache and go to the network for the data). */
|
||||
/* this (potentially) runs the mesh for the new query */
|
||||
mesh_new_prefetch(worker->env.mesh, qinfo, flags, leeway +
|
||||
PREFETCH_EXPIRY_ADD);
|
||||
PREFETCH_EXPIRY_ADD, rpz_passthru);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1073,6 +1074,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
int need_drop = 0;
|
||||
int is_expired_answer = 0;
|
||||
int is_secure_answer = 0;
|
||||
int rpz_passthru = 0;
|
||||
/* We might have to chase a CNAME chain internally, in which case
|
||||
* we'll have up to two replies and combine them to build a complete
|
||||
* answer. These variables control this case. */
|
||||
@ -1338,7 +1340,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if(worker->env.auth_zones &&
|
||||
rpz_callback_from_worker_request(worker->env.auth_zones,
|
||||
&worker->env, &qinfo, &edns, c->buffer, worker->scratchpad,
|
||||
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
|
||||
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats,
|
||||
&rpz_passthru)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
if(sldns_buffer_limit(c->buffer) == 0) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
@ -1464,7 +1467,8 @@ lookup_cache:
|
||||
reply_and_prefetch(worker, lookup_qinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
repinfo, leeway,
|
||||
(partial_rep || need_drop));
|
||||
(partial_rep || need_drop),
|
||||
rpz_passthru);
|
||||
if(!partial_rep) {
|
||||
rc = 0;
|
||||
regional_free_all(worker->scratchpad);
|
||||
@ -1527,7 +1531,8 @@ lookup_cache:
|
||||
/* grab a work request structure for this new request */
|
||||
mesh_new_client(worker->env.mesh, &qinfo, cinfo,
|
||||
sldns_buffer_read_u16_at(c->buffer, 2),
|
||||
&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer));
|
||||
&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
rpz_passthru);
|
||||
regional_free_all(worker->scratchpad);
|
||||
worker_mem_report(worker, NULL);
|
||||
return 0;
|
||||
|
@ -1,3 +1,6 @@
|
||||
15 February 2022: Wouter
|
||||
- Fix #628: A rpz-passthru action is not ending RPZ zone processing.
|
||||
|
||||
11 February 2022: Wouter
|
||||
- Fix #624: Unable to stop Unbound in Windows console (does not
|
||||
respond to CTRL+C command).
|
||||
|
@ -650,7 +650,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
}
|
||||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_fg_done_cb, q)) {
|
||||
w->back->udp_buff, qid, libworker_fg_done_cb, q, 0)) {
|
||||
free(qinfo.qname);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
@ -730,7 +730,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
if(async_id)
|
||||
*async_id = q->querynum;
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_event_done_cb, q)) {
|
||||
w->back->udp_buff, qid, libworker_event_done_cb, q, 0)) {
|
||||
free(qinfo.qname);
|
||||
return UB_NOMEM;
|
||||
}
|
||||
@ -867,7 +867,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
q->w = w;
|
||||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_bg_done_cb, q)) {
|
||||
w->back->udp_buff, qid, libworker_bg_done_cb, q, 0)) {
|
||||
add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0);
|
||||
}
|
||||
free(qinfo.qname);
|
||||
|
@ -833,8 +833,11 @@ static int
|
||||
respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
|
||||
enum respip_action* action,
|
||||
struct ub_packed_rrset_key** data, int* rpz_log, char** log_name,
|
||||
int* rpz_cname_override, struct regional* region, int* is_rpz)
|
||||
int* rpz_cname_override, struct regional* region, int* is_rpz,
|
||||
int* rpz_passthru)
|
||||
{
|
||||
if(rpz_passthru && *rpz_passthru)
|
||||
return 0;
|
||||
if(r->action_override == RPZ_DISABLED_ACTION) {
|
||||
*is_rpz = 0;
|
||||
return 1;
|
||||
@ -848,6 +851,9 @@ respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
|
||||
*data = r->cname_override;
|
||||
*rpz_cname_override = 1;
|
||||
}
|
||||
if(*action == respip_always_transparent /* RPZ_PASSTHRU_ACTION */
|
||||
&& rpz_passthru)
|
||||
*rpz_passthru = 1;
|
||||
*rpz_log = r->log;
|
||||
if(r->log_name)
|
||||
if(!(*log_name = regional_strdup(region, r->log_name)))
|
||||
@ -861,7 +867,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
const struct respip_client_info* cinfo, const struct reply_info* rep,
|
||||
struct reply_info** new_repp, struct respip_action_info* actinfo,
|
||||
struct ub_packed_rrset_key** alias_rrset, int search_only,
|
||||
struct regional* region, struct auth_zones* az)
|
||||
struct regional* region, struct auth_zones* az, int* rpz_passthru)
|
||||
{
|
||||
const uint8_t* ctaglist;
|
||||
size_t ctaglen;
|
||||
@ -934,7 +940,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
ipset->tagname, ipset->num_tags);
|
||||
}
|
||||
lock_rw_rdlock(&az->rpz_lock);
|
||||
for(a = az->rpz_first; a && !raddr; a = a->rpz_az_next) {
|
||||
for(a = az->rpz_first; a && !raddr && !(rpz_passthru && *rpz_passthru); a = a->rpz_az_next) {
|
||||
lock_rw_rdlock(&a->lock);
|
||||
r = a->rpz;
|
||||
if(!r->taglist || taglist_intersect(r->taglist,
|
||||
@ -943,7 +949,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
r->respip_set, &rrset_id, &rr_id))) {
|
||||
if(!respip_use_rpz(raddr, r, &action, &data,
|
||||
&rpz_log, &log_name, &rpz_cname_override,
|
||||
region, &rpz_used)) {
|
||||
region, &rpz_used, rpz_passthru)) {
|
||||
log_err("out of memory");
|
||||
lock_rw_unlock(&raddr->lock);
|
||||
lock_rw_unlock(&a->lock);
|
||||
@ -1094,7 +1100,8 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
if(!respip_rewrite_reply(&qstate->qinfo,
|
||||
qstate->client_info, qstate->return_msg->rep,
|
||||
&new_rep, &actinfo, &alias_rrset, 0,
|
||||
qstate->region, qstate->env->auth_zones)) {
|
||||
qstate->region, qstate->env->auth_zones,
|
||||
&qstate->rpz_passthru)) {
|
||||
goto servfail;
|
||||
}
|
||||
if(actinfo.action != respip_none) {
|
||||
@ -1169,7 +1176,7 @@ respip_merge_cname(struct reply_info* base_rep,
|
||||
|
||||
/* see if the target reply would be subject to a response-ip action. */
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo,
|
||||
&alias_rrset, 1, region, az))
|
||||
&alias_rrset, 1, region, az, NULL))
|
||||
return 0;
|
||||
if(actinfo.action != respip_none) {
|
||||
log_info("CNAME target of redirect response-ip action would "
|
||||
|
@ -176,6 +176,8 @@ int respip_merge_cname(struct reply_info* base_rep,
|
||||
* will be set (or intact) accordingly but the modified reply won't be built.
|
||||
* @param az: auth zones containing RPZ information.
|
||||
* @param region: allocator to build *new_repp.
|
||||
* @param rpz_passthru: keeps track of query state can have passthru that
|
||||
* stops further rpz processing. Or NULL for cached answer processing.
|
||||
* @return 1 on success, 0 on error.
|
||||
*/
|
||||
int respip_rewrite_reply(const struct query_info* qinfo,
|
||||
@ -183,7 +185,8 @@ int respip_rewrite_reply(const struct query_info* qinfo,
|
||||
const struct reply_info *rep, struct reply_info** new_repp,
|
||||
struct respip_action_info* actinfo,
|
||||
struct ub_packed_rrset_key** alias_rrset,
|
||||
int search_only, struct regional* region, struct auth_zones* az);
|
||||
int search_only, struct regional* region, struct auth_zones* az,
|
||||
int* rpz_passthru);
|
||||
|
||||
/**
|
||||
* Get the response-ip function block.
|
||||
|
@ -5370,7 +5370,7 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
* called straight away */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
|
||||
&auth_xfer_transfer_lookup_callback, xfr)) {
|
||||
&auth_xfer_transfer_lookup_callback, xfr, 0)) {
|
||||
lock_basic_lock(&xfr->lock);
|
||||
log_err("out of memory lookup up master %s", master->host);
|
||||
return 0;
|
||||
@ -6561,7 +6561,7 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
* called straight away */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
|
||||
&auth_xfer_probe_lookup_callback, xfr)) {
|
||||
&auth_xfer_probe_lookup_callback, xfr, 0)) {
|
||||
lock_basic_lock(&xfr->lock);
|
||||
log_err("out of memory lookup up master %s", master->host);
|
||||
return 0;
|
||||
@ -8340,7 +8340,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
|
||||
/* the callback can be called straight away */
|
||||
lock_rw_unlock(&z->lock);
|
||||
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
|
||||
&auth_zonemd_dnskey_lookup_callback, z)) {
|
||||
&auth_zonemd_dnskey_lookup_callback, z, 0)) {
|
||||
lock_rw_wrlock(&z->lock);
|
||||
log_err("out of memory lookup of %s for zonemd",
|
||||
(fetch_ds?"DS":"DNSKEY"));
|
||||
|
@ -458,7 +458,8 @@ mesh_serve_expired_init(struct mesh_state* mstate, int timeout)
|
||||
|
||||
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, uint16_t qflags,
|
||||
struct edns_data* edns, struct comm_reply* rep, uint16_t qid)
|
||||
struct edns_data* edns, struct comm_reply* rep, uint16_t qid,
|
||||
int rpz_passthru)
|
||||
{
|
||||
struct mesh_state* s = NULL;
|
||||
int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
|
||||
@ -513,6 +514,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
}
|
||||
if(unique)
|
||||
mesh_state_make_unique(s);
|
||||
s->s.rpz_passthru = rpz_passthru;
|
||||
/* copy the edns options we got from the front */
|
||||
if(edns->opt_list_in) {
|
||||
s->s.edns_opts_front_in = edns_opt_copy_region(edns->opt_list_in,
|
||||
@ -606,7 +608,7 @@ servfail_mem:
|
||||
int
|
||||
mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
|
||||
uint16_t qid, mesh_cb_func_type cb, void* cb_arg)
|
||||
uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru)
|
||||
{
|
||||
struct mesh_state* s = NULL;
|
||||
int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
|
||||
@ -632,6 +634,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
}
|
||||
if(unique)
|
||||
mesh_state_make_unique(s);
|
||||
s->s.rpz_passthru = rpz_passthru;
|
||||
if(edns->opt_list_in) {
|
||||
s->s.edns_opts_front_in = edns_opt_copy_region(edns->opt_list_in,
|
||||
s->s.region);
|
||||
@ -686,7 +689,8 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
* 0 (false), in which case the new state is only made runnable so it
|
||||
* will not be run recursively on top of the current state. */
|
||||
static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run)
|
||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
|
||||
int rpz_passthru)
|
||||
{
|
||||
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
@ -741,6 +745,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
s->list_select = mesh_jostle_list;
|
||||
}
|
||||
}
|
||||
s->s.rpz_passthru = rpz_passthru;
|
||||
|
||||
if(!run) {
|
||||
#ifdef UNBOUND_DEBUG
|
||||
@ -757,9 +762,9 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
}
|
||||
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, time_t leeway)
|
||||
uint16_t qflags, time_t leeway, int rpz_passthru)
|
||||
{
|
||||
mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1);
|
||||
mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1, rpz_passthru);
|
||||
}
|
||||
|
||||
void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
|
||||
@ -1693,6 +1698,7 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
|
||||
if(mstate->s.curmod == 0) {
|
||||
struct query_info* qinfo = NULL;
|
||||
uint16_t qflags;
|
||||
int rpz_p = 0;
|
||||
|
||||
mesh_query_done(mstate);
|
||||
mesh_walk_supers(mesh, mstate);
|
||||
@ -1701,13 +1707,15 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
|
||||
* from an external DNS server, we'll need to schedule
|
||||
* a prefetch after removing the current state, so
|
||||
* we need to make a copy of the query info here. */
|
||||
if(mstate->s.need_refetch)
|
||||
if(mstate->s.need_refetch) {
|
||||
mesh_copy_qinfo(mstate, &qinfo, &qflags);
|
||||
rpz_p = mstate->s.rpz_passthru;
|
||||
}
|
||||
|
||||
mesh_state_delete(&mstate->s);
|
||||
if(qinfo) {
|
||||
mesh_schedule_prefetch(mesh, qinfo, qflags,
|
||||
0, 1);
|
||||
0, 1, rpz_p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1917,7 +1925,7 @@ apply_respip_action(struct module_qstate* qstate,
|
||||
return 1;
|
||||
|
||||
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, actinfo,
|
||||
alias_rrset, 0, qstate->region, az))
|
||||
alias_rrset, 0, qstate->region, az, NULL))
|
||||
return 0;
|
||||
|
||||
/* xxx_deny actions mean dropping the reply, unless the original reply
|
||||
|
@ -296,10 +296,13 @@ void mesh_delete(struct mesh_area* mesh);
|
||||
* @param edns: edns data from client query.
|
||||
* @param rep: where to reply to.
|
||||
* @param qid: query id to reply with.
|
||||
* @param rpz_passthru: if true, the rpz passthru was previously found and
|
||||
* further rpz processing is stopped.
|
||||
*/
|
||||
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, uint16_t qflags,
|
||||
struct edns_data* edns, struct comm_reply* rep, uint16_t qid);
|
||||
struct edns_data* edns, struct comm_reply* rep, uint16_t qid,
|
||||
int rpz_passthru);
|
||||
|
||||
/**
|
||||
* New query with callback. Create new query state if needed, and
|
||||
@ -314,11 +317,13 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
* @param qid: query id to reply with.
|
||||
* @param cb: callback function.
|
||||
* @param cb_arg: callback user arg.
|
||||
* @param rpz_passthru: if true, the rpz passthru was previously found and
|
||||
* further rpz processing is stopped.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, struct edns_data* edns, struct sldns_buffer* buf,
|
||||
uint16_t qid, mesh_cb_func_type cb, void* cb_arg);
|
||||
uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru);
|
||||
|
||||
/**
|
||||
* New prefetch message. Create new query state if needed.
|
||||
@ -328,9 +333,11 @@ int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
* @param qinfo: query from client.
|
||||
* @param qflags: flags from client query.
|
||||
* @param leeway: TTL leeway what to expire earlier for this update.
|
||||
* @param rpz_passthru: if true, the rpz passthru was previously found and
|
||||
* further rpz processing is stopped.
|
||||
*/
|
||||
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, time_t leeway);
|
||||
uint16_t qflags, time_t leeway, int rpz_passthru);
|
||||
|
||||
/**
|
||||
* Handle new event from the wire. A serviced query has returned.
|
||||
|
@ -1997,6 +1997,7 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r,
|
||||
break;
|
||||
case RPZ_PASSTHRU_ACTION:
|
||||
ret = NULL;
|
||||
ms->rpz_passthru = 1;
|
||||
break;
|
||||
default:
|
||||
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
|
||||
@ -2051,6 +2052,7 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r,
|
||||
break;
|
||||
case RPZ_PASSTHRU_ACTION:
|
||||
ret = NULL;
|
||||
ms->rpz_passthru = 1;
|
||||
break;
|
||||
default:
|
||||
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
|
||||
@ -2114,6 +2116,11 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
||||
struct local_zone* z = NULL;
|
||||
struct matched_delegation_point match = {0};
|
||||
|
||||
if(ms->rpz_passthru) {
|
||||
verbose(VERB_ALGO, "query is rpz_passthru, no futher processing");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
|
||||
|
||||
az = ms->env->auth_zones;
|
||||
@ -2179,6 +2186,11 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
|
||||
enum localzone_type lzt;
|
||||
struct dns_msg* ret = NULL;
|
||||
|
||||
if(ms->rpz_passthru) {
|
||||
verbose(VERB_ALGO, "query is rpz_passthru, no futher processing");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
|
||||
az = ms->env->auth_zones;
|
||||
|
||||
@ -2253,6 +2265,7 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
|
||||
break;
|
||||
case RPZ_PASSTHRU_ACTION:
|
||||
ret = NULL;
|
||||
ms->rpz_passthru = 1;
|
||||
break;
|
||||
default:
|
||||
verbose(VERB_ALGO, "rpz: qname trigger after cname: bug: unhandled or invalid action: '%s'",
|
||||
@ -2270,7 +2283,8 @@ rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
|
||||
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
|
||||
sldns_buffer* buf, struct regional* temp,
|
||||
/* output parameters */
|
||||
struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out)
|
||||
struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out,
|
||||
int* passthru)
|
||||
{
|
||||
int ret = 0;
|
||||
enum rpz_action client_action;
|
||||
@ -2278,7 +2292,9 @@ rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
|
||||
az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out);
|
||||
|
||||
client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action);
|
||||
|
||||
if(client_action == RPZ_PASSTHRU_ACTION) {
|
||||
*passthru = 1;
|
||||
}
|
||||
if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION &&
|
||||
client_action != RPZ_PASSTHRU_ACTION)) {
|
||||
if(client_action == RPZ_PASSTHRU_ACTION
|
||||
@ -2323,7 +2339,7 @@ int
|
||||
rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
|
||||
struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist,
|
||||
size_t taglen, struct ub_server_stats* stats)
|
||||
size_t taglen, struct ub_server_stats* stats, int* passthru)
|
||||
{
|
||||
struct rpz* r = NULL;
|
||||
struct auth_zone* a = NULL;
|
||||
@ -2332,7 +2348,8 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
|
||||
enum localzone_type lzt;
|
||||
|
||||
int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo,
|
||||
edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r);
|
||||
edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r,
|
||||
passthru);
|
||||
if(clientip_trigger >= 0) {
|
||||
if(a) {
|
||||
lock_rw_unlock(&a->lock);
|
||||
@ -2357,6 +2374,9 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
|
||||
} else {
|
||||
lzt = rpz_action_to_localzone_type(r->action_override);
|
||||
}
|
||||
if(r->action_override == RPZ_PASSTHRU_ACTION) {
|
||||
*passthru = 1;
|
||||
}
|
||||
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char nm[255+1], zn[255+1];
|
||||
|
@ -176,12 +176,14 @@ void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
|
||||
* @param taglist: taglist to lookup.
|
||||
* @param taglen: length of taglist.
|
||||
* @param stats: worker stats struct
|
||||
* @param passthru: returns if the query can passthru further rpz processing.
|
||||
* @return: 1 if client answer is ready, 0 to continue resolving
|
||||
*/
|
||||
int rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
|
||||
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
|
||||
struct regional* temp, struct comm_reply* repinfo,
|
||||
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats);
|
||||
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
|
||||
int* passthru);
|
||||
|
||||
/**
|
||||
* Callback to process when the iterator module is about to send queries.
|
||||
|
111
testdata/rpz_passthru.rpl
vendored
Normal file
111
testdata/rpz_passthru.rpl
vendored
Normal file
@ -0,0 +1,111 @@
|
||||
; config options
|
||||
server:
|
||||
module-config: "respip validator iterator"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: no
|
||||
access-control: 192.0.0.0/8 allow
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
rpz-log: yes
|
||||
rpz-log-name: "rpz.example.com"
|
||||
rpz-action-override: passthru
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz.example.com
|
||||
TEMPFILE_CONTENTS rpz.example.com
|
||||
$ORIGIN example.com.
|
||||
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
|
||||
1379078166 28800 7200 604800 7200 )
|
||||
3600 IN NS ns1.rpz.example.com.
|
||||
3600 IN NS ns2.rpz.example.com.
|
||||
$ORIGIN rpz.example.com.
|
||||
c.a TXT "local data 1st zone"
|
||||
d.a A 127.0.0.1
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz2.example.com."
|
||||
rpz-log: yes
|
||||
rpz-log-name: "rpz2.example.com"
|
||||
rpz-action-override: nxdomain
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz2.example.com
|
||||
TEMPFILE_CONTENTS rpz2.example.com
|
||||
$ORIGIN example.com.
|
||||
rpz2 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
|
||||
1379078166 28800 7200 604800 7200 )
|
||||
3600 IN NS ns1.rpz.example.com.
|
||||
3600 IN NS ns2.rpz.example.com.
|
||||
$ORIGIN rpz2.example.com.
|
||||
c.a TXT "local data 2nd zone"
|
||||
24.0.5.0.192.rpz-client-ip A 127.0.0.1
|
||||
24.0.5.0.192.rpz-client-ip TXT "clientip 2nd zone"
|
||||
24.0.3.2.1.rpz-ip A 127.0.0.2
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "a."
|
||||
stub-addr: 10.20.30.40
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test RPZ passthru ends processing for later triggers.
|
||||
|
||||
; a.
|
||||
RANGE_BEGIN 0 1000
|
||||
ADDRESS 10.20.30.40
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
SECTION ANSWER
|
||||
c.a. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
d.a. IN A
|
||||
SECTION ANSWER
|
||||
d.a. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 10 QUERY ADDRESS 192.0.5.1
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 11 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c.a. IN TXT
|
||||
SECTION ANSWER
|
||||
c.a. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY ADDRESS 192.0.2.1
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
d.a. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 21 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
d.a. IN A
|
||||
SECTION ANSWER
|
||||
d.a. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
37
testdata/rpz_qname.rpl
vendored
37
testdata/rpz_qname.rpl
vendored
@ -6,6 +6,8 @@ server:
|
||||
|
||||
rpz:
|
||||
name: "rpz.example.com."
|
||||
rpz-log: yes
|
||||
rpz-log-name: "rpz.example.com"
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz.example.com
|
||||
TEMPFILE_CONTENTS rpz.example.com
|
||||
@ -20,10 +22,13 @@ a CNAME *. ; duplicate CNAME here on purpose
|
||||
*.a TXT "wildcard local data"
|
||||
b.a CNAME *.
|
||||
c.a CNAME rpz-passthru.
|
||||
c.g CNAME rpz-passthru.
|
||||
TEMPFILE_END
|
||||
|
||||
rpz:
|
||||
name: "rpz2.example.com."
|
||||
rpz-log: yes
|
||||
rpz-log-name: "rpz2.example.com"
|
||||
zonefile:
|
||||
TEMPFILE_NAME rpz2.example.com
|
||||
TEMPFILE_CONTENTS rpz2.example.com
|
||||
@ -39,6 +44,7 @@ e CNAME *.a.example.
|
||||
*.e CNAME *.b.example.
|
||||
drop CNAME rpz-drop.
|
||||
tcp CNAME rpz-tcp-only.
|
||||
c.g CNAME .
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
@ -50,6 +56,9 @@ stub-zone:
|
||||
stub-zone:
|
||||
name: "tcp."
|
||||
stub-addr: 10.20.30.60
|
||||
stub-zone:
|
||||
name: "g."
|
||||
stub-addr: 10.20.30.40
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test all support RPZ action for QNAME trigger
|
||||
@ -89,6 +98,16 @@ SECTION ANSWER
|
||||
x.b.a. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
c.g. IN TXT
|
||||
SECTION ANSWER
|
||||
c.g. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
RANGE_END
|
||||
|
||||
; example.
|
||||
@ -396,5 +415,23 @@ f.example. IN CNAME d.
|
||||
d. IN TXT "local data 2nd zone"
|
||||
ENTRY_END
|
||||
|
||||
; check if passthru ends processing
|
||||
STEP 110 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
c.g. IN TXT
|
||||
ENTRY_END
|
||||
|
||||
STEP 111 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
c.g. IN TXT
|
||||
SECTION ANSWER
|
||||
c.g. IN TXT "answer from upstream ns"
|
||||
ENTRY_END
|
||||
|
||||
; no answer is checked at exit of testbound.
|
||||
SCENARIO_END
|
||||
|
@ -667,6 +667,8 @@ struct module_qstate {
|
||||
/** Extended result of response-ip action processing, mainly
|
||||
* for logging purposes. */
|
||||
struct respip_action_info* respip_action_info;
|
||||
/** if the query is rpz passthru, no further rpz processing for it */
|
||||
int rpz_passthru;
|
||||
|
||||
/** whether the reply should be dropped */
|
||||
int is_drop;
|
||||
|
@ -2397,7 +2397,7 @@ probe_anchor(struct module_env* env, struct trust_anchor* tp)
|
||||
qinfo.qclass);
|
||||
|
||||
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
|
||||
&probe_answer_cb, env)) {
|
||||
&probe_answer_cb, env, 0)) {
|
||||
log_err("out of memory making 5011 probe");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user