Skip to content

fix: RFC correctness driven updates#124

Merged
msimerson merged 1 commit into
lsongdev:masterfrom
NicTool:fix-h2-to-h5
May 26, 2026
Merged

fix: RFC correctness driven updates#124
msimerson merged 1 commit into
lsongdev:masterfrom
NicTool:fix-h2-to-h5

Conversation

@msimerson
Copy link
Copy Markdown
Collaborator

@msimerson msimerson commented May 26, 2026

📑 Description

  • fix(packet): Name decode rejects pointer cycles (RFC 1035)
  • fix(packet): EDNS exposes extendedRcode/version/doFlag; udpPayloadSize configurable (RFC 6891)
  • fix(packet): Header initializes ancount; AD/CD bits split from Z (RFC 4035)
  • fix(packet): ECS encoder truncates address to ceil(prefix/8) octets, adds IPv6 family (RFC 7871)

✅ Checks

  • My pull request adheres to the code style of this project
  • All the tests have passed

Extra info

RFC 1035 §4.1.4

Packet.Name.decode (packet.js:443–465) follows compression pointers by jumping reader.offset directly. A crafted packet whose pointer chain forms a cycle (pointer → pointer → original) causes unbounded recursion /
infinite loop, which can crash the process or consume 100% CPU.

RFC 6891 §6.1.3, RFC 4035 §3.2.1

The EDNS OPT record TTL field encodes (in order): 8 bits extended RCODE, 8 bits EDNS version, 1 bit DO (DNSSEC OK), 15 bits reserved Z. dns2 always hardcodes ttl: 0 on both encode and decode (packet.js:735, packet.js:743), meaning:

  • The DO bit is never set in outgoing queries. Upstream resolvers will not return DNSSEC records (RRSIG, NSEC, …) unless DO=1 is requested.
  • Extended RCODEs received from upstream (BADVERS=16, BADCOOKIE=23, etc.) are silently lost; callers always see the truncated 4-bit RCODE only.

RFC 1035 §4.1.1 (header field layout)

Packet.Header (packet.js:231–248) initialises qdcount, nscount, and arcount to 0, but ancount is absent. A freshly constructed Packet.Header therefore has header.ancount === undefined. toBuffer
works around this by re-assigning this.header.ancount = this.answers.length, but any code that inspects header.ancount before calling toBuffer will read undefined rather than 0.

RFC 7871 §6 (EDNS Client Subnet option encoding)

Packet.Resource.EDNS.ECS.encode (packet.js:835–844) always writes all four IPv4 address octets regardless of sourcePrefixLength. RFC 7871 §6 says the ADDRESS field must contain only the significant octets:⌈sourcePrefixLength / 8⌉ bytes. Sending extra octets is a spec violation and wastes space.

Additionally the encoder splits record.ip on . (IPv4 only); an IPv6 CIDR (family 2) will produce NaN bytes for each octet.

RFC 4035 §3.2.3

RFC 4035 repurposed the two formerly-zero Z bits in the DNS header as AD (Authentic Data, bit 5) and CD (Checking Disabled, bit 6). dns2 reads all three Z bits as a single z value and provides no separate ad or cd
accessors. Clients cannot set or check these flags independently, making DNSSEC validation signalling impossible.

- fix(packet): Name decode rejects pointer cycles (RFC 1035)
- fix(packet): EDNS exposes extendedRcode/version/doFlag; udpPayloadSize configurable (RFC 6891)
- fix(packet): Header initializes ancount; AD/CD bits split from Z (RFC 4035)
- fix(packet): ECS encoder truncates address to ceil(prefix/8) octets, adds IPv6 family (RFC 7871)
@msimerson msimerson marked this pull request as ready for review May 26, 2026 01:13
@msimerson msimerson merged commit 19f93e4 into lsongdev:master May 26, 2026
5 checks passed
@msimerson msimerson deleted the fix-h2-to-h5 branch May 26, 2026 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant