Skip to content

livox rust: bind host ports with SO_REUSEADDR, as SDK2 does - #4240

Open
jeff-hykin wants to merge 2 commits into
mainfrom
jeff/fix/livox_rust_reuse_addr
Open

jeff-hykin wants to merge 2 commits into
mainfrom
jeff/fix/livox_rust_reuse_addr

Conversation

@jeff-hykin

@jeff-hykin jeff-hykin commented Sep 19, 2026

Copy link
Copy Markdown
Member

Don't forcefully reuse the Mid360 port (needed for R1 Pro stuff)

The vendor's livox_ros_driver2 (Livox SDK2) holds the same host ports and
binds them with SO_REUSEADDR, so the C++ Point-LIO module (also SDK2) shares
them and this driver, binding plainly, was the one process refused with
EADDRINUSE. Bind the command and data sockets with reuse set.

Also make the impostor-sender test run on macOS, where 127.0.0.2 is not on
lo0: fall back to the routed interface address.
@jeff-hykin
jeff-hykin marked this pull request as ready for review September 19, 2026 14:54
@jeff-hykin jeff-hykin added the backport:skip Skip creating a backport to any release branches label Sep 19, 2026
@greptile-apps

greptile-apps Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 4/5

Not safe to merge until the route-dependent test panic is addressed; the socket-sharing test gap is non-blocking but leaves the intended traffic behavior unverified.

Findings

  1. P1 Avoid route-dependent fallback
  2. P2 Test actual socket traffic

Summary

This change improves UDP socket binding compatibility and adds coverage around SDK2-style port sharing, but two test paths need attention. The SDK2 coexistence test confirms only that startup succeeds, not that handshake and sensor packets continue to flow while competing sockets remain bound. The unexpected-sender test also panics when its fallback cannot select a routed local address on an isolated runner.

Reviews (1) · Last reviewed commit: "livox rust: bind host ports with SO_REUS..."

Comment on lines +674 to +680
);
assert!(
source.is_ok(),
"must coexist with an SDK2 binder: {:?}",
source.err()
);
stop.store(true, Ordering::Relaxed);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Test actual socket traffic

This test only verifies that LiveSource::start returns, then immediately stops the source. It can pass while the SDK2-style sockets receive the handshake ACKs or point and IMU datagrams instead. Keep those sockets bound through a completed fake-device handshake and assert receipt of both packet types. This is non-blocking, but without it the regression test can miss a broken data path.

Artifacts

Command output from the check

  • Ran the PR's existing coexistence test from the repository root; it passed but only ran the startup-and-stop path, confirming the limited scope.

Evidence from the check

  • Temporary executable command that adds a test retaining the three SDK2-style bindings, ACKing the full handshake, and requiring point and IMU receipt.

Command output from the check

  • Executed the focused validation from the repository root; it timed out waiting for a packet with competing SDK2-style sockets held, so full traffic coexistence was not demonstrated.

View artifacts

T-Rex Ran code and verified through T-Rex

Comment on lines +445 to +451
probe
.connect(SocketAddrV4::new(Ipv4Addr::new(10, 255, 255, 255), 9))
.expect("no 127.0.0.2 alias and no default route: nowhere to forge from");
match probe.local_addr().unwrap() {
std::net::SocketAddr::V4(addr) if !addr.ip().is_loopback() => *addr.ip(),
addr => panic!("routed address {addr} is not a usable impostor"),
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Avoid route-dependent fallback

If 127.0.0.2 is unavailable and the runner has no default route, this fallback panics after UDP address selection fails, before the sender-filter assertion runs. The unexpected-sender test therefore fails on isolated or offline runners even though the production behavior is unaffected. Use a deterministic local setup or handle an unavailable route without panicking. This must be fixed before merging because it makes the test suite fail in supported isolated environments.

Artifacts

Evidence from the check

  • Evidence file captured while the check ran.

Command output from the check

  • The full command output behind this check.

Command output from the check

  • The full command output behind this check.

Command output from the check

  • The full command output behind this check.

Command output from the check

  • The full command output behind this check.

View artifacts

T-Rex Ran code and verified through T-Rex

@greptile-apps

greptile-apps Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Comments Outside Diff

These findings sit on lines the diff does not cover, so they could not be posted inline. Each one leaves this list once its file changes.

  • P2 SDK2 coexistence test does not validate usable data-plane coexistence

    • Bug
      • starts_while_an_sdk2_process_holds_the_host_ports passes after LiveSource::start and immediately stops. A focused run keeping identical SDK2-style competing bindings alive while ACKing the complete handshake and transmitting point/IMU packets timed out waiting for receipt.
    • Cause
      • The added test neither provides a device to acknowledge the asynchronous control handshake nor calls recv; with SO_REUSEPORT, datagrams may be assigned to the competing sockets rather than this source.
    • Fix
      • Extend the coexistence test with a fake device that ACKs every handshake step and sends point and IMU packets while the competing sockets remain alive; assert handshake completion and receipt of both packet types. If sharing is intentionally bind-only, narrow the test name and claim accordingly.

@codecov

codecov Bot commented Sep 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

@@           Coverage Diff           @@
##             main    #4240   +/-   ##
=======================================
  Coverage   79.71%   79.71%           
=======================================
  Files        1508     1508           
  Lines      142607   142607           
  Branches    12209    12209           
=======================================
  Hits       113681   113681           
  Misses      25485    25485           
  Partials     3441     3441           
Components Coverage Δ
Tests 95.41% <ø> (+<0.01%) ⬆️
Flag Coverage Δ
OS-ubuntu-24.04-arm 75.35% <ø> (-0.01%) ⬇️
OS-ubuntu-latest 76.16% <ø> (+<0.01%) ⬆️
Py-3.10 75.94% <ø> (+<0.01%) ⬆️
Py-3.11 76.14% <ø> (-0.01%) ⬇️
Py-3.12 76.15% <ø> (+<0.01%) ⬆️
SelfHosted-Large 30.61% <ø> (ø)
SelfHosted-Linux 36.65% <ø> (+<0.01%) ⬆️
SelfHosted-macOS 36.98% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.
see 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Sep 19, 2026
aclauer
aclauer previously approved these changes Sep 19, 2026
/// over a specific one). A vendor SDK2 process -- `livox_ros_driver2` on the
/// Galaxea R1 -- holds the same host ports, and the kernel only lets two
/// sockets share a port when both asked for it. A plain bind is refused with
/// `EADDRINUSE`; the C++ Point-LIO module, which binds through SDK2, never

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just remove this commentary about deleted code? Otherwise lgtm!

@github-actions github-actions Bot removed the ready-to-merge Required CI checks have passed on this PR label Sep 19, 2026
@github-actions github-actions Bot added the ready-to-merge Required CI checks have passed on this PR label Sep 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip Skip creating a backport to any release branches ready-to-merge Required CI checks have passed on this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants