Compare commits

...
3 Commits
Author SHA1 Message Date
Owen SchwartzandGitHub 2aa637f4d8 Merge pull request #424 from Serph91P/fix/compat-registration-chain-race
fix: preserve the pending WireGuard registration chain
2026-08-05 09:28:18 -04:00
Owen 1bde15f0a7 add test for magic packets 2026-08-03 12:14:21 -04:00
Seraph91P b5a7213cdb fix: preserve pending registration chain
Backwards-compatible registrations do not receive a wg/connect response.
Do not let them replace the chain ID of a normal registration that may
already be in flight.
2026-07-21 16:43:45 +00:00
3 changed files with 22 additions and 2 deletions
+17
View File
@@ -683,6 +683,23 @@ func (b *SharedBind) receiveIPv4Simple(conn *net.UDPConn, bufs [][]byte, sizes [
}
}
// IsMagicPacket reports whether payload is one of our connectivity-test magic
// packets (a MagicTestRequest or MagicTestResponse). These packets are meant to
// travel directly between physical UDP sockets and must never be encapsulated by
// WireGuard - e.g. if OS routing mistakenly sends one into a WireGuard TUN
// interface (because the destination falls inside a routed tunnel subnet), it
// should be dropped there rather than tunneled, which would otherwise make a
// LAN-local endpoint test falsely appear to succeed over the tunnel.
func IsMagicPacket(payload []byte) bool {
if len(payload) >= MagicTestRequestLen && bytes.HasPrefix(payload, MagicTestRequest) {
return true
}
if len(payload) >= MagicTestResponseLen && bytes.HasPrefix(payload, MagicTestResponse) {
return true
}
return false
}
// handleMagicPacket checks if the packet is a magic test packet and responds if so.
// Returns true if the packet was a magic packet and was handled (should not be passed to WireGuard).
func (b *SharedBind) handleMagicPacket(data []byte, addr *net.UDPAddr) bool {
+3 -1
View File
@@ -1010,7 +1010,9 @@ func (n *Newt) registerHandlers(ctx context.Context) {
}
bcChainId := generateChainId()
n.pendingRegisterChainId = bcChainId
// Pangolin intentionally does not answer backwards-compatible
// registrations with newt/wg/connect. Do not replace the chain ID of
// the real registration while its response may already be in flight.
if err := n.client.SendMessage(topicWGRegister, map[string]interface{}{
"publicKey": n.publicKey.String(),
"newtVersion": n.config.Version,
+2 -1
View File
@@ -280,7 +280,8 @@ func (n *Newt) startPingCheck(fn pingFunc, serverIP, tunnelID string) chan struc
"chainId": pingChainId,
}, 3*time.Second)
bcChainId := generateChainId()
n.pendingRegisterChainId = bcChainId
// This compatibility message has no wg/connect response and must
// not supersede the pending real registration chain.
if err := n.client.SendMessage("newt/wg/register", map[string]interface{}{
"publicKey": n.publicKey.String(),
"backwardsCompatible": true,