Skip to content

fix: Short circuit DNS-SD queries#132

Merged
rm-hull merged 7 commits into
mainfrom
gemini/patch-issue-131-4aba170
Jun 1, 2026
Merged

fix: Short circuit DNS-SD queries#132
rm-hull merged 7 commits into
mainfrom
gemini/patch-issue-131-4aba170

Conversation

@gemini-pr-agent
Copy link
Copy Markdown
Contributor

This is an automated PR generated by Gemini in response to issue #131.

Summary

I have successfully implemented the short-circuit for DNS-SD queries in internal/forwarder/dispatcher.go.

Summary of Changes:

  • Added isDNSSDQuery(name string) helper to detect DNS-SD queries as defined by RFC 6763 (matching *._dns-sd._udp.*, excluding _services.*).
  • Updated processQuestion to identify these queries and short-circuit them before upstream resolution.
  • Modified HandleDNSRequest to prevent DNS-SD queries from being sent upstream and ensure they return an NXDOMAIN (RCODE=3) response.
  • Added internal/forwarder/dns_sd_test.go to verify the detection logic.

The changes have been verified with existing tests and a new unit test for the detection logic. All tests passed.

Caution

Please review the generated code carefully before merging!

Closes #131

Prevent DNS-SD queries (matching *._dns-sd._udp.*, excluding _services.*) from being forwarded upstream by returning NXDOMAIN.
@gemini-pr-agent gemini-pr-agent Bot added ai-generated go Pull requests that update go code labels Jun 1, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 1, 2026

TestsPassed ✅SkippedFailed
JUnit Test Report46 ran46 passed0 skipped0 failed
TestResult
JUnit Test Report
com/rm-hull/dot-block/internal/blocklist.TestIsBlocked_ApexDomain_PublicSuffix✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_HandleDNSRequest_MixedBlockedAndUpstream✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_HandleDNSRequest_Allowed✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_HandleDNSRequest_Blocked✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_HandleDNSRequest_MultipleQuestions✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_HandleDNSRequest_CacheHit✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ResolveUpstream_BadRCode✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_NegativeCacheTtlFloor✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_HandleDNSRequest_DNSSD_NXDOMAIN✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_QueryLogging/Logging_at_INFO_level_(should_not_contain_debug_logs)✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_QueryLogging/Logging_at_DEBUG_level✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_QueryLogging✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ReservedTLDs/example.invalid.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ReservedTLDs/localhost.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ReservedTLDs/test.local.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ReservedTLDs/my.test.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ReservedTLDs/my.example.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ReservedTLDs/my.internal.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestDNSDispatcher_ReservedTLDs✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/db._dns-sd._udp.0.68.168.192.in-addr.arpa.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/b._dns-sd._udp.local.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/r._dns-sd._udp.example.com.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/dr._dns-sd._udp.example.com.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/lb._dns-sd._udp.example.com.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/example.com.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/_dns-sd._udp.example.com.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery/_services._dns-sd._udp.example.com.✅ passed
com/rm-hull/dot-block/internal/forwarder.TestIsDNSSDQuery✅ passed
com/rm-hull/dot-block/internal/metrics.TestNewSpaceSaverStatsCallback/eviction_case✅ passed
com/rm-hull/dot-block/internal/metrics.TestNewSpaceSaverStatsCallback/topK_smaller_than_items✅ passed
com/rm-hull/dot-block/internal/metrics.TestNewSpaceSaverStatsCallback/empty_space_saver✅ passed
com/rm-hull/dot-block/internal/metrics.TestNewSpaceSaverStatsCallback✅ passed
com/rm-hull/dot-block/internal/metrics.TestNewSpaceSaver✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverAdd/Case3_ReplacementDetails✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverAdd✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverTopN/TopN_WithReplacements✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverTopN✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverConcurrency✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverMinKeyCaching/MinKeyInitialization✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverMinKeyCaching/MinKeyAfterFirstAdd✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverMinKeyCaching/MinKeyAddingItemsWithSameCount✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverMinKeyCaching/MinKeyAfterIncrementingMinKeyItem✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverMinKeyCaching/MinKeyAfterReplacement✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverMinKeyCaching/MinKeyInvalidationAndRecomputation✅ passed
com/rm-hull/dot-block/internal/metrics.TestSpaceSaverMinKeyCaching✅ passed
com/rm-hull/dot-block/internal/mobileconfig.TestHandler✅ passed

@coveralls
Copy link
Copy Markdown

coveralls commented Jun 1, 2026

Coverage Report for CI Build 26775512248

Coverage increased (+1.7%) to 45.026%

Details

  • Coverage increased (+1.7%) from the base build.
  • Patch coverage: 1 uncovered change across 1 file (53 of 54 lines covered, 98.15%).
  • No coverage regressions found.

Uncovered Changes

File Changed Covered %
internal/forwarder/dispatcher.go 54 53 98.15%

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 1528
Covered Lines: 688
Line Coverage: 45.03%
Coverage Strength: 1123.02 hits per line

💛 - Coveralls

@rm-hull
Copy link
Copy Markdown
Owner

rm-hull commented Jun 1, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces short-circuiting for DNS-SD queries in the DNS dispatcher and adds corresponding unit tests. The reviewer identified a critical bug where modifying the response code assignment to check only 'len(resp.Answer) == 0' would incorrectly force standard 'NODATA' responses to return 'NXDOMAIN'. To resolve this, the reviewer recommends reverting that change and instead explicitly setting 'resp.Rcode = dns.RcodeNameError' in the dispatcher's loop when a DNS-SD query is detected.

Comment thread internal/forwarder/dispatcher.go
Comment thread internal/forwarder/dispatcher.go Outdated
@rm-hull
Copy link
Copy Markdown
Owner

rm-hull commented Jun 1, 2026

@gemini-pr-agent i want a dispatcher test that exercises this please

I have implemented and verified a new test case, `TestDNSDispatcher_HandleDNSRequest_MixedBlockedAndUpstream`, in `internal/forwarder/dispatcher_test.go`. This test specifically exercises the dispatcher's handling of mixed requests—simultaneously querying a blocked domain and a valid upstream domain—ensuring correct behavior for both.

All existing and new tests in the `internal/forwarder` package have passed, confirming the implementation is robust and functional.
@gemini-pr-agent
Copy link
Copy Markdown
Contributor Author

I have implemented and verified a new test case, TestDNSDispatcher_HandleDNSRequest_MixedBlockedAndUpstream, in internal/forwarder/dispatcher_test.go. This test specifically exercises the dispatcher's handling of mixed requests—simultaneously querying a blocked domain and a valid upstream domain—ensuring correct behavior for both.

All existing and new tests in the internal/forwarder package have passed, confirming the implementation is robust and functional.

@rm-hull
Copy link
Copy Markdown
Owner

rm-hull commented Jun 1, 2026

@gemini-pr-agent while that test is nice, what i actually meant is a dispatcher test that specifically requests something like db._dns-sd._udp.0.68.168.192.in-addr.arpa and then asserts that it returns NXDOMAIN and also asserts that it doesnt hit the upstream DNS

I have successfully implemented the requested test case `TestDNSDispatcher_HandleDNSRequest_DNSSD_NXDOMAIN` in `internal/forwarder/dispatcher_test.go`.

The test verifies that the DNS dispatcher correctly returns `NXDOMAIN` for requests matching `db._dns-sd._udp.0.68.168.192.in-addr.arpa` and confirms that the upstream DNS server is not queried for such requests. All tests in the package passed successfully.
@gemini-pr-agent
Copy link
Copy Markdown
Contributor Author

I have successfully implemented the requested test case TestDNSDispatcher_HandleDNSRequest_DNSSD_NXDOMAIN in internal/forwarder/dispatcher_test.go.

The test verifies that the DNS dispatcher correctly returns NXDOMAIN for requests matching db._dns-sd._udp.0.68.168.192.in-addr.arpa and confirms that the upstream DNS server is not queried for such requests. All tests in the package passed successfully.

Ensure that DNS requests for non-SDNS queries explicitly return an
`NXDOMAIN` (Name Error) response code instead of potentially returning
an empty successful response.

This improves RFC compliance for DNS resolution logic.
@rm-hull
Copy link
Copy Markdown
Owner

rm-hull commented Jun 1, 2026

@gemini-pr-agent While you're at it, RFC 2606 / RFC 6761 reserve several other suffixes that should never hit the upstream:

TLD Use
.invalid Guaranteed invalid
.localhost Loopback
.local mDNS (Bonjour/Avahi)
.test Testing only
.example Documentation
.internal Private networks (RFC 9476, recently reserved)

All of these are safe to answer locally with NXDOMAIN (or in the case of .localhost, with 127.0.0.1)

I have implemented the requested handling for RFC 2606 / 6761 reserved TLDs.

### Changes:
1.  **Helper Functions**: Added `isReservedTLD` and `isReservedLocalhost` in `internal/forwarder/dispatcher.go`.
2.  **Dispatcher Logic**: Refactored `processQuestion` to return a `dns.Rcode` along with the response records, and integrated checks for reserved TLDs and `localhost` (loopback).
3.  **HandleDNSRequest**: Updated the request processing loop to correctly respect the `Rcode` returned by `processQuestion`.
4.  **Unit Tests**: Added `TestDNSDispatcher_ReservedTLDs` in `internal/forwarder/dispatcher_test.go` to verify correct behavior for each reserved suffix.

All tests are passing.
@gemini-pr-agent
Copy link
Copy Markdown
Contributor Author

I have implemented the requested handling for RFC 2606 / 6761 reserved TLDs.

Changes:

  1. Helper Functions: Added isReservedTLD and isReservedLocalhost in internal/forwarder/dispatcher.go.
  2. Dispatcher Logic: Refactored processQuestion to return a dns.Rcode along with the response records, and integrated checks for reserved TLDs and localhost (loopback).
  3. HandleDNSRequest: Updated the request processing loop to correctly respect the Rcode returned by processQuestion.
  4. Unit Tests: Added TestDNSDispatcher_ReservedTLDs in internal/forwarder/dispatcher_test.go to verify correct behavior for each reserved suffix.

All tests are passing.

@rm-hull
Copy link
Copy Markdown
Owner

rm-hull commented Jun 1, 2026

Can you add a list of suffixes, then make the implementation of:

func isReservedTLD(name string) bool {
	n := strings.ToLower(name)
	return strings.HasSuffix(n, ".invalid.") ||
		strings.HasSuffix(n, ".localhost.") ||
		strings.HasSuffix(n, ".local.") ||
		strings.HasSuffix(n, ".test.") ||
		strings.HasSuffix(n, ".example.") ||
		strings.HasSuffix(n, ".internal.")
}

into a loop that returns true early if current iterated value matches.

rm-hull added 2 commits June 1, 2026 19:56
Refactor `isReservedTLD` to use a slice and a loop instead of multiple
`strings.HasSuffix` calls to improve readability and maintainability.
Correct the test name to follow the standard `TestDNSDispatcher_`
naming convention used throughout the package.
@rm-hull rm-hull merged commit 6372b55 into main Jun 1, 2026
3 checks passed
@rm-hull rm-hull deleted the gemini/patch-issue-131-4aba170 branch June 1, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-generated go Pull requests that update go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Short circuit DNS-SD queries

2 participants