mORMot2 DailyDaily read of upstream commits

DNS gains EDNS, stricter reply validation and IPv6 resolvers

The DNS client now advertises a 1232-byte EDNS UDP payload, falls back when a server returns FORMERR, accepts resolver ports and IPv6 addresses, and validates the echoed question and response source before parsing records. The implementation changed repeatedly across the batch, so DNS users should take the final build rather than an intermediate revision. TCachedValues.Exists is corrected and tested, and DHCP scopes finally emit their configured domain name.

TL;DR

  • Land on 2.4.16805 for the complete DNS series; builds 2.4.16794 through 2.4.16804 contain intermediate cache, EDNS, parsing or validation states.
  • DnsQuery uses EDNS with a 1232-byte default, remembers FORMERR fallback, and validates the response question, type, class, source address and source port.
  • Resolver definitions now accept IPv4 with an inline port and IPv6 addresses; DnsBuildQuestion exposes an optional EDNS payload size.
  • TCachedValues.Exists now selects the correct comparator, and Exists/Add default to a non-expiring cache window.
  • TDhcpState.AddRegularOptions now sends DHCP option 15 from Scope.DomainName, while a per-client rule still takes precedence.

Upgrade advice

DNS users should land on build 2.4.16805 and take the whole series. Do not stop between 2.4.16794 and 2.4.16804: successive commits correct cache expiry, EDNS FORMERR fallback, response positioning, decompression and reply matching. Users of TCachedValues should upgrade from 2.4.16790 to receive the comparator fix. DHCP servers relying on Scope.DomainName should take the final head commit on top of 2.4.16805.

Build2.4.16790 → 2.4.16805
Commits17
Lines+559 -370
Read5 min

16 of 16 entries · 17 commits upstream

Stories
# Entry Category Units
1 High DNS replies must now match the resolver, port and original question DnsSendQuestionRaw accepts IPv4 or IPv6 resolver addresses and rejects UDP replies whose source IP or port differs from the requested endpoint. DnsQuery decompresses and compares the echoed QName, QTYPE and QCLASS before ParseDnsResult, while TDnsHeader.SetZ now writes Flags2 instead of Flags. Security mormot.net.dns a415524a+69-62

net: several DNS fixes

Impact

Malformed, mismatched or misdirected replies are skipped in favor of the next configured resolver instead of being parsed as the requested answer. Applications can also query an IPv6 DNS server directly.

Public API

  • DnsSendQuestionbehaviour-changed — Resolver endpoints may be IPv6, and UDP responses must match both source address and port.
  • DnsQuerybehaviour-changed — A successful reply must echo the requested QName, QTYPE and QCLASS before records are accepted.
  • TDnsHeader.Zbehaviour-changed — The setter now updates the second DNS flags byte where the Z bits are stored.

Arnaud Bouchez · 17:33 UTC · view the commit on GitHub →

2 High DNS decompression rejects cyclic pointer chains and oversized names The internal DnsDecompress routine now tracks the last compression offset, requires each pointer to move backward, rejects reserved pointer forms and enforces the 255-character DNS name limit before copying into a fixed buffer. DnsParseString delegates to this bounded routine. Security mormot.net.dns ae18fe67+53-44

net: hardened DNS decompression logic

Impact

Malformed or hostile DNS packets cannot keep the decompressor in a cyclic chain or overflow its temporary name buffer. Valid backward-compressed names continue to decode.

Public API

  • DnsParseStringbehaviour-changed — Cyclic, forward, reserved, out-of-range and oversized compressed names now fail with a zero result.

Arnaud Bouchez · 15:13 UTC · view the commit on GitHub →

3 High EDNS fallback and record positioning are corrected DnsQuery now falls back to a plain RFC 1035 request only when an EDNS request returns FORMERR, caches that server decision for up to four minutes, and separates record parsing into ParseDnsResult. DnsBuildQuestion temporarily reports the question-body boundary used for parsing. Fixes mormot.net.dns 432444d3+63-52

net: several fixes to EDNS(0) support

Impact

This fixes the initial EDNS branch, which treated non-FORMERR errors as a reason to disable EDNS and did not correctly enter the FORMERR fallback. Later commits replace the temporary body-size assumption, so this build is not a stopping point.

Arnaud Bouchez · 12:40 UTC · view the commit on GitHub →

4 High DNS record parsing starts from the question returned by the server ParseDnsResult derives the first record position by decompressing the QName in the response instead of reusing the locally built request length. DnsQuery requires QuestionCount=1, and TCP accepts a header-sized response rather than requiring more than the header. Fixes mormot.net.dns 3da23281+41-22

net: several DNS fixes

Impact

Responses whose echoed question uses a different valid wire encoding are parsed from their actual boundary. Responses with an unexpected question count are rejected instead of shifting record parsing.

Public API

  • DnsQuerybehaviour-changed — Replies must contain one question, and record parsing follows the returned question encoding.

Arnaud Bouchez · 13:52 UTC · view the commit on GitHub →

5 High TCachedValues lookup now uses the comparator that sorted the cache TCachedValues.Exists reverses the incorrect comparison branches: a configured CustomCompare is passed to the matching FastFindPUtf8CharSorted overload, while nil selects the default overload. Exists and Add also gain TixShr=0 defaults, and zero now means no periodic flush. Fixes mormot.core.unicode 256cc2f4+13-11

core: fixed TCachedValues

Impact

The public cache added in 2.4.16790 can now find values with both the default and a custom comparator. Existing experimental users should replace the defective build before relying on Exists or duplicate suppression.

Public API

  • TCachedValues.Existsbehaviour-changed — Lookup now uses CustomCompare when assigned and the default comparator otherwise; TixShr defaults to zero.
  • TCachedValues.Addsignature-changed — TixShr becomes optional with a zero default, representing a non-expiring cache.

Arnaud Bouchez · 08:04 UTC · view the commit on GitHub →

6 High DnsQuery enables 1232-byte EDNS and fixes the default DNS port DnsQuery first sends an OPT-enabled question using the new global DnsEdnsUdpSize, defaulting to 1232 bytes and bounded to the 4KB receive buffer. DnsSendQuestionRaw changes its empty-Port fallback from 389 to 53, and DnsQuery changes Res from out to var so it can finalize managed fields before reuse. New features mormot.net.dns fb1b5127+81-38

net: implemented EDNS(0) advertised UDP payload size

Impact

Most DNS answers up to 1232 bytes can remain on UDP, reducing TCP fallback. Direct DnsSendQuestion calls with an empty Port now target the correct DNS service, but the initial EDNS fallback logic is corrected by the next commit.

Public API

  • DnsEdnsUdpSizeadded — Public global controlling the advertised EDNS UDP payload; default 1232, zero disables EDNS, and values are bounded to 512..4096.
  • DnsQuerysignature-changed — The TDnsResult parameter changes from out to var; ordinary variable calls keep the same syntax.

Arnaud Bouchez · 11:26 UTC · view the commit on GitHub →

7 Medium DHCP scopes now send their configured domain name TDhcpState.AddRegularOptions in mormot.net.dhcp now calls AddOptionOnceU for doDomainName using Scope.DomainName. Tests cover the scope value and confirm that a requested domain-name supplied by a per-client rule is emitted first and therefore keeps precedence. Fixes mormot.net.dhcp 3ad9e8c1+29-0

net: DHCP server was never sending the domain-name option 15

Impact

Clients receiving leases from TDhcpServer can now obtain DHCP option 15 from the scope configuration. Existing per-client domain-name overrides keep their behavior.

zen010101 · 17:43 UTC · view the commit on GitHub →

8 Medium Resolver entries may carry their own port DnsSendQuestionRaw parses a single colon in Address as an inline IPv4 port, overriding the separate Port argument before TNetAddr setup. The tcp@ prefix is removed before this parsing, and cache keys use the stripped address. New features mormot.net.dns c6756d1e+17-12

dns: allow 'ip:port' for DNS servers definitions

Impact

NameServers can target resolvers such as 127.0.0.1:5353 without changing the global DnsPort. Multiple-colon IPv6 literals are not mistaken for this inline-port syntax.

Worth a look

Review custom resolver configuration if it currently carries a separate port; it may now be expressed per NameServers entry.

Public API

  • DnsSendQuestionbehaviour-changed — Address accepts an IPv4 address with an inline :port value.

Arnaud Bouchez · 13:07 UTC · view the commit on GitHub →

9 Medium DnsBuildQuestion can append an EDNS OPT record DnsBuildQuestion gains an optional EdnsUdpSize parameter. A nonzero value adds one OPT pseudo-record, sets AdditionalCount, clamps the advertised UDP size to 512..4096, and emits zero extended RCODE, version, flags and option data. New features mormot.net.dns cd234840+18-5

net: optional EDNS(0) support for DnsBuildQuestion()

Impact

Low-level callers can construct standards-shaped EDNS questions without assembling the OPT record themselves. Existing three-argument calls keep classic DNS behavior because the new parameter defaults to zero.

Worth a look

Review custom DnsBuildQuestion callers that want larger UDP replies; set EdnsUdpSize explicitly and take the later DNS fixes.

Public API

  • DnsBuildQuestionsignature-changed — Adds optional EdnsUdpSize: cardinal = 0 and emits an OPT pseudo-record when nonzero.

Arnaud Bouchez · 09:08 UTC · view the commit on GitHub →

10 Medium DNS transport accepts raw replies before applying query policy The transport implementation becomes DnsSendQuestionRaw, which accepts structurally valid UDP or TCP replies regardless of RCODE or answer count. The public DnsSendQuestion wrapper retains the old success policy, while the no-TCP cache insertion now uses the same TixShr=6 period as lookup. Under the hood mormot.net.dns f1b7dcaf+25-20

net: fixed and refactored DnsSendQuestion()

Impact

Higher-level DnsQuery can inspect FORMERR and implement EDNS fallback without weakening the public raw-query contract. The one-minute suppression of servers that fail TCP becomes effective again.

Arnaud Bouchez · 09:29 UTC · view the commit on GitHub →

11 Medium DNS adopts the shared cache wrapper for failed TCP resolvers The bespoke NoTcpSafe, NoTcpTix16 and NoTcpServers storage is replaced by TCachedValues. TCachedValue and TCachedValues also treat TixShr=0 as a non-expiring period and document that their record storage must start zero-filled. Under the hood mormot.core.os+3 e8fd8b73+14-21

net: some DNS code simplification

Impact

The intended behavior remains a 64-second cache of resolvers that do not answer over TCP. This commit inserts with the new default TixShr=0 while lookup uses 6, so the cache is ineffective until the following DnsSendQuestion refactor passes 6 to Add.

Public API

  • TCachedValue.Cachebehaviour-changed — TixShr=0 now selects a stable non-expiring cache period instead of deriving a tick value.

Arnaud Bouchez · 08:36 UTC · view the commit on GitHub →

12 Low Intel and AMD search assembly reduces register and move pressure Several x86 and x64 scan/search routines emit -1 with or instead of mov. The x64 FastFindPUtf8CharSorted implementation is reorganized to avoid r12/r13 saves, cache the first byte and compare subsequent bytes with indexed addressing. Performance mormot.core.base+1 1daae163+54-52

core: optimized Intel/AMD asm

Impact

Common scans and sorted RawUtf8 lookup use fewer instructions or saved registers on Intel/AMD targets. Public behavior and return values remain unchanged.

Arnaud Bouchez · 08:03 UTC · view the commit on GitHub →

13 Low The 16-bit byte swap emits simpler FPC code bswap16 in mormot.core.base now takes its cardinal argument by value and computes the low byte through ToByte before shifting and combining it with the high byte. The function remains inline where supported. Performance mormot.core.base e00798bb+6-5

core: optimized bswap16() function

Impact

FPC can generate a shorter sequence for a very common endian conversion. Results remain the same for existing callers.

Public API

  • bswap16signature-changed — The scalar parameter changes from const cardinal to cardinal; normal calls remain source-compatible.

Arnaud Bouchez · 17:31 UTC · view the commit on GitHub →

14 Low Linux ARP lookup uses explicit wire-order constants GetRemoteMacAddress in mormot.net.sock.posix.inc replaces repeated bswap16 calls with ETH_P_IP_LE, ETH_P_ARP_LE and shifted ARP constants when building and checking raw Ethernet frames. TRawARP is normalized to TRawArp inside the implementation include. Under the hood mormot.net.sock 3b7a2a4f+17-15

net: refactored GetRemoteMacAddress() on Linux

Impact

Linux remote-MAC discovery keeps the same packet layout and privilege requirements. The change removes runtime byte swaps from this low-level path without changing application calls.

Arnaud Bouchez · 17:33 UTC · view the commit on GitHub →

15 Low TFTP frame opcodes are written directly in wire order TTftpContext replaces bswap16 calls with constant shifts when writing OACK, ACK, DAT and ERR opcodes. Sequence and error-code fields retain their existing conversion logic. Under the hood mormot.net.tftp.client eee50161+6-6

net: minor TFTP logic refactoring

Impact

Generated TFTP frames are unchanged; this is a small internal simplification with no API or protocol migration.

Arnaud Bouchez · 17:31 UTC · view the commit on GitHub →

16 Low The cache repair receives direct add, lookup and reset coverage test.core.base initializes TCachedValues and verifies missing lookups, unique insertion, duplicate rejection, successful lookup and Reset. The PDF font test accepts one additional known platform-dependent hash. Tests test.core.base+1 816a0e19+24-5

tests: enhanced coverage

Impact

Production code is unchanged. The tests guard the default-comparator defect fixed in the preceding commit and broaden accepted PDF rendering variance.

Arnaud Bouchez · 08:04 UTC · view the commit on GitHub →

Upstream activity commits per day · last 60 days
Commits977
Active days44/60
Busiest2026-09-30
Peak60
2026-08-15: 0 commits2026-08-16: 0 commits2026-08-17: 0 commits2026-08-18: 0 commits2026-08-19: 0 commits2026-08-20: 0 commits2026-08-21: 0 commits2026-08-22: 0 commits2026-08-23: 0 commits2026-08-24: 0 commits2026-08-25: 0 commits2026-08-26: 0 commits2026-08-27: 26 commits2026-08-28: 11 commits2026-08-29: 10 commits2026-08-30: 1 commit2026-08-31: 23 commits2026-09-01: 0 commits2026-09-02: 20 commits2026-09-03: 29 commits2026-09-04: 35 commits2026-09-05: 13 commits2026-09-06: 0 commits2026-09-07: 0 commits2026-09-08: 23 commits2026-09-09: 10 commits2026-09-10: 17 commits2026-09-11: 23 commits2026-09-12: 14 commits2026-09-13: 9 commits2026-09-14: 7 commits2026-09-15: 4 commits2026-09-16: 24 commits2026-09-17: 26 commits2026-09-18: 21 commits2026-09-19: 59 commits2026-09-20: 13 commits2026-09-21: 5 commits2026-09-22: 34 commits2026-09-23: 17 commits2026-09-24: 57 commits2026-09-25: 22 commits2026-09-26: 26 commits2026-09-27: 0 commits2026-09-28: 2 commits2026-09-29: 19 commits2026-09-30: 60 commits2026-10-01: 26 commits2026-10-02: 30 commits2026-10-03: 32 commits2026-10-04: 15 commits2026-10-05: 1 commit2026-10-06: 26 commits2026-10-07: 37 commits2026-10-08: 27 commits2026-10-09: 35 commits2026-10-10: 33 commits2026-10-11: 9 commits2026-10-12: 11 commits2026-10-13: 35 commits
2026-08-152026-10-13