mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
- Fix caps-for-id fallback, and added fallback attempt when servers
drop 0x20 perturbed queries. git-svn-id: file:///svn/unbound/trunk@3146 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
efe2a74af9
commit
bc7f906590
13 changed files with 74 additions and 36 deletions
|
|
@ -1293,8 +1293,8 @@ worker_delete(struct worker* worker)
|
|||
struct outbound_entry*
|
||||
worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
uint16_t qclass, uint16_t flags, int dnssec, int want_dnssec,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, struct module_qstate* q)
|
||||
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* q)
|
||||
{
|
||||
struct worker* worker = q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
|
|
@ -1303,7 +1303,7 @@ worker_send_query(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
|||
return NULL;
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(worker->back, qname,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec, nocaps,
|
||||
q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, addr,
|
||||
addrlen, zone, zonelen, worker_handle_service_reply, e,
|
||||
worker->back->udp_buff);
|
||||
|
|
@ -1350,7 +1350,7 @@ struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname),
|
|||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
24 June 2014: Wouter
|
||||
- Fix caps-for-id fallback, and added fallback attempt when servers
|
||||
drop 0x20 perturbed queries.
|
||||
|
||||
17 June 2014: Wouter
|
||||
- iana portlist updated.
|
||||
|
||||
|
|
|
|||
|
|
@ -1854,8 +1854,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->qchase.qname, iq->qchase.qname_len,
|
||||
iq->qchase.qtype, iq->qchase.qclass,
|
||||
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD,
|
||||
iq->dnssec_expected, &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen, qstate);
|
||||
iq->dnssec_expected, iq->caps_fallback, &target->addr,
|
||||
target->addrlen, iq->dp->name, iq->dp->namelen, qstate);
|
||||
if(!outq) {
|
||||
log_addr(VERB_DETAIL, "error sending query to auth server",
|
||||
&target->addr, target->addrlen);
|
||||
|
|
@ -2765,6 +2765,21 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
iq->response = NULL;
|
||||
iq->state = QUERY_RESP_STATE;
|
||||
if(event == module_event_noreply || event == module_event_error) {
|
||||
if(event == module_event_noreply && iq->sent_count >= 3 &&
|
||||
qstate->env->cfg->use_caps_bits_for_id &&
|
||||
!iq->caps_fallback) {
|
||||
/* start fallback */
|
||||
iq->caps_fallback = 1;
|
||||
iq->caps_server = 0;
|
||||
iq->caps_reply = NULL;
|
||||
iq->state = QUERYTARGETS_STATE;
|
||||
iq->num_current_queries--;
|
||||
/* need fresh attempts for the 0x20 fallback, if
|
||||
* that was the cause for the failure */
|
||||
iter_dec_attempts(iq->dp, 3);
|
||||
verbose(VERB_DETAIL, "Capsforid: timeouts, starting fallback");
|
||||
goto handle_it;
|
||||
}
|
||||
goto handle_it;
|
||||
}
|
||||
if( (event != module_event_reply && event != module_event_capsfail)
|
||||
|
|
@ -2813,7 +2828,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo,
|
||||
iq->response->rep);
|
||||
|
||||
if(event == module_event_capsfail) {
|
||||
if(event == module_event_capsfail || iq->caps_fallback) {
|
||||
if(!iq->caps_fallback) {
|
||||
/* start fallback */
|
||||
iq->caps_fallback = 1;
|
||||
|
|
@ -2825,7 +2840,11 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||
goto handle_it;
|
||||
} else {
|
||||
/* check if reply is the same, otherwise, fail */
|
||||
if(!reply_equal(iq->response->rep, iq->caps_reply,
|
||||
if(!iq->caps_reply) {
|
||||
iq->caps_reply = iq->response->rep;
|
||||
iq->caps_server = -1; /*become zero at ++,
|
||||
so that we start the full set of trials */
|
||||
} else if(!reply_equal(iq->response->rep, iq->caps_reply,
|
||||
qstate->env->scratch)) {
|
||||
verbose(VERB_DETAIL, "Capsforid fallback: "
|
||||
"getting different replies, failed");
|
||||
|
|
|
|||
|
|
@ -230,7 +230,8 @@ struct iter_qstate {
|
|||
int caps_fallback;
|
||||
/** state for capsfail: current server number to try */
|
||||
size_t caps_server;
|
||||
/** state for capsfail: stored query for comparisons */
|
||||
/** state for capsfail: stored query for comparisons. Can be NULL if
|
||||
* no response had been seen prior to starting the fallback. */
|
||||
struct reply_info* caps_reply;
|
||||
|
||||
/** Current delegation message - returned for non-RD queries */
|
||||
|
|
|
|||
|
|
@ -821,8 +821,9 @@ void libworker_alloc_cleanup(void* arg)
|
|||
|
||||
struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* q)
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q)
|
||||
{
|
||||
struct libworker* w = (struct libworker*)q->env->worker;
|
||||
struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
|
||||
|
|
@ -831,7 +832,7 @@ struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
|||
return NULL;
|
||||
e->qstate = q;
|
||||
e->qsent = outnet_serviced_query(w->back, qname,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec,
|
||||
qnamelen, qtype, qclass, flags, dnssec, want_dnssec, nocaps,
|
||||
q->env->cfg->tcp_upstream, q->env->cfg->ssl_upstream, addr,
|
||||
addrlen, zone, zonelen, libworker_handle_service_reply, e,
|
||||
w->back->udp_buff);
|
||||
|
|
@ -953,7 +954,7 @@ struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
|
|||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ struct tube;
|
|||
* @param flags: host order flags word, with opcode and CD bit.
|
||||
* @param dnssec: if set, EDNS record will have DO bit set.
|
||||
* @param want_dnssec: signatures needed.
|
||||
* @param nocaps: ignore capsforid(if in config), do not perturb qname.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: delegation point name.
|
||||
|
|
@ -68,8 +69,9 @@ struct tube;
|
|||
*/
|
||||
struct outbound_entry* libworker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* q);
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q);
|
||||
|
||||
/** process incoming replies from the network */
|
||||
int libworker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||
|
|
@ -111,6 +113,7 @@ void worker_sighandler(int sig, void* arg);
|
|||
* @param flags: host order flags word, with opcode and CD bit.
|
||||
* @param dnssec: if set, EDNS record will have DO bit set.
|
||||
* @param want_dnssec: signatures needed.
|
||||
* @param nocaps: ignore capsforid(if in config), do not perturb qname.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: wireformat dname of the zone.
|
||||
|
|
@ -121,8 +124,9 @@ void worker_sighandler(int sig, void* arg);
|
|||
*/
|
||||
struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, struct module_qstate* q);
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* process control messages from the main thread. Frees the control
|
||||
|
|
|
|||
|
|
@ -1206,7 +1206,7 @@ lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
|||
/** Create new serviced entry */
|
||||
static struct serviced_query*
|
||||
serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
||||
int want_dnssec, int tcp_upstream, int ssl_upstream,
|
||||
int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, int qtype)
|
||||
{
|
||||
|
|
@ -1233,6 +1233,7 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
|||
sq->qtype = qtype;
|
||||
sq->dnssec = dnssec;
|
||||
sq->want_dnssec = want_dnssec;
|
||||
sq->nocaps = nocaps;
|
||||
sq->tcp_upstream = tcp_upstream;
|
||||
sq->ssl_upstream = ssl_upstream;
|
||||
memcpy(&sq->addr, addr, addrlen);
|
||||
|
|
@ -1350,7 +1351,7 @@ static void
|
|||
serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns)
|
||||
{
|
||||
/* if we are using 0x20 bits for ID randomness, perturb them */
|
||||
if(sq->outnet->use_caps_for_id) {
|
||||
if(sq->outnet->use_caps_for_id && !sq->nocaps) {
|
||||
serviced_perturb_qname(sq->outnet->rnd, sq->qbuf, sq->qbuflen);
|
||||
}
|
||||
/* generate query */
|
||||
|
|
@ -1828,10 +1829,11 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
|||
struct serviced_query*
|
||||
outnet_serviced_query(struct outside_network* outnet,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
|
||||
int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, comm_point_callback_t* callback,
|
||||
void* callback_arg, sldns_buffer* buff)
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
int tcp_upstream, int ssl_upstream, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
sldns_buffer* buff)
|
||||
{
|
||||
struct serviced_query* sq;
|
||||
struct service_callback* cb;
|
||||
|
|
@ -1844,7 +1846,7 @@ outnet_serviced_query(struct outside_network* outnet,
|
|||
return NULL;
|
||||
if(!sq) {
|
||||
/* make new serviced query entry */
|
||||
sq = serviced_create(outnet, buff, dnssec, want_dnssec,
|
||||
sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
|
||||
tcp_upstream, ssl_upstream, addr, addrlen, zone,
|
||||
zonelen, (int)qtype);
|
||||
if(!sq) {
|
||||
|
|
|
|||
|
|
@ -309,6 +309,8 @@ struct serviced_query {
|
|||
int dnssec;
|
||||
/** We want signatures, or else the answer is likely useless */
|
||||
int want_dnssec;
|
||||
/** ignore capsforid */
|
||||
int nocaps;
|
||||
/** tcp upstream used, use tcp, or ssl_upstream for SSL */
|
||||
int tcp_upstream, ssl_upstream;
|
||||
/** where to send it */
|
||||
|
|
@ -466,6 +468,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
|||
* If the value includes BIT_DO, DO bit is set when in EDNS queries.
|
||||
* @param want_dnssec: signatures are needed, without EDNS the answer is
|
||||
* likely to be useless.
|
||||
* @param nocaps: ignore use_caps_for_id and use unperturbed qname.
|
||||
* @param tcp_upstream: use TCP for upstream queries.
|
||||
* @param ssl_upstream: use SSL for upstream queries.
|
||||
* @param callback: callback function.
|
||||
|
|
@ -482,10 +485,11 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
|
|||
*/
|
||||
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream,
|
||||
int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen, comm_point_callback_t* callback,
|
||||
void* callback_arg, struct sldns_buffer* buff);
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
int tcp_upstream, int ssl_upstream, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
struct sldns_buffer* buff);
|
||||
|
||||
/**
|
||||
* Remove service query callback.
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ struct outbound_entry* worker_send_query(uint8_t* ATTR_UNUSED(qname),
|
|||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
|
|
@ -135,7 +135,7 @@ struct outbound_entry* libworker_send_query(uint8_t* ATTR_UNUSED(qname),
|
|||
size_t ATTR_UNUSED(qnamelen), uint16_t ATTR_UNUSED(qtype),
|
||||
uint16_t ATTR_UNUSED(qclass), uint16_t ATTR_UNUSED(flags),
|
||||
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
|
||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
|
||||
size_t ATTR_UNUSED(zonelen), struct module_qstate* ATTR_UNUSED(q))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1037,9 +1037,10 @@ pending_tcp_query(struct outside_network* outnet, sldns_buffer* packet,
|
|||
struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int ATTR_UNUSED(want_dnssec),
|
||||
int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
|
||||
size_t zonelen, comm_point_callback_t* callback, void* callback_arg,
|
||||
int ATTR_UNUSED(nocaps), int ATTR_UNUSED(tcp_upstream),
|
||||
int ATTR_UNUSED(ssl_upstream), struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
comm_point_callback_t* callback, void* callback_arg,
|
||||
sldns_buffer* ATTR_UNUSED(buff))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_t fptr)
|
|||
int
|
||||
fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q))
|
||||
|
|
|
|||
|
|
@ -211,7 +211,7 @@ int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_t fptr);
|
|||
*/
|
||||
int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
|
||||
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
|
||||
uint16_t flags, int dnssec, int want_dnssec,
|
||||
uint16_t flags, int dnssec, int want_dnssec, int nocaps,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q));
|
||||
|
|
|
|||
|
|
@ -212,6 +212,8 @@ struct module_env {
|
|||
* If BIT_CD is set, CD bit is set in queries with EDNS records.
|
||||
* @param want_dnssec: if set, the validator wants DNSSEC. Without
|
||||
* EDNS, the answer is likely to be useless for this domain.
|
||||
* @param nocaps: do not use caps_for_id, use the qname as given.
|
||||
* (ignored if caps_for_id is disabled).
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param zone: delegation point name.
|
||||
|
|
@ -224,7 +226,7 @@ struct module_env {
|
|||
*/
|
||||
struct outbound_entry* (*send_query)(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
int want_dnssec, struct sockaddr_storage* addr,
|
||||
int want_dnssec, int nocaps, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, uint8_t* zone, size_t zonelen,
|
||||
struct module_qstate* q);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue