Skip to content

dns improvements#2989

Merged
floitsch merged 11 commits intomasterfrom
CL/dns-impr
Mar 21, 2026
Merged

dns improvements#2989
floitsch merged 11 commits intomasterfrom
CL/dns-impr

Conversation

@close2
Copy link
Copy Markdown
Collaborator

@close2 close2 commented Feb 1, 2026

depends on PR #2988

Refactor DnsClient to be an interface. Rename the get_ method and remove the version, which only accepts a single type.

@close2 close2 requested a review from floitsch February 1, 2026 15:22
@floitsch floitsch changed the base branch from master to CL/implement_mdns_one_shot February 8, 2026 12:28
Copy link
Copy Markdown
Member

@floitsch floitsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Comment thread lib/net/modules/dns.toit
Comment thread lib/net/modules/dns.toit Outdated
Comment thread lib/net/modules/dns.toit Outdated
Comment thread lib/net/modules/dns.toit Outdated
Comment thread lib/net/modules/dns.toit Outdated
Comment thread tests/dns_packet_test.toit Outdated
Comment thread tests/dns_packet_test.toit Outdated
Comment thread tests/dns_packet_test.toit Outdated
Comment thread tests/dns_packet_test.toit Outdated
Comment thread lib/net/modules/dns.toit Outdated
Base automatically changed from CL/implement_mdns_one_shot to master February 14, 2026 14:46
@close2 close2 force-pushed the CL/dns-impr branch 2 times, most recently from 7ca111a to b5d9960 Compare March 20, 2026 23:04
Copy link
Copy Markdown
Member

@floitsch floitsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@floitsch
Copy link
Copy Markdown
Member

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 21, 2026

Walkthrough

The PR refactors the DNS client API to accept a list of record types instead of a single type, converts DnsClient from an abstract class to an interface with a new DnsClientBase_ implementation, expands DNS packet encoding/decoding to support authorities and additionals sections, introduces a new TxtResource class, and updates all tests accordingly.

Changes

Cohort / File(s) Summary
DNS Module Refactoring
lib/net/modules/dns.toit
Converted DnsClient to interface; introduced DnsClientBase_ abstract class with shared cache and fast-path logic. Updated get method signature from --record-type/int to --record-types/List. Refactored type handling throughout. Added support for DNS packet authorities and additionals sections with new decode-resource_ and write-resource_ helpers. Introduced TxtResource class with text list support. Modified create-dns-packet signature to accept --authorities and --additionals parameters.
DNS API Test Updates
tests/dns-tools-test.toit, tests/dns_cache_retry_test.toit, tests/dns_mdns_test.toit, tests/dns_packet_test.toit
Updated DNS client method calls from --record-type= to --record-types=[...] across multiple test files. Added new test case test-additional-section in dns_packet_test.toit to validate authorities and additionals section encoding/decoding with assertion checks.
UDP Resource Whitespace Cleanup
src/resources/udp_esp32.cc, src/resources/udp_win.cc
Removed blank lines in switch statement cases without functional changes to control flow or logic.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • #2986: Modifies DNS packet encoding/decoding and resource handling in the same module, including TXT/SRV rdata processing and related helper functions.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'dns improvements' is vague and generic, using non-descriptive terms that don't convey specific information about the main changes (interface refactoring, API changes, packet decoding expansion). Use a more specific title like 'Refactor DnsClient to interface and expand packet parsing' to clearly describe the main changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description is related to the changeset, mentioning the interface refactoring and method rename, which are key aspects of the changes shown in the raw summary.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch CL/dns-impr

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can customize the high-level summary generated by CodeRabbit.

Configure the reviews.high_level_summary_instructions setting to provide custom instructions for generating the high-level summary.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
lib/net/modules/dns.toit (3)

821-826: Asymmetry between TXT encoding and decoding.

TxtResource is used for encoding multi-string TXT records (see write-resource_ at lines 922-929), but decode-resource_ (line 692) creates StringResource for decoded TXT records. This asymmetry means:

  • Encoding: supports both TxtResource (multi-string) and StringResource (single string)
  • Decoding: always produces StringResource (single string only)

If round-trip consistency is needed, consider decoding TXT records as TxtResource when multiple character-strings are present.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/net/modules/dns.toit` around lines 821 - 826, The decode-resource_ path
currently converts TXT (RECORD-TXT) records into StringResource even though
write-resource_ supports TxtResource (multi-string) and StringResource; update
decode-resource_ so that when parsing RECORD-TXT it constructs TxtResource when
the rdata contains multiple character-strings (and only use StringResource for
single-string cases), ensuring round-trip symmetry between TxtResource,
StringResource, write-resource_, and decode-resource_.

271-274: Redundant cache initialization.

The cache_ field is initialized twice: once at declaration (line 271) and again in the constructor (line 274). The field initializer ::= Map already creates the Map instance.

♻️ Suggested simplification
 abstract class DnsClientBase_ implements DnsClient:
   cache_ ::= Map  // From numeric q-type to (Map name to CacheEntry_).
 
   constructor:
-    cache_ = Map
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/net/modules/dns.toit` around lines 271 - 274, The cache_ field is being
double-initialized: it already has a field initializer "cache_ ::= Map" and the
constructor also reassigns cache_ = Map; remove the redundant assignment in the
constructor (leave the field initializer) or alternatively remove the field
initializer and only initialize inside the constructor—pick one approach and
keep only a single initialization for cache_ (used to store per q-type Map of
name→CacheEntry_) to avoid unnecessary reassignment.

678-692: TXT record decoding only reads the first character-string.

The current implementation reads only the first <length><data> segment of a TXT record. Per RFC 1035, TXT records can contain multiple character-strings. If a TXT record has multiple strings (e.g., rd-length=12 with two 5-byte strings), only the first is decoded and the rest are skipped by the to-skip logic.

This may be intentional for simplicity, but consider whether multi-string TXT records need full support. If so, the loop should consume all character-strings within rd-length.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/net/modules/dns.toit` around lines 678 - 692, The TXT-record branch
(RECORD-TXT) only reads one <character-string> using a single
reader.read-byte/read-string and leaves remaining bytes unparsed; change it to
loop while rd-length > 0 reading a length octet, validate rd-length >= length+1
each iteration, read that many bytes with reader.read-string and append each
string (or collect into a list and join as desired) into the value for the
StringResource r-name type ttl flush value, and ensure you decrement/track the
consumed bytes so the loop exits when the entire rd-length is consumed; preserve
the existing protocol-error_ check for invalid lengths.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/net/modules/dns.toit`:
- Around line 922-929: The TxtResource branch writes each TXT string length as a
single byte without validating per-string size, which can overflow since
write-byte accepts only 0-255; update the TxtResource encoding to validate each
string in txt.text (the same way StringResource does) before writing: iterate
txt.text, check s.size <= 255 and raise or return an error if not, then compute
total-len and write each entry using buffer.write-byte s.size and buffer.write
s; ensure the validation occurs prior to buffer-be.write-int16 so total length
isn't computed for invalid entries.

---

Nitpick comments:
In `@lib/net/modules/dns.toit`:
- Around line 821-826: The decode-resource_ path currently converts TXT
(RECORD-TXT) records into StringResource even though write-resource_ supports
TxtResource (multi-string) and StringResource; update decode-resource_ so that
when parsing RECORD-TXT it constructs TxtResource when the rdata contains
multiple character-strings (and only use StringResource for single-string
cases), ensuring round-trip symmetry between TxtResource, StringResource,
write-resource_, and decode-resource_.
- Around line 271-274: The cache_ field is being double-initialized: it already
has a field initializer "cache_ ::= Map" and the constructor also reassigns
cache_ = Map; remove the redundant assignment in the constructor (leave the
field initializer) or alternatively remove the field initializer and only
initialize inside the constructor—pick one approach and keep only a single
initialization for cache_ (used to store per q-type Map of name→CacheEntry_) to
avoid unnecessary reassignment.
- Around line 678-692: The TXT-record branch (RECORD-TXT) only reads one
<character-string> using a single reader.read-byte/read-string and leaves
remaining bytes unparsed; change it to loop while rd-length > 0 reading a length
octet, validate rd-length >= length+1 each iteration, read that many bytes with
reader.read-string and append each string (or collect into a list and join as
desired) into the value for the StringResource r-name type ttl flush value, and
ensure you decrement/track the consumed bytes so the loop exits when the entire
rd-length is consumed; preserve the existing protocol-error_ check for invalid
lengths.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bbe3e3bb-2ddd-4ecf-97db-24a8d583c70c

📥 Commits

Reviewing files that changed from the base of the PR and between e0c42b1 and b609ca0.

📒 Files selected for processing (7)
  • lib/net/modules/dns.toit
  • src/resources/udp_esp32.cc
  • src/resources/udp_win.cc
  • tests/dns-tools-test.toit
  • tests/dns_cache_retry_test.toit
  • tests/dns_mdns_test.toit
  • tests/dns_packet_test.toit
💤 Files with no reviewable changes (2)
  • src/resources/udp_esp32.cc
  • src/resources/udp_win.cc

Comment thread lib/net/modules/dns.toit
Comment on lines +922 to +929
if record is TxtResource:
txt := record as TxtResource
total-len := 0
txt.text.do: | s | total-len += s.size + 1
buffer-be.write-int16 total-len
txt.text.do: | s |
buffer.write-byte s.size
buffer.write s
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing length validation for individual TXT strings in TxtResource.

When encoding StringResource TXT records, there's a 255-byte limit check (line 932). However, TxtResource strings (lines 927-929) are written without validating that each individual string doesn't exceed 255 bytes. Since s.size is written as a single byte, strings longer than 255 bytes would cause truncation or incorrect encoding.

🛡️ Proposed fix to add validation
       if record is TxtResource:
         txt := record as TxtResource
         total-len := 0
-        txt.text.do: | s | total-len += s.size + 1
+        txt.text.do: | s |
+          if s.size > 255: throw (DnsException "TXT character-string cannot exceed 255 bytes" --name=record.name)
+          total-len += s.size + 1
         buffer-be.write-int16 total-len
         txt.text.do: | s |
           buffer.write-byte s.size
           buffer.write s
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lib/net/modules/dns.toit` around lines 922 - 929, The TxtResource branch
writes each TXT string length as a single byte without validating per-string
size, which can overflow since write-byte accepts only 0-255; update the
TxtResource encoding to validate each string in txt.text (the same way
StringResource does) before writing: iterate txt.text, check s.size <= 255 and
raise or return an error if not, then compute total-len and write each entry
using buffer.write-byte s.size and buffer.write s; ensure the validation occurs
prior to buffer-be.write-int16 so total length isn't computed for invalid
entries.

Copy link
Copy Markdown
Member

@floitsch floitsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@floitsch floitsch merged commit ff876a5 into master Mar 21, 2026
36 of 37 checks passed
@floitsch floitsch deleted the CL/dns-impr branch March 21, 2026 17:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants