feat: Windows IPv6 traceroute (Icmp6SendEcho2)#50
Merged
Conversation
Add examples/spike_windows_v6.rs, run in a Windows 11 ARM64 VM with native IPv6, and record the findings in docs/IPV6_DESIGN.md (replacing the Windows entry in the open-questions list): - The required source SOCKADDR_IN6 accepts the unspecified address (::) with AF_INET6 — the stack picks the source, no enumeration needed - IP_OPTION_INFORMATION.Ttl caps the hop limit; expired probes return Status IP_HOP_LIMIT_EXCEEDED (11013) with the router address - ICMPV6_ECHO_REPLY_LH layout confirmed (36 bytes; packed 26-byte IPV6_ADDRESS_EX at 0 with network-order [u16;8] words at byte 6, Status at 28, RoundTripTime at 32, echoed payload at 36 for Echo Replies only — Time Exceeded does not echo, same asymmetry as v4) - Timeout: the event still signals; Icmp6ParseReplies returns 0 with GetLastError = IP_REQ_TIMED_OUT (11010) The spike stays in-repo as a permanent diagnostic per project policy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add src/socket/windows_v6.rs mirroring the v4 WindowsAsyncIcmpSocket: event-based Icmp6CreateFile/Icmp6SendEcho2/Icmp6ParseReplies with a spawn_blocking waiter, the same Tokio-vs-Windows timeout-buffer logic (WINDOWS_ICMP_* constants in config/timing.rs), and the same pending- handle Drop optimization. Unspecified :: source (spike-validated), no elevation required. Echo-reply id/seq verification uses the payload echoed at offset 36; replies parse through Icmp6ParseReplies per the async API contract, with 0 replies mapped to a timeout response. Dispatch the Windows V6 factory arm to the new socket (UDP protocol preference returns a typed NotImplemented, as on macOS/BSD), reuse ProbeMode::WindowsIcmp (no new enum variant — additive-only API), and compile the platform-neutral icmpv6 codec for its unit tests only on Windows, since the Win32 API parses replies itself. Unit tests cover the spike-verified reply layout: hop-limit-exceeded, destination echo, zero-RTT fallback, foreign-identifier rejection, timeout status, short buffers, and word byte order — all 8 pass in the Windows 11 VM alongside the rest of the lib suite (231 tests), and a live 17-hop ftr -6 google.com trace with full enrichment plus a v4 regression trace both succeed there. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
cargo clippy --target x86_64-pc-windows-msvc --all-targets was carrying ~16 dead-code warnings invisible to CI (whose clippy job runs on Ubuntu): the v4 raw-ICMP codec helpers in src/socket/icmp.rs are unused on Windows (allow dead_code there — the Win32 API parses replies), the v6 spikes' RFC constants are unreferenced when only the stub main compiles (file-level cfg_attr allow), and windows.rs kept an unused new_with_config constructor (removed; the verbose variant is the only caller path). The windows-msvc target now passes clippy --all-targets with -D warnings; adding that cross-target check to CI is the durable fix and is noted in the PR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #50 +/- ##
==========================================
- Coverage 84.45% 84.31% -0.14%
==========================================
Files 36 36
Lines 6663 6663
==========================================
- Hits 5627 5618 -9
- Misses 1036 1045 +9
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
test_ipv6_target_platform_behavior and test_error_types still listed Windows in their Ipv6NotSupported fallback arms; with Icmp6SendEcho2 support landed, a ::1 trace now succeeds unprivileged there (verified in the Windows 11 VM before pushing — both suites green). Move Windows into the unprivileged-success arm alongside macOS and Linux. Co-Authored-By: Claude Fable 5 <noreply@anthropic.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.
Windows was the last platform without IPv6 traceroute after v0.9.0. This PR closes that gap with the IP Helper
Icmp6CreateFile/Icmp6SendEcho2/Icmp6ParseRepliesAPI, mirroring the proven v4WindowsAsyncIcmpSocketdesign (event handle per probe,spawn_blockingwaiter, and the Tokio-vs-Windows timeout-buffer logic fromdocs/WINDOWS_ASYNC_FINDINGS.md). No elevation required, same as v4.-6now works on every supported platform.Spike-first validation (live, before implementation)
examples/spike_windows_v6.rs(permanent in-repo diagnostic) ran in a Windows 11 ARM64 VM with native IPv6 (Sonic fiber, bridged) and confirmed every hypothesis fromdocs/IPV6_DESIGN.md, now recorded there as a "Validated findings (Windows)" section:SOCKADDR_IN6accepts the unspecified::withAF_INET6— the stack picks the source; no interface enumeration/GetBestInterfaceExneededIP_OPTION_INFORMATION.Ttlsets the hop limit; expired probes returnStatus = IP_HOP_LIMIT_EXCEEDED(11013) with the router's addressICMPV6_ECHO_REPLY_LHlayout verified by hex dump: 36 bytes, packed 26-byteIPV6_ADDRESS_EX(address[u16;8]words in network byte order at byte 6),Statusat 28,RoundTripTimeat 32, echoed request payload at 36 for Echo Replies only (Time Exceeded doesn't echo — same asymmetry as v4)Icmp6ParseRepliesreturns 0 withGetLastError() = IP_REQ_TIMED_OUT(11010)Live results from the VM
ftr -6 -v google.com(abridged):Also verified in the VM:
ftr -6 ::1loopback,ftr 8.8.8.8v4 regression trace, and the full lib test suite (231 passed, including the 8 newwindows_v6reply-parse unit tests against synthetic spike-verified buffers).Implementation notes
src/socket/windows_v6.rs: new socket; replies go throughIcmp6ParseRepliesper the async API contract (0 parsed replies maps to a timeout response); echo-reply id/seq verification uses the payload echoed at offset 36;read_unalignedfor the reply struct (Vec buffers have 1-byte alignment)src/socket/factory.rs: Windows V6 arm dispatches to the new socket; explicit UDP protocol preference returns typedNotImplemented(consistent with macOS/BSD)ProbeMode::WindowsIcmp— no new public enum variantsLint debt payoff
cargo clippy --target x86_64-pc-windows-msvc --all-targetscarried ~16 dead-code warnings invisible to CI (whose clippy job runs on Ubuntu): unused v4 raw-ICMP codec helpers on Windows, spike RFC constants under stub mains, and an unusednew_with_configconstructor. All resolved — the windows-msvc target is now clean under-D warnings. The durable fix is adding a windows-target clippy cross-check to CI (tracked in the improvement plan); this PR clears the baseline for it.🤖 Generated with Claude Code