Skip to content

fix(net): use subnet-directed broadcast for LAN discovery (#86)#1

Open
Omar-Bsoul wants to merge 1 commit into
mainfrom
fix/lan-subnet-broadcast-86
Open

fix(net): use subnet-directed broadcast for LAN discovery (#86)#1
Omar-Bsoul wants to merge 1 commit into
mainfrom
fix/lan-subnet-broadcast-86

Conversation

@Omar-Bsoul

@Omar-Bsoul Omar-Bsoul commented Jun 6, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes fbraz3#86 — LAN lobby discovery fails between machines because announcements broadcast to the global 255.255.255.255, which routers/OSes often drop or route onto the wrong (Docker/VPN/virtual) NIC. Switches discovery to a per-interface subnet-directed broadcast and prefers the real private-LAN NIC.

Changes

  • IPEnumeration: reads ifa_netmask in the getifaddrs() loop and stores netmask + derived directed broadcast (ip | ~netmask, host byte order) on EnumeratedIP. Defaults to INADDR_BROADCAST when unknown (e.g. Win32 path) so nothing regresses.
  • LANAPI::SetLocalIP: sets m_broadcastAddr from the interface backing the selected local IP (exact match preferred; first real private-LAN interface as fallback), falling back to INADDR_BROADCAST only when no subnet is known. Adds isPrivateLanIP() (10/8, 172.16/12, 192.168/16).

Validation

⚠️ Not build-verified, and not yet runtime-tested on two machines. Proper test: two arm64 Macs (same LAN, or a directed-broadcast-passing VPN like ZeroTier) should now discover each other in the LAN lobby and finish a same-seed skirmish with matching per-frame CRC. Please test before merge.

🤖 AI-assisted (drafted with Claude, human-reviewed). Staged in this fork.

LAN game discovery sent its announce/request packets to the global
255.255.255.255 broadcast, which routers and virtual NICs (Docker/VPN)
frequently drop or route onto the wrong interface, so two machines on the
same LAN never see each other.

Capture each interface's netmask in IPEnumeration (host byte order) and
derive the per-interface subnet-directed broadcast (ip | ~netmask).
LANAPI::SetLocalIP now selects the broadcast target from the interface
backing the local IP, preferring a real private-LAN NIC over virtual
adapters, and falls back to INADDR_BROADCAST when no netmask is known so
behavior never regresses.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Omar-Bsoul

Copy link
Copy Markdown
Owner Author

🔬 Adversarial review — passed (0 confirmed defects)

This branch was put through a multi-agent adversarial review before being marked ready:

  • 7 review lenses across the changed files (byte-order/network semantics, memory & object lifetime, logic/regression, Win32 parity, compile-safety, and — for the CRC PR — CRC-determinism).
  • Every raised finding then faced a 3-verifier panel (refute / runtime-impact / fix-correctness); a finding survives only with a ≥2/3 majority.

Result for this PR: no confirmed defects.

The only finding raised in the whole review set was on PR #1 (UDP::Write log byte-order), and it was rejected 0/3 as a false positive — independently confirmed: PRINTF_IP_AS_4_INTS expects host byte order; Write’s IP is host-order (it htonl()s when building the sockaddr) so logging it raw is correct, while Bind reassigns IP=htonl(IP) before logging and therefore correctly uses ntohl(IP). The asymmetry is intentional and correct.

⚠️ Static review only — still pending two-machine LAN build/runtime validation.

🤖 Review performed by Claude Code (multi-agent workflow).

@fbraz3

fbraz3 commented Jun 25, 2026

Copy link
Copy Markdown

hey there, thanks for working on that. it's hard to me due I have no engought hardware to test all combination needed.

I'm currently working on CRC mismatches fbraz3#176

Also found something interesting on Core/GameEngine/Include/Common/GameDefines.h there are some retail compatibilty flags that can be disabled, including a network one that can make easey to work on UDP packets

// Disable non retail fixes in the networking, such as putting more data per UDP packet
#ifndef RETAIL_COMPATIBLE_NETWORKING
#define RETAIL_COMPATIBLE_NETWORKING (1)
#endif

I'm also testing disabling all RETAIL_COMPATIBLE flags because mac/linux will never be compatible with retail.

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.

LAN lobby discovery fails between Linux and macOS builds

2 participants