Repository navigation
fix(net): GOAWAY local check decodes every IPv4 spelling the dial accepts - #8327
Conversation
Quest-Claim: f9992fa60ae537c8
…epts Rust's is_local reads a non-special scheme's host back through https, as js/net does, so moqt://127.1 and friends count as loopback, and treats localhost. as localhost. Both sides replay rs/moq-net/fixtures/endpoints.json. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 4 minutes. View limit details
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. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed 2e2f754. No actionable findings.
The Rust classifier now normalizes opaque hosts through the special-scheme parser before checking local IPv4 forms and trailing-dot localhost names. Checked the existing IPv6/mapped-address handling, redirect policy ordering, shared Rust/JS fixture paths, and public-to-local refusal regression. DNS-resolved destinations remain outside this literal-address check, as documented. The release backport remains explicitly tracked.
Verification limits: GitHub-only static review; Rust/JS tests and native DNS/dial behavior were not executed.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
- Rust classifier decodes opaque hosts:
is_localinrs/moq-net/src/reconnect/redirect.rsnow re-reads aHost::Domainthrough the WHATWG special-scheme host parser (https://{host}/), classifies the resultingIpv4/Ipv6/Domain, and strips a trailing dot before thelocalhostcheck, somoqt://127.1, hex/octal/decimal IPv4,LOCALHOST,localhost., and0are refused like their dotted-quad spellings. The old literal logic remains as the fallback when the reparse fails. - Shared corpus:
rs/moq-net/fixtures/endpoints.jsonholds 30 spellings and verdicts, replayed by the Rust unit test (include_str!) andjs/net/src/connection/endpoint.test.ts(Bun.file), so the Rust and JS classifiers cannot drift. - Redirect behaviour test: adds a
Redirect::Followrefusal case formoqt://127.1against a non-local current target. - Quest re-scope:
quest/m0/goaway-loopback.mdis rewritten to cover only thereleasebackport.
Verification: the JS suite and tsc --noEmit pass, and the fixture file lints clean. The crate test could not run here (target/ was locked by another session), so I compiled a verbatim copy of is_local/is_local_ip/is_local_v4 against the checkout's url 2.5.8 rlib: all 30 cases classify as the fixture expects. I also probed glibc getaddrinfo for the shorthand/hex/octal spellings the native dial sees — each resolves to the same address the WHATWG parser yields, and invalid-octal forms (08, 019) fail both, so no dial-accepted literal spelling is left unclassified.
deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

Summary
A GOAWAY from a non-local relay could steer a
redirect: "follow"Rust client to loopback by spelling the address as shorthand or numeric IPv4 (moqt://127.1,0x7f000001,2130706433,0177.0.0.1). A non-special scheme keeps its host opaque,str::parse::<IpAddr>refused those spellings, and the native dial still reached 127.0.0.1.rs/moq-net/src/reconnect/redirect.rs:is_localreads aHost::Domainback through anhttps://URL (WHATWG host parser), as js/net'sendpoint.tshas done since moq-dev/moq#8222, and strips a trailing dot before thelocalhostcheck.rs/moq-net/fixtures/endpoints.json: one corpus of spellings and verdicts, replayed by the Rust unit test andjs/net/src/connection/endpoint.test.ts, so the classifiers cannot drift.releasebackport, which CONTRIBUTING.md says lands only after themainfix.Hostnames that resolve to local addresses stay out of scope (documented on
Redirect::Follow).Impact
Public API: none. Wire: none. Behavior: such redirects are refused.
Caused by
is_localonstr::parse::<IpAddr>.Choices made without asking
rs/moq-net/fixtures/, besidelite.json.Follow-ups
None.
Models
Size: S
Implementer: Claude Code, Opus 5.5, unknown effort
(Written by Opus 5.5)
Review
Rewritten by
quest reviewafter each round.01a1bd10-1c75-75c3-9efe-d489d2031f55, round 1The change is focused and covered by targeted cases, with no actionable defects found in source review, though builds and tests were not run as instructed.