return false;
}
+ memcpy(response, &queryId, sizeof(queryId));
+ memcpy(response + sizeof(queryId), value.value.c_str() + sizeof(queryId), sizeof(dnsheader) - sizeof(queryId));
+
+ if (value.len == sizeof(dnsheader)) {
+ /* DNS header only, our work here is done */
+ *responseLen = value.len;
+ d_hits++;
+ return true;
+ }
+
string dnsQName(dq.qname->toDNSString());
const size_t dnsQNameLen = dnsQName.length();
if (value.len < (sizeof(dnsheader) + dnsQNameLen)) {
return false;
}
- memcpy(response, &queryId, sizeof(queryId));
- memcpy(response + sizeof(queryId), value.value.c_str() + sizeof(queryId), sizeof(dnsheader) - sizeof(queryId));
memcpy(response + sizeof(dnsheader), dnsQName.c_str(), dnsQNameLen);
if (value.len > (sizeof(dnsheader) + dnsQNameLen)) {
memcpy(response + sizeof(dnsheader) + dnsQNameLen, value.value.c_str() + sizeof(dnsheader) + dnsQNameLen, value.len - (sizeof(dnsheader) + dnsQNameLen));
return false;
}
+ if (dh->qdcount == 0) {
+ if (dh->rcode != RCode::NoError && dh->rcode != RCode::NXDomain) {
+ return true;
+ }
+ else {
+ g_stats.nonCompliantResponses++;
+ return false;
+ }
+ }
+
try {
rqname=DNSName(response, responseLen, sizeof(dnsheader), false, &rqtype, &rqclass, &consumed);
}
return false;
}
+ restoreFlags(dh, origFlags);
+
+ if (*responseLen == sizeof(dnsheader)) {
+ return true;
+ }
+
if(g_fixupCase) {
string realname = qname.toDNSString();
if (*responseLen >= (sizeof(dnsheader) + realname.length())) {
}
}
- restoreFlags(dh, origFlags);
-
if (ednsAdded || ecsAdded) {
char * optStart = NULL;
size_t optLen = 0;
receivedQuery.id = query.id
self.assertEquals(query, receivedQuery)
+ def testHeaderOnlyRefused(self):
+ """
+ Basics: Header-only refused response
+ """
+ name = 'header-only-refused-response.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ response = dns.message.make_response(query)
+ response.set_rcode(dns.rcode.REFUSED)
+ response.question = []
+
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
+
+ (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, response)
+
+ def testHeaderOnlyNoErrorResponse(self):
+ """
+ Basics: Header-only NoError response should be dropped
+ """
+ name = 'header-only-noerror-response.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ response = dns.message.make_response(query)
+ response.question = []
+
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, None)
+
+ (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, None)
+
+ def testHeaderOnlyNXDResponse(self):
+ """
+ Basics: Header-only NXD response should be dropped
+ """
+ name = 'header-only-nxd-response.tests.powerdns.com.'
+ query = dns.message.make_query(name, 'A', 'IN')
+ response = dns.message.make_response(query)
+ response.set_rcode(dns.rcode.NXDOMAIN)
+ response.question = []
+
+ (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, None)
+
+ (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response)
+ self.assertTrue(receivedQuery)
+ receivedQuery.id = query.id
+ self.assertEquals(query, receivedQuery)
+ self.assertEquals(receivedResponse, None)
+
if __name__ == '__main__':
unittest.main()