From: Peter van Dijk Date: Thu, 23 May 2013 10:58:29 +0000 (+0200) Subject: when receiving a QR=0 "response", try to match it to an outstanding query so we can... X-Git-Tag: auth-3.3-rc1~17^2~3 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6da3b3ad325a6224807c88e54934b5ce778a4f54;p=pdns when receiving a QR=0 "response", try to match it to an outstanding query so we can note the error --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index f250a2121..a3339921b 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -1447,63 +1447,65 @@ void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var) dnsheader dh; memcpy(&dh, data, sizeof(dh)); - if(dh.qr) { - PacketID pident; - pident.remote=fromaddr; - pident.id=dh.id; - pident.fd=fd; - if(!dh.qdcount) { // UPC, Nominum, very old BIND on FormErr, NSD - pident.domain.clear(); - pident.type = 0; - } - else { - try { - pident.domain=questionExpand(data, len, pident.type); // don't copy this from above - we need to do the actual read - } - catch(std::exception& e) { - g_stats.serverParseError++; // won't be fed to lwres.cc, so we have to increment - L<d_waiters.find(pident); - if(iter != MT->d_waiters.end()) { - doResends(iter, pident, packet); + if(!dh.qr) { + L<d_waiters.find(pident); + if(iter != MT->d_waiters.end()) { + doResends(iter, pident, packet); + } - if(!MT->sendEvent(pident, &packet)) { - // we do a full scan for outstanding queries on unexpected answers. not too bad since we only accept them on the right port number, which is hard enough to guess - for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end(); ++mthread) { - if(pident.fd==mthread->key.fd && mthread->key.remote==pident.remote && mthread->key.type == pident.type && - pdns_iequals(pident.domain, mthread->key.domain)) { - mthread->key.nearMisses++; - } +retryWithName: - // be a bit paranoid here since we're weakening our matching - if(pident.domain.empty() && !mthread->key.domain.empty() && !pident.type && mthread->key.type && - pident.id == mthread->key.id && mthread->key.remote == pident.remote) { - // cerr<<"Empty response, rest matches though, sending to a waiter"<key.domain; - pident.type = mthread->key.type; - goto retryWithName; // note that this only passes on an error, lwres will still reject the packet - } + if(!MT->sendEvent(pident, &packet)) { + // we do a full scan for outstanding queries on unexpected answers. not too bad since we only accept them on the right port number, which is hard enough to guess + for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end(); ++mthread) { + if(pident.fd==mthread->key.fd && mthread->key.remote==pident.remote && mthread->key.type == pident.type && + pdns_iequals(pident.domain, mthread->key.domain)) { + mthread->key.nearMisses++; } - g_stats.unexpectedCount++; // if we made it here, it really is an unexpected answer - if(g_logCommonErrors) { - L<d_waiters.size()<<" waiters"<key.domain.empty() && !pident.type && mthread->key.type && + pident.id == mthread->key.id && mthread->key.remote == pident.remote) { + // cerr<<"Empty response, rest matches though, sending to a waiter"<key.domain; + pident.type = mthread->key.type; + goto retryWithName; // note that this only passes on an error, lwres will still reject the packet } } - else if(fd >= 0) { - t_udpclientsocks->returnSocket(fd); + g_stats.unexpectedCount++; // if we made it here, it really is an unexpected answer + if(g_logCommonErrors) { + L<d_waiters.size()<<" waiters"<= 0) { + t_udpclientsocks->returnSocket(fd); + } } FDMultiplexer* getMultiplexer()