During my recent DNS protocol experiments, I encountered an interesting behavior when attempting to query multiple record types simultaneously. While separate DNS packets for A and MX records work perfectly (returning both IP addresses and mail exchange data respectively), combining them in a single packet's question section yields only the A-record response.
The DNS protocol (RFC 1035) technically supports multiple questions in a single query packet. However, most DNS implementations handle this scenario differently:
// Sample DNS query structure with multiple questions
dns_query = {
header: {
id: 0x1234,
flags: 0x0100, // Standard query
qdcount: 2, // Two questions
ancount: 0,
nscount: 0,
arcount: 0
},
questions: [
{ qname: "test.com", qtype: "A", qclass: "IN" },
{ qname: "test.com", qtype: "MX", qclass: "IN" }
]
}
Several factors contribute to this behavior:
- Server Configuration: Many DNS servers implement response filtering for performance and security reasons
- Protocol Interpretation: Some implementations treat multi-question packets as malformed
- Cache Optimization:
Servers often prioritize A-records as the most commonly requested type
For reliable multi-record queries, consider these approaches:
# Using dig with multiple separate queries
dig test.com A +noall +answer
dig test.com MX +noall +answer
# Alternative: Use a DNS library with proper multi-query handling
const dns = require('dns');
dns.resolve('test.com', 'A', (err, addresses) => { ... });
dns.resolve('test.com', 'MX', (err, exchanges) => { ... });
Some specialized DNS servers (particularly authoritative servers) may properly handle multi-question packets. Test with:
# Using dig with multiple questions
dig test.com A MX +noall +answer
When working with raw DNS protocol implementation, I discovered an interesting behavior: A properly formatted DNS packet containing multiple record queries in its Question section often receives incomplete responses. For example, when querying both A and MX records for "example.com" in a single request, most DNS servers only respond with A records.
The RFC 1035 specification for DNS doesn't explicitly prohibit multiple questions in a single query, but section 4.1.2 states: "the question section contains QDCOUNT (usually 1) entries". This suggests that while technically possible, multi-question DNS packets aren't the expected standard implementation.
// Sample DNS query structure with multiple questions
typedef struct {
uint16_t id;
uint16_t flags;
uint16_t qdcount; // Typically set to 2 for dual queries
uint16_t ancount;
uint16_t nscount;
uint16_t arcount;
// Question 1: A record query
unsigned char qname1[];
uint16_t qtype1;
uint16_t qclass1;
// Question 2: MX record query
unsigned char qname2[];
uint16_t qtype2;
uint16_t qclass2;
} dns_query_t;
Most DNS server implementations (BIND, PowerDNS, etc.) handle multi-question packets in one of three ways:
- Return only the first question's answer (common with A records)
- Return SERVFAIL (RFC 2136 compliant)
- Process all questions but with potential performance impacts
For reliable multi-record queries, consider these approaches:
// Using dig for parallel queries (Unix systems)
dig example.com A +noall +answer & dig example.com MX +noall +answer
// Python solution using dnspython
import dns.resolver
answers = dns.resolver.resolve('example.com', 'A')
mx_answers = dns.resolver.resolve('example.com', 'MX')
While combining queries seems efficient, DNS servers optimize for UDP packet size (typically 512 bytes). Multiple questions may:
- Trigger TCP fallback due to larger size
- Increase server CPU load for parallel processing
- Violate common client implementations
Modern extensions like DNS over HTTPS (DoH) and DNS over TLS (DoT) maintain similar behavior. The emerging EDNS(0) standard could potentially support proper multi-question handling, but current implementations remain conservative.