Conversation
When the inviter was reached over IPv6 link-local, outboundIP dropped the scope zone when advertising its address, so the joiner's Completion Exchange POST had no route and pairing failed after the PIN step. Keep the zone, and render peer addresses into URLs via net/url so the zone is percent-encoded per RFC 6874 (a raw % is rejected as an invalid URL escape). Signed-off-by: mkalkere <14184493+mkalkere@users.noreply.github.com>
Signed-off-by: mkalkere <14184493+mkalkere@users.noreply.github.com>
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.
Description
Fixes #69: pairing failed after a correct PIN when the inviter connected over IPv6 link-local.
Root cause is not TLS, as first suspected -- the pairing client pins the server key (DER compare, no hostname verification), so the handshake was fine. The failure is visible in the reporter's log:
outboundIP()rendered the local address withip.String(), dropping the IPv6 scope zone. The inviter advertised[fe80::...]:14321with no zone, so after the PIN was accepted the joiner's Completion Exchange POST died withno route to host-- the address was unroutable without%en0.The fix, in
services/nvpair-cluster-manager: (1)outboundIPnow preserves the zone via a newscopedHosthelper; (2) a newpeerURLhelper renders peer addresses into URLs throughnet/url, percent-encoding the zone per RFC 6874. The second part is required, not cosmetic: Go'surl.Parserejects a raw%en0as an invalid URL escape, so preserving the zone alone would have traded a dial error for a parse error. Applied at all three raw string-concat URL sites: pairing POST (invite.go), removal notify (mtls.go), roster reconcile (roster_http.go).Scope
Included: the three call sites above,
pairing_linklocal_test.go, version bump,docs/pairing-ipv6-link-local.mdx. Excluded: the same raw-concat pattern innvpair-workload-manager/broadcast.go:127andnvpair-errors/peersync.go:280-- same latent defect, different components, left for a focused follow-up.Validation
go test -race ./...inservices/nvpair-cluster-manager: pass, exceptTestReachableEndpointFirstLeadsWithTheAddressThatAnswers, which fails identically on pristine upstream (sandbox networking, unrelated to this change).outboundIP, RFC 6874 rendering round-trips, all three call sites produce parseable URLs for zone'd addresses.go vetclean,gofmtclean,node scripts/spdx-headers.mjsreports 0 missing headers on every branch.Risk
%25en0); required forurl.Parseto accept it. No behavior change for IPv4 or loopback addresses.Checklist
git commit -s), certifying the Developer Certificate of Origin.services/versions.json, and described user-visible changes above so they reach the release notes.