Repository navigation
fix(inputs): fail a flow or dnstap listener that cannot bind instead of running without it - #805
Conversation
…of running without it uvw 3 returns libuv errors from bind(), listen() and recv() rather than emitting them, and the flow and dnstap inputs ignored the return values. A second flow policy whose input listened on a UDP port already in use was accepted and reported running, on a socket that never got the port, so it received nothing. The same held for a dnstap TCP server on a port in use and a Unix socket that could not be bound. start() now checks each call and throws with libuv's reason, after closing the handles and the loop it had created, so the policy load fails and is rolled back. The flow input builds its bind address itself: uvw's bind(ip, port) cut an IPv6 address down to a 16-byte sockaddr, so an IPv6 listener bound whatever the stack held, or nothing. A bind that is not an IPv4 or IPv6 address, or a port outside 1-65535, is refused with a message that says so. The server sockets' error and connection handlers run on the loop thread, where a throw terminates the process. They now log instead, and a client that cannot be accepted or read is closed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
|
/ai-review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
AI Code Review — risk tier: Advisory only. A human owns the merge decision. Summary — Net positive. The fix correctly makes flow/dnstap listeners fail loudly on bind errors instead of silently running unbound, and the IPv6 sockaddr-truncation fix for flow UDP binding is sound and well-tested. No new issues introduced by this diff; two pre-existing bugs elsewhere are worth tracking separately. Pre-existing / out-of-scope
No other findings. 🤖 AI Code Review · run · prompts: |
|
AI Code Review — risk tier: Advisory only. A human owns the merge decision. Summary — Net positive. Listeners now fail loudly on bind errors instead of running unbound, the IPv6 sockaddr-truncation fix for flow UDP binding is sound, and the sFlow source-IP handling now correctly branches on the sender's address family. No new issues found. Resolved since last review
🤖 AI Code Review · run · prompts: Previous review · 2026-10-29 · f8ef6efAI Code Review — risk tier: Advisory only. A human owns the merge decision. Summary — Net-positive reliability fix: bind/listen/accept/read return codes are now checked and surfaced, failed listeners roll back the policy instead of silently running on a dead socket, the IPv6 🤖 AI Code Review · run · prompts: |
LCOV of commit
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f8ef6efedc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
With IPv6 binds now working, an sFlow datagram from an IPv6 peer reached the callback, which still parsed the sender as IPv4 only. The failed parse left the sample's sourceIP as uninitialized IPv4 bytes. The sender is now read as IPv4 or IPv6, and an IPv4-mapped address from a dual-stack bind is kept as IPv4. The IPv6 test sends a valid sFlow datagram and checks the sample's sender. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
|
/ai-review |
|
🔁 AI Code Review updated for |
|
Codex Review: Didn't find any major issues. Another round soon, please! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Fixes MON-713. QA found that a second pktvisor flow policy on a UDP port already in use, with a different
input.config, was accepted and reported running. pktvisord answered 201 and ran two input streams, but only one socket listened on the port. The docs say pktvisor refuses that policy.Cause. uvw 3 returns libuv's result from
bind(),listen()andrecv()rather than emitting an error event. The flow input and both dnstap servers ignored those results. So a bind that failed with "address already in use" went unnoticed,start()succeeded, and the input ran on a socket that never got the port.Fix.
FlowInputStreamandDnstapInputStream(TCP and Unix) check each call. On failure they close the handles and the loop they created, then throw with libuv's reason. The policy load then fails and is rolled back (fix(policies): roll back every failed load and detach it from shared inputs #803), and orb-agent shows the policyfailed_to_applywith, for example,unable to bind flow UDP server on 0.0.0.0:6343: address already in use.bind(ip, port)passes the address through a helper that returns a 16-bytesockaddr. That cuts a 28-bytesockaddr_in6short, so the bind used whatever followed on the stack. On the current develop image,bind: "::"andbind: "::1"bound nothing. The flow input now builds asockaddr_storagewithuv_ip4_addr/uv_ip6_addrand callsbind(const sockaddr &). sFlow samples from an IPv6 peer now carry an IPv6 sender. Before, the callback parsed every sender as IPv4, so it left those bytes uninitialized. An IPv4-mapped sender from a dual-stack::bind is kept as IPv4.bindthat is not an IPv4 or IPv6 address (localhost), or a port outside 1–65535, is refused with a message that says so. Before, it ran on an ephemeral port, a truncated port, or no port at all.accept()orread()fails is closed.Tests
All 25 ctest targets pass on macOS (Release). The new tests:
::1receives a valid sFlow datagram and the sample's sender is IPv6::1;localhost, port 0 and port 70000 are refused. All but the IPv6 test failed on develop. The IPv6 test passed on develop here only by chance: the truncated address happened to bind at-O2on macOS, while Linux left it unbound.Bad Config: a flow policy on a port another flow input listens on is refused. Two policies sit on a config-less flow tap, like orb-agent's managedfleet_flow, on one port with different configs. The second load fails and is rolled back, and the first keeps its listener. It failed on develop.Not changed here
accept(), or a client handle that can't be created, libuv stops watching the listening socket, so the dnstap server accepts no further clients. Both failures are close to impossible in practice.close_eventhandlers look a session up by the fd of a closing handle;🤖 Generated with Claude Code