Permalink
Browse files

when receiving a QR=0 "response", try to match it to an outstanding q…

…uery so we can note the error
  • Loading branch information...
1 parent d393c2d commit ee90f02ac6c0d3b2853e07576ad614a4bfc3f01f @Habbie Habbie committed May 23, 2013
Showing with 49 additions and 47 deletions.
  1. +49 −47 pdns/pdns_recursor.cc
View
@@ -1446,63 +1446,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<<Logger::Warning<<"Error in packet from "<< fromaddr.toStringWithPort() << ": "<<e.what() << endl;
- return;
- }
- }
- string packet;
- packet.assign(data, len);
+ PacketID pident;
+ pident.remote=fromaddr;
+ pident.id=dh.id;
+ pident.fd=fd;
- MT_t::waiters_t::iterator iter=MT->d_waiters.find(pident);
- if(iter != MT->d_waiters.end()) {
- doResends(iter, pident, packet);
+ if(!dh.qr) {
+ L<<Logger::Warning<<"Not taking data from question on outgoing socket from "<< fromaddr.toStringWithPort() <<endl;
+ }
+
+ if(!dh.qdcount || // UPC, Nominum, very old BIND on FormErr, NSD
+ !dh.qr) { // one weird server
+ 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<<Logger::Warning<<"Error in packet from "<< fromaddr.toStringWithPort() << ": "<<e.what() << endl;
+ return;
}
+ }
+ string packet;
+ packet.assign(data, len);
- retryWithName:
+ MT_t::waiters_t::iterator iter=MT->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"<<endl;
- pident.domain = mthread->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<<Logger::Warning<<"Discarding unexpected packet from "<<fromaddr.toStringWithPort()<<": "<<pident.domain<<", "<<pident.type<<", "<<MT->d_waiters.size()<<" waiters"<<endl;
+
+ // 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"<<endl;
+ pident.domain = mthread->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<<Logger::Warning<<"Discarding unexpected packet from "<<fromaddr.toStringWithPort()<<": "<<pident.domain<<", "<<pident.type<<", "<<MT->d_waiters.size()<<" waiters"<<endl;
}
}
- else
- L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< fromaddr.toStringWithPort() <<endl;
+ else if(fd >= 0) {
+ t_udpclientsocks->returnSocket(fd);
+ }
}
FDMultiplexer* getMultiplexer()

0 comments on commit ee90f02

Please sign in to comment.