A. Schulze:
Last week I had an issue with a domain I could analyse in detail.
The external customer run a Debian Squeeze + bind 9.7.3 for his
domain and rDNS
The rDNS was broken because we sent queries for *.In.ADr.ArpA.
The Debian servers was "protected" by a Cisco firewall.
This device had a "content inspection" for DNS enabled which broke
his bind9 answers.
Unfortunately the latest 0x20 patches for unbound-1.4.22 did not catch that.
@Wouter, if you'r interested I could setup a test environment...
today we hit a powerdns server responding in a unexpected manner:
$ dig @ns1.ipandmore.de MAIL1.IPANDMORE.DE +norecurse +noall +answer
; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @ns1.ipandmore.de
MAIL1.IPANDMORE.DE +norecurse +noall +answer
; (1 server found)
;; global options: +cmd
MAIL1.IPANDMORE.DE. 14400 IN A 213.252.2.157
-> OK
$ dig @ns1.ipandmore.de 157.2.252.213.in-addr.arpa. PTR +norecurse
+noall +answer
; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @ns1.ipandmore.de
157.2.252.213.in-addr.arpa. PTR +norecurse +noall +answer
; (1 server found)
;; global options: +cmd
157.2.252.213.in-addr.arpa. 900 IN PTR mail1.ipandmore.de.
-> OK
BUT:
$ dig @ns1.ipandmore.de 157.2.252.213.IN-ADDR.ARPA. PTR +norecurse
+noall +answer
; <<>> DiG 9.8.4-rpz2+rl005.12-P1 <<>> @ns1.ipandmore.de
157.2.252.213.IN-ADDR.ARPA. PTR +norecurse +noall +answer
; (1 server found)
;; global options: +cmd
157.2.252.213.in-addr.arpa. 900 IN PTR mail1.ipandmore.de.
-> OK?, notice the lowercase "in-addr.arpa." in the answer.
We had a similar issue in June:
http://unbound.net/pipermail/unbound-users/2014-June/003377.html
Wouter wrote a patch I'm using here to handle the situation where DNS
servers don't answer
to uppercase queries at all. But that mechanism fail here because
there is no timeout.
I run 1.4.22 with the attached patch.
Ideas / Updates?
Andreas
Index: unbound-1.4.22/daemon/worker.c
===================================================================
--- unbound-1.4.22.orig/daemon/worker.c 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/daemon/worker.c 2014-06-26 07:35:47.000000000 +0200
@@ -1291,8 +1291,8 @@
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(
@@ -1301,7 +1301,7 @@
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);
@@ -1347,7 +1347,7 @@
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), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
Index: unbound-1.4.22/daemon/worker.h
===================================================================
--- unbound-1.4.22.orig/daemon/worker.h 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/daemon/worker.h 2014-06-26 07:35:09.000000000 +0200
@@ -173,6 +173,7 @@
* @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: do not use capsforid.
* @param addr: where to.
* @param addrlen: length of addr.
* @param zone: wireformat dname of the zone.
@@ -183,8 +184,9 @@
*/
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
Index: unbound-1.4.22/iterator/iterator.c
===================================================================
--- unbound-1.4.22.orig/iterator/iterator.c 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/iterator/iterator.c 2014-06-26 07:35:09.000000000 +0200
@@ -1846,8 +1846,8 @@
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);
@@ -2757,6 +2757,21 @@
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)
@@ -2805,7 +2820,7 @@
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;
@@ -2817,7 +2832,11 @@
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");
Index: unbound-1.4.22/iterator/iterator.h
===================================================================
--- unbound-1.4.22.orig/iterator/iterator.h 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/iterator/iterator.h 2014-06-26 07:35:09.000000000 +0200
@@ -234,7 +234,8 @@
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 */
Index: unbound-1.4.22/libunbound/libworker.c
===================================================================
--- unbound-1.4.22.orig/libunbound/libworker.c 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/libunbound/libworker.c 2014-06-26 07:35:39.000000000 +0200
@@ -819,8 +819,9 @@
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(
@@ -829,7 +830,7 @@
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);
@@ -951,7 +952,7 @@
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), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
Index: unbound-1.4.22/libunbound/libworker.h
===================================================================
--- unbound-1.4.22.orig/libunbound/libworker.h 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/libunbound/libworker.h 2014-06-26 07:35:09.000000000 +0200
@@ -145,6 +145,7 @@
* @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.
@@ -155,8 +156,9 @@
*/
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,
Index: unbound-1.4.22/services/outside_network.c
===================================================================
--- unbound-1.4.22.orig/services/outside_network.c 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/services/outside_network.c 2014-06-26 07:35:09.000000000 +0200
@@ -1205,7 +1205,7 @@
/** 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)
{
@@ -1232,6 +1232,7 @@
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);
@@ -1349,7 +1350,7 @@
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 */
@@ -1827,10 +1828,11 @@
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;
@@ -1843,7 +1845,7 @@
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) {
Index: unbound-1.4.22/services/outside_network.h
===================================================================
--- unbound-1.4.22.orig/services/outside_network.h 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/services/outside_network.h 2014-06-26 07:35:09.000000000 +0200
@@ -307,6 +307,8 @@
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 */
@@ -464,6 +466,7 @@
* 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.
@@ -480,10 +483,11 @@
*/
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.
Index: unbound-1.4.22/smallapp/worker_cb.c
===================================================================
--- unbound-1.4.22.orig/smallapp/worker_cb.c 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/smallapp/worker_cb.c 2014-06-26 07:35:29.000000000 +0200
@@ -104,7 +104,7 @@
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), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
@@ -135,7 +135,7 @@
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), struct module_qstate* ATTR_UNUSED(q))
{
log_assert(0);
Index: unbound-1.4.22/testcode/fake_event.c
===================================================================
--- unbound-1.4.22.orig/testcode/fake_event.c 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/testcode/fake_event.c 2014-06-26 07:35:09.000000000 +0200
@@ -1037,9 +1037,10 @@
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;
Index: unbound-1.4.22/util/fptr_wlist.c
===================================================================
--- unbound-1.4.22.orig/util/fptr_wlist.c 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/util/fptr_wlist.c 2014-06-26 07:35:09.000000000 +0200
@@ -259,7 +259,7 @@
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))
Index: unbound-1.4.22/util/fptr_wlist.h
===================================================================
--- unbound-1.4.22.orig/util/fptr_wlist.h 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/util/fptr_wlist.h 2014-06-26 07:35:09.000000000 +0200
@@ -211,7 +211,7 @@
*/
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));
Index: unbound-1.4.22/util/module.h
===================================================================
--- unbound-1.4.22.orig/util/module.h 2014-06-26 07:33:09.000000000 +0200
+++ unbound-1.4.22/util/module.h 2014-06-26 07:35:56.000000000 +0200
@@ -212,6 +212,8 @@
* 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 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);
_______________________________________________
Unbound-users mailing list
[email protected]
http://unbound.nlnetlabs.nl/mailman/listinfo/unbound-users