Skip to content

Commit c8bf4c7

Browse files
committed
Add tests to validate acceptance of non-zero Z bits in DNS header decoding for interoperability
1 parent 2c51e60 commit c8bf4c7

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

tests/unit/DNS/Message/HeaderTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,63 @@ public function testResponseCodeValidation(): void
135135
additionalCount: 0
136136
);
137137
}
138+
139+
/**
140+
* Test that packets with non-zero Z bits are accepted for interoperability.
141+
*
142+
* RFC 1035 says Z bits MUST be zero, but many DNS clients/proxies
143+
* (including Google's infrastructure) set these bits. We intentionally
144+
* ignore them to maximize compatibility.
145+
*/
146+
public function testDecodeAcceptsNonZeroZBits(): void
147+
{
148+
// Flags with Z bits set (bits 4-6):
149+
// QR=1, opcode=0, AA=0, TC=0, RD=1, RA=1, Z=0b111, RCODE=0
150+
// = 1000 0001 1111 0000 = 0x81F0
151+
$flagsWithAllZBits = 0x81F0;
152+
$binaryHeader = pack('nnnnnn', 0x1234, $flagsWithAllZBits, 1, 0, 0, 0);
153+
154+
$decoded = Header::decode($binaryHeader);
155+
156+
// Verify the header is decoded correctly despite Z bits
157+
$this->assertSame(0x1234, $decoded->id);
158+
$this->assertTrue($decoded->isResponse);
159+
$this->assertSame(0, $decoded->opcode);
160+
$this->assertFalse($decoded->authoritative);
161+
$this->assertFalse($decoded->truncated);
162+
$this->assertTrue($decoded->recursionDesired);
163+
$this->assertTrue($decoded->recursionAvailable);
164+
$this->assertSame(0, $decoded->responseCode);
165+
$this->assertSame(1, $decoded->questionCount);
166+
}
167+
168+
/**
169+
* Test various Z bit patterns are all accepted.
170+
*/
171+
public function testDecodeAcceptsVariousZBitPatterns(): void
172+
{
173+
$zBitPatterns = [
174+
0x0010, // Z bit 4 only
175+
0x0020, // Z bit 5 only
176+
0x0040, // Z bit 6 only
177+
0x0030, // Z bits 4 and 5
178+
0x0050, // Z bits 4 and 6
179+
0x0060, // Z bits 5 and 6
180+
0x0070, // All Z bits (4, 5, 6)
181+
];
182+
183+
foreach ($zBitPatterns as $zBits) {
184+
// Base flags: QR=0, opcode=0, AA=0, TC=0, RD=1, RA=0, RCODE=0
185+
// = 0000 0001 0000 0000 = 0x0100
186+
$flags = 0x0100 | $zBits;
187+
$binaryHeader = pack('nnnnnn', 0xABCD, $flags, 1, 0, 0, 0);
188+
189+
$decoded = Header::decode($binaryHeader);
190+
191+
$this->assertSame(0xABCD, $decoded->id, "Failed for Z bits pattern: " . sprintf('0x%04X', $zBits));
192+
$this->assertFalse($decoded->isResponse);
193+
$this->assertTrue($decoded->recursionDesired);
194+
$this->assertSame(0, $decoded->responseCode);
195+
}
196+
}
138197
}

0 commit comments

Comments
 (0)