mirror of
https://github.com/NLnetLabs/unbound.git
synced 2024-09-21 06:37:08 +00:00
- Expose if a query (or a subquery) was ratelimited (not src IP
ratelimiting) to libunbound under 'ub_result.was_ratelimited'. This also introduces a change to 'ub_event_callback_type' in libunbound/unbound-event.h. - Tidy pylib tests. git-svn-id: file:///svn/unbound/trunk@4828 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
87bdb489f9
commit
749d1b9ebc
@ -2007,22 +2007,22 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
||||
}
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
@ -2035,13 +2035,13 @@ int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
|
||||
int order_lock_cmp(const void* ATTR_UNUSED(e1), const void* ATTR_UNUSED(e2))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int codeline_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
3 August 2018: George
|
||||
- Expose if a query (or a subquery) was ratelimited (not src IP
|
||||
ratelimiting) to libunbound under 'ub_result.was_ratelimited'.
|
||||
This also introduces a change to 'ub_event_callback_type' in
|
||||
libunbound/unbound-event.h.
|
||||
- Tidy pylib tests.
|
||||
|
||||
3 August 2018: Wouter
|
||||
- Revert previous change for #4136: because it introduces build
|
||||
problems.
|
||||
|
@ -1399,6 +1399,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
log_nametypeclass(VERB_ALGO, "ratelimit exceeded with "
|
||||
"delegation point", iq->dp->name,
|
||||
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
|
||||
qstate->was_ratelimited = 1;
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
}
|
||||
@ -2379,6 +2380,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
ie->num_queries_ratelimited++;
|
||||
lock_basic_unlock(&ie->queries_ratelimit_lock);
|
||||
verbose(VERB_ALGO, "query exceeded ratelimits");
|
||||
qstate->was_ratelimited = 1;
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
}
|
||||
|
@ -293,26 +293,29 @@ context_serialize_answer(struct ctx_query* q, int err, sldns_buffer* pkt,
|
||||
* o uint32 id
|
||||
* o uint32 error_code
|
||||
* o uint32 msg_security
|
||||
* o uint32 was_ratelimited
|
||||
* o uint32 length of why_bogus string (+1 for eos); 0 absent.
|
||||
* o why_bogus_string
|
||||
* o the remainder is the answer msg from resolver lookup.
|
||||
* remainder can be length 0.
|
||||
*/
|
||||
size_t size_of_uint32s = 6 * sizeof(uint32_t);
|
||||
size_t pkt_len = pkt?sldns_buffer_remaining(pkt):0;
|
||||
size_t wlen = (pkt&&q->res->why_bogus)?strlen(q->res->why_bogus)+1:0;
|
||||
uint8_t* p;
|
||||
*len = sizeof(uint32_t)*5 + pkt_len + wlen;
|
||||
*len = size_of_uint32s + pkt_len + wlen;
|
||||
p = (uint8_t*)malloc(*len);
|
||||
if(!p) return NULL;
|
||||
sldns_write_uint32(p, UB_LIBCMD_ANSWER);
|
||||
sldns_write_uint32(p+sizeof(uint32_t), (uint32_t)q->querynum);
|
||||
sldns_write_uint32(p+2*sizeof(uint32_t), (uint32_t)err);
|
||||
sldns_write_uint32(p+3*sizeof(uint32_t), (uint32_t)q->msg_security);
|
||||
sldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)wlen);
|
||||
sldns_write_uint32(p+4*sizeof(uint32_t), (uint32_t)q->res->was_ratelimited);
|
||||
sldns_write_uint32(p+5*sizeof(uint32_t), (uint32_t)wlen);
|
||||
if(wlen > 0)
|
||||
memmove(p+5*sizeof(uint32_t), q->res->why_bogus, wlen);
|
||||
memmove(p+size_of_uint32s, q->res->why_bogus, wlen);
|
||||
if(pkt_len > 0)
|
||||
memmove(p+5*sizeof(uint32_t)+wlen,
|
||||
memmove(p+size_of_uint32s+wlen,
|
||||
sldns_buffer_begin(pkt), pkt_len);
|
||||
return p;
|
||||
}
|
||||
@ -321,21 +324,23 @@ struct ctx_query*
|
||||
context_deserialize_answer(struct ub_ctx* ctx,
|
||||
uint8_t* p, uint32_t len, int* err)
|
||||
{
|
||||
size_t size_of_uint32s = 6 * sizeof(uint32_t);
|
||||
struct ctx_query* q = NULL ;
|
||||
int id;
|
||||
size_t wlen;
|
||||
if(len < 5*sizeof(uint32_t)) return NULL;
|
||||
if(len < size_of_uint32s) return NULL;
|
||||
log_assert( sldns_read_uint32(p) == UB_LIBCMD_ANSWER);
|
||||
id = (int)sldns_read_uint32(p+sizeof(uint32_t));
|
||||
q = (struct ctx_query*)rbtree_search(&ctx->queries, &id);
|
||||
if(!q) return NULL;
|
||||
*err = (int)sldns_read_uint32(p+2*sizeof(uint32_t));
|
||||
q->msg_security = sldns_read_uint32(p+3*sizeof(uint32_t));
|
||||
wlen = (size_t)sldns_read_uint32(p+4*sizeof(uint32_t));
|
||||
if(len > 5*sizeof(uint32_t) && wlen > 0) {
|
||||
if(len >= 5*sizeof(uint32_t)+wlen)
|
||||
q->res->was_ratelimited = sldns_read_uint32(p+4*sizeof(uint32_t));
|
||||
wlen = (size_t)sldns_read_uint32(p+5*sizeof(uint32_t));
|
||||
if(len > size_of_uint32s && wlen > 0) {
|
||||
if(len >= size_of_uint32s+wlen)
|
||||
q->res->why_bogus = (char*)memdup(
|
||||
p+5*sizeof(uint32_t), wlen);
|
||||
p+size_of_uint32s, wlen);
|
||||
if(!q->res->why_bogus) {
|
||||
/* pass malloc failure to the user callback */
|
||||
q->msg_len = 0;
|
||||
@ -344,9 +349,9 @@ context_deserialize_answer(struct ub_ctx* ctx,
|
||||
}
|
||||
q->res->why_bogus[wlen-1] = 0; /* zero terminated for sure */
|
||||
}
|
||||
if(len > 5*sizeof(uint32_t)+wlen) {
|
||||
q->msg_len = len - 5*sizeof(uint32_t) - wlen;
|
||||
q->msg = (uint8_t*)memdup(p+5*sizeof(uint32_t)+wlen,
|
||||
if(len > size_of_uint32s+wlen) {
|
||||
q->msg_len = len - size_of_uint32s - wlen;
|
||||
q->msg = (uint8_t*)memdup(p+size_of_uint32s+wlen,
|
||||
q->msg_len);
|
||||
if(!q->msg) {
|
||||
/* pass malloc failure to the user callback */
|
||||
|
@ -521,8 +521,9 @@ libworker_enter_result(struct ub_result* res, sldns_buffer* buf,
|
||||
/** fillup fg results */
|
||||
static void
|
||||
libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus)
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
q->res->was_ratelimited = was_ratelimited;
|
||||
if(why_bogus)
|
||||
q->res->why_bogus = strdup(why_bogus);
|
||||
if(rcode != 0) {
|
||||
@ -546,13 +547,13 @@ libworker_fillup_fg(struct ctx_query* q, int rcode, sldns_buffer* buf,
|
||||
|
||||
void
|
||||
libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
/* fg query is done; exit comm base */
|
||||
comm_base_exit(q->w->base);
|
||||
|
||||
libworker_fillup_fg(q, rcode, buf, s, why_bogus);
|
||||
libworker_fillup_fg(q, rcode, buf, s, why_bogus, was_ratelimited);
|
||||
}
|
||||
|
||||
/** setup qinfo and edns */
|
||||
@ -603,7 +604,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
NULL, 0, NULL, 0, NULL)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
libworker_fillup_fg(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
libworker_delete(w);
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
@ -612,7 +613,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
w->env, &qinfo, &edns, 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);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
libworker_delete(w);
|
||||
free(qinfo.qname);
|
||||
return UB_NOERROR;
|
||||
@ -634,7 +635,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
|
||||
|
||||
void
|
||||
libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus)
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
ub_event_callback_type cb = q->cb_event;
|
||||
@ -657,7 +658,7 @@ libworker_event_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
else if(s == sec_status_secure)
|
||||
sec = 2;
|
||||
(*cb)(cb_arg, rcode, (void*)sldns_buffer_begin(buf),
|
||||
(int)sldns_buffer_limit(buf), sec, why_bogus);
|
||||
(int)sldns_buffer_limit(buf), sec, why_bogus, was_ratelimited);
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,7 +685,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
regional_free_all(w->env->scratch);
|
||||
free(qinfo.qname);
|
||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
if(ctx->env->auth_zones && auth_zones_answer(ctx->env->auth_zones,
|
||||
@ -692,7 +693,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
regional_free_all(w->env->scratch);
|
||||
free(qinfo.qname);
|
||||
libworker_event_done_cb(q, LDNS_RCODE_NOERROR,
|
||||
w->back->udp_buff, sec_status_insecure, NULL);
|
||||
w->back->udp_buff, sec_status_insecure, NULL, 0);
|
||||
return UB_NOERROR;
|
||||
}
|
||||
/* process new query */
|
||||
@ -710,7 +711,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
|
||||
/** add result to the bg worker result queue */
|
||||
static void
|
||||
add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
|
||||
int err, char* reason)
|
||||
int err, char* reason, int was_ratelimited)
|
||||
{
|
||||
uint8_t* msg = NULL;
|
||||
uint32_t len = 0;
|
||||
@ -724,19 +725,23 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
|
||||
lock_basic_lock(&w->ctx->cfglock);
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
q->res->was_ratelimited = was_ratelimited;
|
||||
if(pkt) {
|
||||
q->msg_len = sldns_buffer_remaining(pkt);
|
||||
q->msg = memdup(sldns_buffer_begin(pkt), q->msg_len);
|
||||
if(!q->msg)
|
||||
msg = context_serialize_answer(q, UB_NOMEM,
|
||||
NULL, &len);
|
||||
else msg = context_serialize_answer(q, err,
|
||||
NULL, &len);
|
||||
} else msg = context_serialize_answer(q, err, NULL, &len);
|
||||
if(!q->msg) {
|
||||
msg = context_serialize_answer(q, UB_NOMEM, NULL, &len);
|
||||
} else {
|
||||
msg = context_serialize_answer(q, err, NULL, &len);
|
||||
}
|
||||
} else {
|
||||
msg = context_serialize_answer(q, err, NULL, &len);
|
||||
}
|
||||
lock_basic_unlock(&w->ctx->cfglock);
|
||||
} else {
|
||||
if(reason)
|
||||
q->res->why_bogus = strdup(reason);
|
||||
q->res->was_ratelimited = was_ratelimited;
|
||||
msg = context_serialize_answer(q, err, pkt, &len);
|
||||
(void)rbtree_delete(&w->ctx->queries, q->node.key);
|
||||
w->ctx->num_async--;
|
||||
@ -755,7 +760,7 @@ add_bg_result(struct libworker* w, struct ctx_query* q, sldns_buffer* pkt,
|
||||
|
||||
void
|
||||
libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
|
||||
char* why_bogus)
|
||||
char* why_bogus, int was_ratelimited)
|
||||
{
|
||||
struct ctx_query* q = (struct ctx_query*)arg;
|
||||
|
||||
@ -773,12 +778,13 @@ libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf, enum sec_status s,
|
||||
return;
|
||||
}
|
||||
q->msg_security = s;
|
||||
if(!buf)
|
||||
if(!buf) {
|
||||
buf = q->w->env->scratch_buffer;
|
||||
}
|
||||
if(rcode != 0) {
|
||||
error_encode(buf, rcode, NULL, 0, BIT_RD, NULL);
|
||||
}
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus);
|
||||
add_bg_result(q->w, q, buf, UB_NOERROR, why_bogus, was_ratelimited);
|
||||
}
|
||||
|
||||
|
||||
@ -803,7 +809,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
return;
|
||||
}
|
||||
if(!setup_qinfo_edns(w, q, &qinfo, &edns)) {
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX, NULL);
|
||||
add_bg_result(w, q, NULL, UB_SYNTAX, NULL, 0);
|
||||
return;
|
||||
}
|
||||
qid = 0;
|
||||
@ -816,7 +822,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
NULL, 0, NULL, 0, NULL)) {
|
||||
regional_free_all(w->env->scratch);
|
||||
q->msg_security = sec_status_insecure;
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL);
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
@ -824,7 +830,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
w->env, &qinfo, &edns, 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);
|
||||
add_bg_result(w, q, w->back->udp_buff, UB_NOERROR, NULL, 0);
|
||||
free(qinfo.qname);
|
||||
return;
|
||||
}
|
||||
@ -832,7 +838,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
|
||||
/* process new query */
|
||||
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
|
||||
w->back->udp_buff, qid, libworker_bg_done_cb, q)) {
|
||||
add_bg_result(w, q, NULL, UB_NOMEM, NULL);
|
||||
add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0);
|
||||
}
|
||||
free(qinfo.qname);
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ struct ub_event {
|
||||
struct ub_event_vmt* vmt;
|
||||
};
|
||||
|
||||
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*);
|
||||
typedef void (*ub_event_callback_type)(void*, int, void*, int, int, char*, int);
|
||||
|
||||
/**
|
||||
* Create a resolving and validation context.
|
||||
|
@ -203,6 +203,12 @@ struct ub_result {
|
||||
*/
|
||||
char* why_bogus;
|
||||
|
||||
/**
|
||||
* If the query or one of its subqueries was ratelimited. Useful if
|
||||
* ratelimiting is enabled and answer is SERVFAIL.
|
||||
*/
|
||||
int was_ratelimited;
|
||||
|
||||
/**
|
||||
* TTL for the result, in seconds. If the security is bogus, then
|
||||
* you also cannot trust this value.
|
||||
|
@ -89,15 +89,15 @@ void libworker_handle_control_cmd(struct tube* tube, uint8_t* msg, size_t len,
|
||||
|
||||
/** mesh callback with fg results */
|
||||
void libworker_fg_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/** mesh callback with bg results */
|
||||
void libworker_bg_done_cb(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/** mesh callback with event results */
|
||||
void libworker_event_done_cb(void* arg, int rcode, struct sldns_buffer* buf,
|
||||
enum sec_status s, char* why_bogus);
|
||||
enum sec_status s, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/**
|
||||
* Worker signal handler function. User argument is the worker itself.
|
||||
|
@ -5150,7 +5150,8 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
|
||||
|
||||
/** callback for task_transfer lookup of host name, of A or AAAA */
|
||||
void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus))
|
||||
enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
|
||||
int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
struct auth_xfer* xfr = (struct auth_xfer*)arg;
|
||||
struct module_env* env;
|
||||
@ -6061,7 +6062,8 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
|
||||
/** callback for task_probe lookup of host name, of A or AAAA */
|
||||
void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus))
|
||||
enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
|
||||
int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
struct auth_xfer* xfr = (struct auth_xfer*)arg;
|
||||
struct module_env* env;
|
||||
|
@ -646,10 +646,12 @@ int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
|
||||
void auth_xfer_probe_timer_callback(void* arg);
|
||||
/** mesh callback for task_probe on lookup of host names */
|
||||
void auth_xfer_probe_lookup_callback(void* arg, int rcode,
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
|
||||
int was_ratelimited);
|
||||
/** mesh callback for task_transfer on lookup of host names */
|
||||
void auth_xfer_transfer_lookup_callback(void* arg, int rcode,
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus);
|
||||
struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
|
||||
int was_ratelimited);
|
||||
|
||||
/*
|
||||
* Compares two 32-bit serial numbers as defined in RFC1982. Returns
|
||||
|
@ -632,8 +632,8 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
|
||||
mesh_run(mesh, e->qstate->mesh_info, event, e);
|
||||
}
|
||||
|
||||
struct mesh_state*
|
||||
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
struct mesh_state*
|
||||
mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
struct respip_client_info* cinfo, uint16_t qflags, int prime,
|
||||
int valrec)
|
||||
{
|
||||
@ -694,6 +694,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
mstate->s.no_cache_lookup = 0;
|
||||
mstate->s.no_cache_store = 0;
|
||||
mstate->s.need_refetch = 0;
|
||||
mstate->s.was_ratelimited = 0;
|
||||
|
||||
/* init modules */
|
||||
for(i=0; i<env->mesh->mods.num; i++) {
|
||||
@ -741,7 +742,7 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
mstate->cb_list = cb->next;
|
||||
fptr_ok(fptr_whitelist_mesh_cb(cb->cb));
|
||||
(*cb->cb)(cb->cb_arg, LDNS_RCODE_SERVFAIL, NULL,
|
||||
sec_status_unchecked, NULL);
|
||||
sec_status_unchecked, NULL, 0);
|
||||
mesh->num_reply_addrs--;
|
||||
}
|
||||
}
|
||||
@ -969,7 +970,8 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
{
|
||||
int secure;
|
||||
char* reason = NULL;
|
||||
/* bogus messages are not made into servfail, sec_status passed
|
||||
int was_ratelimited = m->s.was_ratelimited;
|
||||
/* bogus messages are not made into servfail, sec_status passed
|
||||
* to the callback function */
|
||||
if(rep && rep->security == sec_status_secure)
|
||||
secure = 1;
|
||||
@ -993,7 +995,8 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
r->edns.opt_list = NULL;
|
||||
}
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL);
|
||||
(*r->cb)(r->cb_arg, rcode, r->buf, sec_status_unchecked, NULL,
|
||||
was_ratelimited);
|
||||
} else {
|
||||
size_t udp_size = r->edns.udp_size;
|
||||
sldns_buffer_clear(r->buf);
|
||||
@ -1011,11 +1014,11 @@ mesh_do_callback(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
{
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_SERVFAIL, r->buf,
|
||||
sec_status_unchecked, NULL);
|
||||
sec_status_unchecked, NULL, 0);
|
||||
} else {
|
||||
fptr_ok(fptr_whitelist_mesh_cb(r->cb));
|
||||
(*r->cb)(r->cb_arg, LDNS_RCODE_NOERROR, r->buf,
|
||||
rep->security, reason);
|
||||
rep->security, reason, was_ratelimited);
|
||||
}
|
||||
}
|
||||
free(reason);
|
||||
@ -1201,6 +1204,8 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate)
|
||||
mesh->mods.mod[ref->s->s.curmod]->inform_super));
|
||||
(*mesh->mods.mod[ref->s->s.curmod]->inform_super)(&mstate->s,
|
||||
ref->s->s.curmod, &ref->s->s);
|
||||
/* copy state that is always relevant to super */
|
||||
copy_state_to_super(&mstate->s, ref->s->s.curmod, &ref->s->s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,10 +223,11 @@ struct mesh_reply {
|
||||
|
||||
/**
|
||||
* Mesh result callback func.
|
||||
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus);
|
||||
* called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus,
|
||||
* was_ratelimited);
|
||||
*/
|
||||
typedef void (*mesh_cb_func_type)(void*, int, struct sldns_buffer*, enum sec_status,
|
||||
char*);
|
||||
typedef void (*mesh_cb_func_type)(void* cb_arg, int rcode, struct sldns_buffer*,
|
||||
enum sec_status, char* why_bogus, int was_ratelimited);
|
||||
|
||||
/**
|
||||
* Callback to result routine
|
||||
@ -242,9 +243,8 @@ struct mesh_cb {
|
||||
uint16_t qflags;
|
||||
/** buffer for reply */
|
||||
struct sldns_buffer* buf;
|
||||
|
||||
/** callback routine for results. if rcode != 0 buf has message.
|
||||
* called as cb(cb_arg, rcode, buf, sec_state);
|
||||
* called as cb(cb_arg, rcode, buf, sec_state, why_bogus, was_ratelimited);
|
||||
*/
|
||||
mesh_cb_func_type cb;
|
||||
/** user arg for callback */
|
||||
|
@ -168,21 +168,21 @@ void libworker_handle_control_cmd(struct tube* ATTR_UNUSED(tube),
|
||||
|
||||
void libworker_fg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_bg_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
struct sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
server:
|
||||
verbosity: 2
|
||||
# num-threads: 1
|
||||
#port: @PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
@ -10,10 +8,7 @@ server:
|
||||
do-not-query-localhost: no
|
||||
module-config: "validator iterator"
|
||||
|
||||
#python:
|
||||
#python-script: "pylib.py"
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: "127.0.0.1@@TOPORT@"
|
||||
stub-zone:
|
||||
name: "example.com."
|
||||
stub-addr: "127.0.0.1@@TOPORT@"
|
||||
|
149
testdata/pylib.tdir/pylib.lookup.py
vendored
149
testdata/pylib.tdir/pylib.lookup.py
vendored
@ -1,24 +1,139 @@
|
||||
#!/usr/bin/env python
|
||||
'''
|
||||
Test for unbound lookup.
|
||||
BSD licensed.
|
||||
'''
|
||||
#
|
||||
# Test for pyunbound lookup.
|
||||
# BSD licensed.
|
||||
#
|
||||
import sys
|
||||
import time
|
||||
|
||||
import unbound
|
||||
|
||||
ctx = unbound.ub_ctx()
|
||||
status = ctx.config("ub.conf")
|
||||
if status != 0:
|
||||
print "read config failed ", status
|
||||
exit(1)
|
||||
qname = "www.example.com"
|
||||
qtype = unbound.RR_TYPE_A
|
||||
qclass = unbound.RR_CLASS_IN
|
||||
|
||||
print "config created"
|
||||
def create_context(config_file="ub.lookup.conf", async=False):
|
||||
"""
|
||||
Create an unbound context to use for testing.
|
||||
|
||||
status, result = ctx.resolve("www.example.com", unbound.RR_TYPE_A, unbound.RR_CLASS_IN);
|
||||
if status == 0 and result.havedata:
|
||||
print "Result: ", result.data.address_list
|
||||
else:
|
||||
print "Failed ", status, " and data ", result
|
||||
"""
|
||||
ctx = unbound.ub_ctx()
|
||||
status = ctx.config(config_file)
|
||||
if status != 0:
|
||||
print("read config failed with status: {}".format(status))
|
||||
sys.exit(1)
|
||||
ctx.set_async(async)
|
||||
return ctx
|
||||
|
||||
ctx = None
|
||||
|
||||
exit(0)
|
||||
def callback(data, status, result):
|
||||
"""
|
||||
Callback for background workers.
|
||||
|
||||
"""
|
||||
if status == 0:
|
||||
data['rcode'] = result.rcode
|
||||
data['secure'] = result.secure
|
||||
if result.havedata:
|
||||
data['data'] = result.data
|
||||
data['was_ratelimited'] = result.was_ratelimited
|
||||
data['done'] = True
|
||||
|
||||
|
||||
def test_resolve(ctx):
|
||||
"""
|
||||
Test resolving a domain with a foreground worker.
|
||||
|
||||
"""
|
||||
status, result = ctx.resolve(qname, qtype, qclass)
|
||||
if status == 0 and result.havedata:
|
||||
print("Resolve: {}".format(result.data.address_list))
|
||||
else:
|
||||
print("Failed resolve with: {}".format(status))
|
||||
|
||||
|
||||
def test_async_resolve(ctx):
|
||||
"""
|
||||
Test resolving a domain with a background worker.
|
||||
|
||||
"""
|
||||
cb_data = dict(done=False)
|
||||
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
|
||||
while retval == 0 and not cb_data['done']:
|
||||
time.sleep(0.1)
|
||||
retval = ctx.process()
|
||||
|
||||
if cb_data.get('data'):
|
||||
print("Async resolve: {}".format(cb_data['data'].address_list))
|
||||
else:
|
||||
print("Failed async resolve with: {}".format(retval))
|
||||
|
||||
|
||||
def test_ratelimit_fg_on(ctx):
|
||||
"""
|
||||
Test resolving a ratelimited domain with a foreground worker.
|
||||
|
||||
"""
|
||||
ctx.set_option("ratelimit:", "1")
|
||||
status, result = ctx.resolve(qname, qtype, qclass)
|
||||
if status == 0 and result.was_ratelimited:
|
||||
print("Ratelimit-fg-on: pass")
|
||||
else:
|
||||
print("Failed ratelimit-fg-on with: {}".format(status))
|
||||
|
||||
|
||||
def test_ratelimit_fg_off(ctx):
|
||||
"""
|
||||
Test resolving a non-ratelimited domain with a foreground worker.
|
||||
|
||||
"""
|
||||
status, result = ctx.resolve(qname, qtype, qclass)
|
||||
if status == 0 and result.havedata:
|
||||
print("Ratelimit-fg-off: {}".format(result.data.address_list))
|
||||
else:
|
||||
print("Failed ratelimit-fg-off with: {}".format(status))
|
||||
|
||||
|
||||
def test_ratelimit_bg_on(ctx):
|
||||
"""
|
||||
Test resolving a ratelimited domain with a background worker.
|
||||
|
||||
"""
|
||||
ctx.set_option("ratelimit:", "1")
|
||||
cb_data = dict(done=False)
|
||||
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
|
||||
while retval == 0 and not cb_data['done']:
|
||||
time.sleep(0.1)
|
||||
retval = ctx.process()
|
||||
|
||||
if cb_data.get('was_ratelimited'):
|
||||
print("Ratelimit-bg-on: pass")
|
||||
else:
|
||||
print("Failed ratelimit-bg-on with: {}".format(status))
|
||||
|
||||
|
||||
def test_ratelimit_bg_off(ctx):
|
||||
"""
|
||||
Test resolving a non-ratelimited domain with a background worker.
|
||||
|
||||
"""
|
||||
cb_data = dict(done=False)
|
||||
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
|
||||
while retval == 0 and not cb_data['done']:
|
||||
time.sleep(0.1)
|
||||
retval = ctx.process()
|
||||
|
||||
if cb_data.get('data'):
|
||||
print("Ratelimit-bg-off: {}".format(cb_data['data'].address_list))
|
||||
else:
|
||||
print("Failed ratelimit-bg-off with: {}".format(status))
|
||||
|
||||
|
||||
test_resolve(create_context())
|
||||
test_async_resolve(create_context(async=True))
|
||||
test_ratelimit_fg_on(create_context())
|
||||
test_ratelimit_fg_off(create_context())
|
||||
test_ratelimit_bg_on(create_context(async=True))
|
||||
test_ratelimit_bg_off(create_context(async=True))
|
||||
|
||||
sys.exit(0)
|
||||
|
4
testdata/pylib.tdir/pylib.post
vendored
4
testdata/pylib.tdir/pylib.post
vendored
@ -10,9 +10,9 @@ PRE="../.."
|
||||
. ../common.sh
|
||||
# if no python; exit
|
||||
if grep "define WITH_PYUNBOUND 1" $PRE/config.h; then
|
||||
echo "have python module"
|
||||
echo "have pyunbound"
|
||||
else
|
||||
echo "no python module"
|
||||
echo "no pyunbound"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
13
testdata/pylib.tdir/pylib.pre
vendored
13
testdata/pylib.tdir/pylib.pre
vendored
@ -8,13 +8,16 @@ PRE="../.."
|
||||
. ../common.sh
|
||||
# if no python; exit
|
||||
if grep "define WITH_PYUNBOUND 1" $PRE/config.h; then
|
||||
echo "have python module"
|
||||
echo "have pyunbound"
|
||||
else
|
||||
echo "no python module"
|
||||
echo "no pyunbound"
|
||||
exit 0
|
||||
fi
|
||||
# get module python local
|
||||
cp $PRE/pythonmod/unboundmodule.py .
|
||||
|
||||
# Copy the required libraries
|
||||
cp $PRE/libunbound/python/unbound.py .
|
||||
cp $PRE/.libs/_unbound* .
|
||||
cp $PRE/.libs/libunbound* .
|
||||
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
@ -29,7 +32,7 @@ FWD_PID=$!
|
||||
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||
|
||||
# modify config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < pylib.conf > ub.conf
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < pylib.lookup.conf > ub.lookup.conf
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_ldns_testns_up fwd.log
|
||||
|
159
testdata/pylib.tdir/pylib.py
vendored
159
testdata/pylib.tdir/pylib.py
vendored
@ -1,159 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
ubmodule-msg.py: simple response packet logger
|
||||
|
||||
Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
|
||||
Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz)
|
||||
|
||||
Copyright (c) 2008. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Modified for unit test by Wouter Wijngaards, NLnet Labs, 2009.
|
||||
'''
|
||||
import os
|
||||
|
||||
def init(id, cfg):
|
||||
log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, cfg.python_script))
|
||||
return True
|
||||
|
||||
def deinit(id):
|
||||
log_info("pythonmod: deinit called, module id is %d" % id)
|
||||
return True
|
||||
|
||||
def inform_super(id, qstate, superqstate, qdata):
|
||||
return True
|
||||
|
||||
def setTTL(qstate, ttl):
|
||||
"""Sets return_msg TTL and all the RRs TTL"""
|
||||
if qstate.return_msg:
|
||||
qstate.return_msg.rep.ttl = ttl
|
||||
if (qstate.return_msg.rep):
|
||||
for i in range(0,qstate.return_msg.rep.rrset_count):
|
||||
d = qstate.return_msg.rep.rrsets[i].entry.data
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
d.rr_ttl[j] = ttl
|
||||
|
||||
def dataHex(data, prefix=""):
|
||||
res = ""
|
||||
for i in range(0, (len(data)+15)/16):
|
||||
res += "%s0x%02X | " % (prefix, i*16)
|
||||
d = map(lambda x:ord(x), data[i*16:i*16+17])
|
||||
for ch in d:
|
||||
res += "%02X " % ch
|
||||
for i in range(0,17-len(d)):
|
||||
res += " "
|
||||
res += "| "
|
||||
for ch in d:
|
||||
if (ch < 32) or (ch > 127):
|
||||
res += ". "
|
||||
else:
|
||||
res += "%c " % ch
|
||||
res += "\n"
|
||||
return res
|
||||
|
||||
def printReturnMsg(qstate):
|
||||
print "Return MSG rep :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl)
|
||||
print " qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str
|
||||
if (qstate.return_msg.rep):
|
||||
print "RRSets:",qstate.return_msg.rep.rrset_count
|
||||
prevkey = None
|
||||
for i in range(0,qstate.return_msg.rep.rrset_count):
|
||||
r = qstate.return_msg.rep.rrsets[i]
|
||||
rk = r.rk
|
||||
print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
|
||||
print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
|
||||
|
||||
d = r.entry.data
|
||||
print " RRDatas:",d.count+d.rrsig_count
|
||||
for j in range(0,d.count+d.rrsig_count):
|
||||
print " ",j,":","TTL=",d.rr_ttl[j],"RR data:"
|
||||
print dataHex(d.rr_data[j]," ")
|
||||
|
||||
|
||||
def operate(id, event, qstate, qdata):
|
||||
log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
|
||||
#print "pythonmod: per query data", qdata
|
||||
|
||||
print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list, qstate.qinfo.qname_str,
|
||||
print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype,
|
||||
print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass
|
||||
print
|
||||
|
||||
if (event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS) and (qstate.qinfo.qname_str.endswith("www2.example.com.")):
|
||||
print qstate.qinfo.qname_str
|
||||
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
|
||||
msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300)
|
||||
#msg.authority.append("xxx.seznam.cz. 10 IN A 192.168.1.1")
|
||||
#msg.additional.append("yyy.seznam.cz. 10 IN A 1.1.1.2.")
|
||||
|
||||
# answer can be returned to the client without further checking.
|
||||
|
||||
if qstate.qinfo.qtype == RR_TYPE_A:
|
||||
msg.answer.append("%s 10 IN A 192.168.1.1" % qstate.qinfo.qname_str)
|
||||
if (qstate.qinfo.qtype == RR_TYPE_SRV) or (qstate.qinfo.qtype == RR_TYPE_ANY):
|
||||
msg.answer.append("%s 10 IN SRV 0 0 80 neinfo.example.com." % qstate.qinfo.qname_str)
|
||||
if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
|
||||
msg.answer.append("%s 10 IN TXT path=/" % qstate.qinfo.qname_str)
|
||||
|
||||
if not msg.set_return_msg(qstate):
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
#qstate.return_msg.rep.security = 2 #pokud nebude nasledovat validator, je zapotrebi nastavit security, aby nebyl paket zahozen v mesh_send_reply
|
||||
printReturnMsg(qstate)
|
||||
|
||||
#Authoritative result can't be stored in cache
|
||||
#if (not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0)):
|
||||
# print "Can't store in cache"
|
||||
# qstate.ext_state[id] = MODULE_ERROR
|
||||
# return False
|
||||
#print "Store OK"
|
||||
|
||||
qstate.return_rcode = RCODE_NOERROR
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_NEW:
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_MODDONE:
|
||||
log_info("pythonmod: previous module done")
|
||||
qstate.ext_state[id] = MODULE_FINISHED
|
||||
return True
|
||||
|
||||
if event == MODULE_EVENT_PASS:
|
||||
log_info("pythonmod: event_pass")
|
||||
qstate.ext_state[id] = MODULE_WAIT_MODULE
|
||||
return True
|
||||
|
||||
log_err("pythonmod: BAD event")
|
||||
qstate.ext_state[id] = MODULE_ERROR
|
||||
return True
|
||||
|
||||
log_info("pythonmod: script loaded.")
|
48
testdata/pylib.tdir/pylib.test
vendored
48
testdata/pylib.tdir/pylib.test
vendored
@ -6,9 +6,9 @@
|
||||
|
||||
PRE="../.."
|
||||
if grep "define WITH_PYUNBOUND 1" $PRE/config.h; then
|
||||
echo "have python module"
|
||||
echo "have pyunbound"
|
||||
else
|
||||
echo "no python module"
|
||||
echo "no pyunbound"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
@ -19,22 +19,50 @@ fi
|
||||
#echo export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:../../.libs:."
|
||||
#export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:../../.libs:."
|
||||
|
||||
cp $PRE/libunbound/python/unbound.py .
|
||||
cp $PRE/.libs/_unbound* .
|
||||
cp $PRE/.libs/libunbound* .
|
||||
|
||||
# do the test
|
||||
echo "> pylib.lookup.py www.example.com."
|
||||
./pylib.lookup.py www.example.com. | tee outfile
|
||||
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat fwd.log
|
||||
echo "> check answer"
|
||||
if grep "10.20.30.40" outfile; then
|
||||
echo "OK"
|
||||
if grep "Resolve: \[.\?10.20.30.40.\?\]" outfile; then
|
||||
:
|
||||
else
|
||||
echo "Not OK"
|
||||
echo "Not OK (resolve)"
|
||||
exit 1
|
||||
fi
|
||||
if grep "Async resolve: \[.\?10.20.30.40.\?\]" outfile; then
|
||||
:
|
||||
else
|
||||
echo "Not OK (async resolve)"
|
||||
exit 1
|
||||
fi
|
||||
if grep "Ratelimit-fg-on: pass" outfile; then
|
||||
:
|
||||
else
|
||||
echo "Not OK (ratelimit-fg-on)"
|
||||
exit 1
|
||||
fi
|
||||
if grep "Ratelimit-fg-off: \[.\?10.20.30.40.\?\]" outfile; then
|
||||
:
|
||||
else
|
||||
echo "Not OK (ratelimit-fg-off)"
|
||||
exit 1
|
||||
fi
|
||||
if grep "Ratelimit-bg-on: pass" outfile; then
|
||||
:
|
||||
else
|
||||
echo "Not OK (ratelimit-bg-on)"
|
||||
exit 1
|
||||
fi
|
||||
if grep "Ratelimit-bg-off: \[.\?10.20.30.40.\?\]" outfile; then
|
||||
:
|
||||
else
|
||||
echo "Not OK (ratelimit-bg-off)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
|
||||
exit 0
|
||||
|
@ -913,8 +913,9 @@ parse_reply_in_temp_region(sldns_buffer* pkt, struct regional* region,
|
||||
}
|
||||
memset(msg, 0, sizeof(*msg));
|
||||
sldns_buffer_set_position(pkt, 0);
|
||||
if(parse_packet(pkt, msg, region) != 0)
|
||||
if(parse_packet(pkt, msg, region) != 0){
|
||||
return 0;
|
||||
}
|
||||
if(!parse_create_msg(pkt, msg, NULL, qi, &rep, region)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -236,3 +236,13 @@ log_edns_known_options(enum verbosity_value level, struct module_env* env)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
copy_state_to_super(struct module_qstate* qstate, int ATTR_UNUSED(id),
|
||||
struct module_qstate* super)
|
||||
{
|
||||
/* Overwrite super's was_ratelimited only when it was not set */
|
||||
if(!super->was_ratelimited) {
|
||||
super->was_ratelimited = qstate->was_ratelimited;
|
||||
}
|
||||
}
|
||||
|
@ -621,6 +621,8 @@ struct module_qstate {
|
||||
int no_cache_store;
|
||||
/** whether to refetch a fresh answer on finishing this state*/
|
||||
int need_refetch;
|
||||
/** whether the query (or a subquery) was ratelimited */
|
||||
int was_ratelimited;
|
||||
|
||||
/**
|
||||
* Attributes of clients that share the qstate that may affect IP-based
|
||||
@ -819,4 +821,14 @@ int unique_mesh_state(struct edns_option* list, struct module_env* env);
|
||||
void log_edns_known_options(enum verbosity_value level,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Copy state that may have happened in the subquery and is always relevant to
|
||||
* the super.
|
||||
* @param qstate: query state that finished.
|
||||
* @param id: module id.
|
||||
* @param super: the qstate to inform.
|
||||
*/
|
||||
void copy_state_to_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super);
|
||||
|
||||
#endif /* UTIL_MODULE_H */
|
||||
|
@ -2306,7 +2306,7 @@ autr_debug_print(struct val_anchors* anchors)
|
||||
|
||||
void probe_answer_cb(void* arg, int ATTR_UNUSED(rcode),
|
||||
sldns_buffer* ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(sec),
|
||||
char* ATTR_UNUSED(why_bogus))
|
||||
char* ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
/* retry was set before the query was done,
|
||||
* re-querytime is set when query succeeded, but that may not
|
||||
|
@ -206,6 +206,6 @@ void autr_debug_print(struct val_anchors* anchors);
|
||||
|
||||
/** callback for query answer to 5011 probe */
|
||||
void probe_answer_cb(void* arg, int rcode, struct sldns_buffer* buf,
|
||||
enum sec_status sec, char* errinf);
|
||||
enum sec_status sec, char* errinf, int was_ratelimited);
|
||||
|
||||
#endif /* VALIDATOR_AUTOTRUST_H */
|
||||
|
Loading…
Reference in New Issue
Block a user