Repository navigation
fix: key the dial cache by the pinned ip, add WithResolveOverride - #580
Merged
dogancanbakir merged 4 commits intoOct 22, 2026
Merged
Conversation
dial() looked up the cached dialer by network and address before it read the ip pinned with the IP context value. After the first dial of a host:port, a dial pinned to another ip, even one the network policy denies, connected to the first ip, and an unpinned dial connected to the pinned ip instead of resolving the host. nuclei -sa and httpx -pa pin each resolved ip this way, so they reached one ip per host:port. A dial through the cached dialer also took the hostname from the address again with net.SplitHostPort. That lost the hostname of a host:port:ip address, so no SNI was sent, and replaced the punycode hostname of an IDN host with the raw one, which was then sent as the SNI and used as the key of its dialer history. parseAddress now splits the address once, before the cache lookup, and picks the pinned ip, which connHash includes. Each pinned ip gets its own cached dialer and goes through the network policy check; keys of unpinned dials don't change. The IP value pins every dial made with the context, including a redirect to another host or the dial to an HTTP proxy. WithResolveOverride(ctx, host, ip) pins dials to one host only, like curl --resolve. The IP value and a host:port:ip address take precedence over it.
This was referenced Oct 11, 2026
Draft
mazzz3r
added a commit
to mazzz3r/nuclei
that referenced
this pull request
Oct 13, 2026
go.mod takes dev's versions, including fastdialer v0.5.25, and keeps fastdialer replaced by the branch of projectdiscovery/fastdialer#580, which now includes v0.5.25.
mazzz3r
added a commit
to mazzz3r/httpx
that referenced
this pull request
Oct 13, 2026
The branch of projectdiscovery/fastdialer#580 now includes v0.5.25. Through MVS this raises networkpolicy to v0.1.54 and utils to v0.11.9, which that fastdialer commit requires.
mazzz3r
added a commit
to mazzz3r/httpx
that referenced
this pull request
Oct 13, 2026
The branch of projectdiscovery/fastdialer#580 now includes v0.5.25. Through MVS this raises networkpolicy to v0.1.54 and utils to v0.11.9, which that fastdialer commit requires.
mazzz3r
added a commit
to mazzz3r/httpx
that referenced
this pull request
Oct 19, 2026
go.mod takes dev's versions and keeps fastdialer replaced by the branch of projectdiscovery/fastdialer#580. dev already requires the networkpolicy and utils versions that branch needs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
dial()looked up the cached dialer before it read the pinned ip. After the first dial of a host:port, a dial pinned to another ip, even a denied one, went to the first ip, and so did an unpinned dial. That broke nuclei-saand httpx-pa. A dial through the cached dialer also parsed the address again, so ahost:port:ipaddress sent no SNI and an IDN host sent its Unicode name instead of punycode. Details and a reproduction are in #579.The
IPvalue also pins dials to other hosts made with the same context, such as a redirect target or an HTTP proxy.WithResolveOverridepins one host the waycurl --resolvedoes; nuclei and httpx use it to pin a target to an ip.Changes
parseAddresssplits the address once, before the cache lookup, andpinnedIPpicks the pinned ip: theIPvalue, then the ip of ahost:port:ipaddress, then a resolve override.connHash()includes it, so each pinned ip gets its ownDialWrapand goes through the network policy check. Keys of unpinned dials don't change, anddialTimeoutErrorsuses the same key.SplitHostPortreturned it.WithResolveOverride(ctx, host, ip)pins dials tohoston any port, with one context key per host. The host is compared case-insensitively and without a trailing dot, and it is still sent as SNI. Dials to other hosts resolve as usual. README has an example.Testing
dialer_pin_test.gouses local listeners and the existing mock DNS server:NoAddressAllowedError; an unpinned dial after a pinned one resolves the host;TestDialTLSKeepsSNI: ahost:port:ipaddress, a resolve override, and an IDN host, pinned and resolved, send the ASCII hostname as SNI on the first and the cached dial, andGetDialedIPfinds the dial;WithResolveOverride: the matching host is pinned, other hosts resolve, the parent context is unchanged, case and trailing dot are ignored, and theIPvalue wins;TestDialIPv6Addressdials[::1]:porttwice and checks the history key::1. It is skipped here, as this kernel has no IPv6.main, theTestDialPinnedIPcases and the SNI cases fail: the second pinned dial readsone, thehost:port:ipSNI is empty, and the IDN SNI isbücher.test.go test -race ./...passes exceptTestFastDialerDomainMultiIP/Dial_TCP_Domain_with_port_80, which needs outbound port 80 and fails onmaintoo. The new tests also pass with-racein an offlinegolang:1.27.1container.golangci-lint run ./...(v2): 0 issues.pinned.test:18301,IP127.0.0.1IP127.0.0.2IP127.0.0.2, with 127.0.0.2 denieddenied address found for hostpinned.test:18443:127.0.0.1, twicepinned.testbücher.test:18443bücher.testxn--bcher-kva.testCloses #579