[SANDBOX] rewrite in rust#91
Closed
AlexandreYang wants to merge 43 commits into
Closed
Conversation
Member
Author
|
This commit adds a full Rust implementation of datadog-traceroute with feature parity to the Go implementation: ## Core Libraries - traceroute-core: Error types, core types, TracerouteDriver trait, result types with serde serialization - traceroute-packets: Source/Sink traits with platform implementations: - Linux: AF_PACKET sockets with BPF filters - macOS: BPF devices (/dev/bpfN) + raw sockets - Windows: Raw sockets with IP_HDRINCL ## Protocol Implementations - traceroute-udp: UDP traceroute with pnet packet construction - traceroute-tcp: TCP SYN traceroute with Paris mode support - traceroute-icmp: ICMP Echo traceroute with parallel support - traceroute-sack: TCP SACK traceroute with handshake support ## User Interfaces - traceroute-cli: CLI binary with clap, matching Go flags - traceroute-server: HTTP server with Axum, GET /traceroute endpoint ## Testing & CI - E2E tests for localhost and public targets - GitHub Actions workflow for unit tests, clippy, and E2E tests on Linux, macOS, and Windows 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a slash command to monitor and fix GitHub CI failures. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Cargo does not allow [target.'cfg(...)'.workspace.dependencies] in virtual manifests. This moves libc and windows-sys to regular workspace dependencies and fixes the crate dependency to use windows-sys instead of windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- parallel.rs:69: Add explicit type annotation for closure parameter - serial.rs:53: Extract is_dest and ttl before moving probe 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Extract ttl_idx and is_dest before using probe to avoid use-after-move. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use NetHeaders instead of IpHeaders - Use payload.slice() instead of direct payload access - Use type_u8()/code_u8() instead of to_bytes() for ICMP types 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- parser.rs: Handle ICMP types using Unknown variant pattern instead of non-existent type_u8/code_u8 methods - windows.rs: Cast to *const u8 instead of *const i8 for setsockopt - windows.rs: Use TracerouteError::from() instead of non-existent Io variant 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- parser.rs: Match on &icmp.icmp_type to borrow instead of move - darwin.rs: Use TracerouteError::from() instead of non-existent Io variant 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- traceroute-icmp/packet.rs: Use IcmpPacket view for checksum calculation and manually set checksum bytes to avoid type mismatch - traceroute-packets/darwin.rs: Extract is_loopback before loop to avoid borrowing self while iterating - traceroute-sack/packet.rs: Extract buffer.len() before creating mutable borrow for MutableTcpPacket 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- traceroute-tcp/driver.rs: Use rand::thread_rng() instead of rand::rng() (rand 0.8.x API, not 0.9.x) - traceroute-core/serial.rs: Add ?Sized bound to allow dyn TracerouteDriver - traceroute-cli/runner.rs: Use TokioAsyncResolver with tokio_from_system_conf() - traceroute-server/runner.rs: Same hickory-resolver API fixes All tests now pass locally. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused imports (trace, AsRawSocket) - Remove dead code constants (IPPROTO_IP, IP_HDRINCL, SO_RCVTIMEO, etc.) - Remove unnecessary casts in socket() and setsockopt() calls - Fix unused mutable variable in start_driver() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- traceroute-icmp/driver.rs: remove unused warn import - traceroute-icmp/packet.rs: remove unused pnet_packet::Packet import - traceroute-udp/packet.rs: remove unused pnet_packet::Packet import 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove unused imports (warn, pnet_packet::Packet, Ipv4Addr, Write, AsRawFd, FromRawFd, File, Read, IoRead, IoWrite, get_min_sack_from_options, DEFAULT_PORT) - Remove dead code constants (SO_ATTACH_FILTER, SO_DETACH_FILTER) - Add #[allow(dead_code)] for unused fields (is_ipv6, max_ttl) - Add #[allow(clippy::too_many_arguments)] for TcpDriver::new - Fix never_loop in darwin.rs read() by removing unnecessary loop - Fix redundant closures (use TracerouteError::SocketCreation directly) - Fix unused variable (state -> _state) - Use ? operator instead of if let Err pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Ipv4Addr type is used in unit tests but was incorrectly removed from imports since cargo clippy doesn't check test code by default. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move E2E tests from rust/tests/ to traceroute-cli crate - Add tests for all protocols: UDP, TCP, ICMP - Test both localhost and public targets (1.1.1.1) - Add comprehensive field validation for traceroute output: - Protocol, destination, runs, run_id (UUID format) - Source/destination info, hop structure, sequential TTL - Hop count statistics - Test HTTP server endpoints (traceroute + health) - Add unit tests for JSON parsing and UUID validation - Add dev-dependencies: mockall, regex, serde, serde_json 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The E2E tests were failing in CI because they couldn't find the CLI binary. The tests look for binaries at relative paths like `target/release/datadog-traceroute`, but when running via `cargo test`, the working directory can vary. This fix: 1. Uses CARGO_MANIFEST_DIR to compute the workspace root path 2. Supports EXECUTABLE/SERVER_EXECUTABLE env vars from CI 3. Falls back to relative paths for local development 4. Improves error messages to help debug path issues 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Log output was being written to stdout, which corrupted the JSON output when parsing test results. This fix redirects all tracing logs to stderr to keep stdout clean for JSON output only. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit fixes three critical issues that were causing CI failures in the Rust E2E tests across different platforms: **macOS (os error 57 - Socket not connected):** - Fixed use-after-free bug in darwin.rs where sockaddr structures went out of scope before sendto() was called - The sa_ptr was pointing to dropped stack memory, causing undefined behavior - Refactored write_to() to keep sockaddr in scope during the sendto call **Windows (os error 10022 - Invalid argument):** - Windows raw sockets require binding before recvfrom() can work - Added bind() call in RawConn::new() to bind to the local address - Changed to use a shared socket (Arc<Mutex<RawConn>>) for both Source and Sink, matching the Go implementation's behavior **Linux (IPv4 packet parse errors):** - AF_PACKET captures all network traffic including non-IP packets - When parsing fails (e.g., malformed headers), the error was fatal - Added PacketParseFailed and PacketTooShort to is_retryable() so the traceroute loop continues reading instead of failing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The E2E tests can hang indefinitely in some cases. Add a timeout to prevent CI from running forever. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous fix incorrectly tried to bind to the target IP address instead of the local interface. Windows raw sockets should bind to INADDR_ANY (0.0.0.0) to receive packets from any local interface. This fixes error 10049 (WSAEADDRNOTAVAIL) when running traceroute to public targets on Windows. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove debug log reference to local_addr variable which was removed when changing to bind to INADDR_ANY. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove SOCK_NONBLOCK from AF_PACKET and raw socket creation - SO_RCVTIMEO only works on blocking sockets; with non-blocking sockets read() returns immediately with EAGAIN, causing an infinite loop - Now the socket properly blocks until data arrives or timeout occurs - Also handle TimedOut error kind in addition to WouldBlock 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add RUST_LOG=debug environment variable to E2E test jobs to help identify where tests are hanging. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enable --verbose flag on CLI invocations and print stderr output to help diagnose where tests are hanging. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The test harness now uses spawn + polling with a 2-minute timeout per CLI invocation instead of blocking forever with .output(). This helps diagnose hanging and prevents tests from timing out the entire CI job. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This reverts commit 0b3317f.
The test was expecting port 443 for TCP, but CLI defaults to 33434. This caused test_localhost_tcp_syn to fail with assertion mismatch. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a test subprocess times out, capture its stderr output before killing to help diagnose where the process is hanging. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Print CLI JSON output to help diagnose validation failures. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Previously, responses_to_hops() created 30 hops regardless of when the destination was reached, leading to test failures where the "last hop" was an unreachable TTL=30 hop instead of the actual destination. Now truncates hops to only include up to the last hop that received a response (either intermediate or destination). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The ICMP driver expects to read echo ID and sequence number from icmp_info.payload[0..4], but the parser was setting payload to empty for Echo Reply messages. This caused MalformedPacket errors. Now properly extract ID and seq from IcmpEchoHeader and store them in the payload field for both ICMPv4 and ICMPv6. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.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.
Planning: