try {
lwr->d_tcbit = 0;
MOADNSParser mdp(false, reinterpret_cast<const char*>(buf.data()), buf.size());
+
+ // RFC 1035 Section 4.1.1: QR must be 1 for responses
+ if (!mdp.d_header.qr) {
+ lwr->d_rcode = RCode::ServFail;
+ lwr->d_validpacket = false;
+ t_Counters.at(rec::Counter::serverParseError)++;
+ return LWResult::Result::PermanentError;
+ }
+
lwr->d_aabit = mdp.d_header.aa;
lwr->d_tcbit = mdp.d_header.tc;
lwr->d_rcode = mdp.d_header.rcode;
pident->id = dnsheader.id;
pident->fd = fileDesc;
- if (!dnsheader.qr && g_logCommonErrors) {
- g_slogout->info(Logr::Error, "Not taking data from question on outgoing socket", "from", Logging::Loggable(fromaddr));
+ if (!dnsheader.qr) {
+ // RFC 1035 Section 4.1.1: QR=0 means query, not response. Discard.
+ if (g_logCommonErrors) {
+ g_slogout->info(Logr::Error, "Not taking data from question on outgoing socket", "from", Logging::Loggable(fromaddr));
+ }
+ t_Counters.at(rec::Counter::unexpectedCount)++;
+ return;
}
if (dnsheader.qdcount == 0U || // UPC, Nominum, very old BIND on FormErr, NSD