feat: add Windows UDP broadcast relay#2222
Merged
KKRainbow merged 13 commits intoMay 9, 2026
Merged
Conversation
31d18d4 to
5d53a79
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an opt-in Windows-only UDP broadcast relay that captures UDP broadcast packets from physical interfaces, normalizes them to the EasyTier virtual IPv4, and forwards them to peers, with config/CLI/env plumbing and frontend exposure.
Changes:
- Added
enable_udp_broadcast_relayflag through protobuf (FlagsInConfig,NetworkConfig), default flags, launcher config mapping, and CLI/env parsing. - Implemented Windows raw-socket capture + packet normalization + forwarding via
PeerManager, including unit tests for packet transforms. - Exposed the option in shared frontend config types/UI and added i18n strings.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| easytier/src/proto/common.proto | Adds enable_udp_broadcast_relay to FlagsInConfig. |
| easytier/src/proto/api_manage.proto | Adds enable_udp_broadcast_relay to RPC NetworkConfig. |
| easytier/src/common/config.rs | Sets default enable_udp_broadcast_relay to false. |
| easytier/src/core.rs | Adds CLI/env option and merges into runtime flags. |
| easytier/src/launcher.rs | Maps RPC NetworkConfig ⇄ FlagsInConfig including the new flag; updates tests. |
| easytier/src/instance/mod.rs | Wires in the new Windows UDP broadcast module behind cfg. |
| easytier/src/instance/instance.rs | Starts the relay on Windows+TUN when the flag is enabled. |
| easytier/src/instance/windows_udp_broadcast.rs | New raw-socket capture/normalize/forward implementation + unit tests. |
| easytier/locales/app.yml | Adds CLI help text translations for the new option. |
| easytier-web/frontend-lib/src/types/network.ts | Adds the flag to the shared frontend config type + defaults. |
| easytier-web/frontend-lib/src/locales/en.yaml | Adds UI strings for the new flag. |
| easytier-web/frontend-lib/src/locales/cn.yaml | Adds UI strings for the new flag. |
| easytier-web/frontend-lib/src/components/Config.vue | Adds the flag to the boolean flags list shown in the UI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| if sockets.is_empty() { | ||
| anyhow::bail!( | ||
| "failed to open any Windows raw UDP socket; administrator privileges are required" |
5d53a79 to
583c87e
Compare
Comment on lines
1577
to
+1584
| pub async fn get_msg_dst_peer_ipv4(&self, ipv4_addr: &Ipv4Addr) -> (Vec<PeerId>, bool) { | ||
| let mut is_exit_node = false; | ||
| let mut dst_peers = vec![]; | ||
| if self.is_all_peers_broadcast_ipv4(ipv4_addr) { | ||
| dst_peers.extend(self.peers.list_routes().await.iter().filter_map(|x| { | ||
| if *x.key() != self.my_peer_id { | ||
| Some(*x.key()) | ||
| } else { | ||
| None | ||
| } | ||
| })); | ||
| dst_peers.extend(Self::select_ipv4_broadcast_peers( | ||
| &self.peers.list_route_infos().await, | ||
| self.my_peer_id, | ||
| )); |
Comment on lines
+537
to
+570
| #[cfg(all(windows, any(target_arch = "x86_64", target_arch = "x86")))] | ||
| struct WinDivertCaptureReader { | ||
| inner: std::cell::UnsafeCell<WinDivert<layer::NetworkLayer>>, | ||
| } | ||
|
|
||
| #[cfg(all(windows, any(target_arch = "x86_64", target_arch = "x86")))] | ||
| unsafe impl Send for WinDivertCaptureReader {} | ||
|
|
||
| #[cfg(all(windows, any(target_arch = "x86_64", target_arch = "x86")))] | ||
| unsafe impl Sync for WinDivertCaptureReader {} | ||
|
|
||
| #[cfg(all(windows, any(target_arch = "x86_64", target_arch = "x86")))] | ||
| impl WinDivertCaptureReader { | ||
| fn new(inner: WinDivert<layer::NetworkLayer>) -> Self { | ||
| Self { | ||
| inner: std::cell::UnsafeCell::new(inner), | ||
| } | ||
| } | ||
|
|
||
| fn recv<'a>( | ||
| &self, | ||
| buffer: Option<&'a mut [u8]>, | ||
| ) -> Result<WinDivertPacket<'a, layer::NetworkLayer>, WinDivertError> { | ||
| let inner = unsafe { &*self.inner.get() }; | ||
| inner.recv(buffer) | ||
| } | ||
|
|
||
| fn shutdown(&self) -> anyhow::Result<()> { | ||
| let inner = unsafe { &mut *self.inner.get() }; | ||
| inner | ||
| .shutdown(WinDivertShutdownMode::Recv) | ||
| .with_context(|| "WinDivert UDP broadcast capture shutdown failed")?; | ||
| Ok(()) | ||
| } |
Comment on lines
+828
to
+855
| Err(err) => { | ||
| tracing::warn!( | ||
| ?err, | ||
| capture_backend, | ||
| "Windows UDP broadcast capture receive failed" | ||
| ); | ||
| match socket.fallback_to_raw() { | ||
| Ok(true) => { | ||
| let old_backend = capture_backend; | ||
| capture_backend = socket.backend_name(); | ||
| tracing::warn!( | ||
| old_backend, | ||
| new_backend = capture_backend, | ||
| "Windows UDP broadcast capture backend fell back" | ||
| ); | ||
| } | ||
| Ok(false) => {} | ||
| Err(fallback_err) => { | ||
| tracing::error!( | ||
| ?fallback_err, | ||
| "Windows UDP broadcast raw socket fallback failed; stopping relay" | ||
| ); | ||
| break; | ||
| } | ||
| } | ||
| continue; | ||
| } | ||
| }; |
Comment on lines
+1033
to
+1036
| tracing::warn!( | ||
| ?err, | ||
| "failed to start Windows UDP broadcast relay; administrator privileges are required" | ||
| ); |
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.
This PR may helps games to find rooms in virtual network.
Summary
Testing
Notes