Skip to content

Fix Darwin multicast loopback by binding to INADDR_ANY#75

Merged
thebentern merged 3 commits into
meshtastic:masterfrom
jamesarich:fix/darwin-multicast-loopback-bind
Jun 27, 2026
Merged

Fix Darwin multicast loopback by binding to INADDR_ANY#75
thebentern merged 3 commits into
meshtastic:masterfrom
jamesarich:fix/darwin-multicast-loopback-bind

Conversation

@jamesarich

@jamesarich jamesarich commented Jun 25, 2026

Copy link
Copy Markdown

Summary

AsyncUDP::listenMulticast() bound the UDP socket to the multicast group address (224.0.0.69:port). Linux loops those datagrams back to sibling processes on the same host, but Darwin/BSD does not — so two meshtasticd native nodes on one macOS host never exchanged NodeInfo over UDP multicast.

Bind to INADDR_ANY:port on __APPLE__ instead. The uv_udp_set_membership() group join above still filters received traffic to the group. Linux is unchanged (still binds the group address, preserving the existing SO_BROADCAST receive-fanout behavior).

#if defined(__APPLE__)
    uv_ip4_addr("0.0.0.0", port, (struct sockaddr_in *)&uvAddr);
#endif
    if (uv_udp_bind(&_socket, (const struct sockaddr *)&uvAddr, 0) < 0) {

Test plan

  • Rebuilt native-macos (meshtastic/firmware) with -DHAS_UDP_MULTICAST=1 and confirmed two native nodes now mesh over 224.0.0.69:4403 — both node DBs cross-populate.
  • Linux meshing remains green: verified two nodes in the official meshtasticd Docker image cross-populate and deliver a text message.

listenMulticast() bound the UDP socket to the multicast group address
(224.0.0.69:port). Linux delivers looped-back multicast to sibling
processes bound this way, but Darwin/BSD does not, so two meshtasticd
native nodes on the same macOS host never exchanged NodeInfo over UDP.

Bind to INADDR_ANY:port on __APPLE__ instead; the uv_udp_set_membership()
group join still filters received traffic. Linux keeps binding to the
group address so the existing SO_BROADCAST receive-fanout behavior is
unchanged.

Validated: two native-macos meshtasticd nodes now mesh over
224.0.0.69:4403 (both node DBs cross-populate); Linux meshing
(verified in Docker) is unaffected.

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.

Adjusts UDP multicast listening on macOS/Darwin so multiple native nodes on the same host can receive looped-back multicast by binding to INADDR_ANY instead of the multicast group address.

Changes:

  • Add an Apple-specific bind target override to 0.0.0.0:port in AsyncUDP::listenMulticast().
  • Document the cross-platform rationale (Linux vs. Darwin/BSD behavior) in code comments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread cores/portduino/AsyncUDP.cpp
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.

Comment thread cores/portduino/AsyncUDP.cpp
Comment thread cores/portduino/AsyncUDP.cpp Outdated
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thebentern thebentern merged commit c3323de into meshtastic:master Jun 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants