This commit is contained in:
jdl
2026-06-07 20:30:31 +02:00
parent 747d73890f
commit 3877ec5f35
15 changed files with 173 additions and 80 deletions

View File

@@ -1,13 +1,29 @@
package peer
import "net/netip"
import (
"encoding/binary"
"net/netip"
"golang.org/x/crypto/nacl/sign"
"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
)
func (a *App) onMulticastDiscovery(e MulticastEvent) {
if a.isPublic {
return
}
peer, ok := a.peersByKey[e.pubKey]
// Peek at the VPN IP byte to find the sender peer before verifying.
// nacl/sign prepends a 64-byte signature, so payload starts at offset sign.Overhead.
if len(e.signed) != mcSignedBeaconLen {
return
}
netAddr := a.vpnNet.Addr().As4()
octets := netAddr
octets[3] = e.signed[sign.Overhead]
vpnIP := netip.AddrFrom4(octets)
peer, ok := a.peersByIP[vpnIP]
if !ok {
return
}
@@ -16,11 +32,28 @@ func (a *App) onMulticastDiscovery(e MulticastEvent) {
return
}
payload, ok := sign.Open(nil, e.signed, &peer.SignPubKey)
if !ok {
return
}
// payload: [1 VPN IP byte][32 WG pubkey][2 WG port]
wgPubKey, err := wgtypes.NewKey(payload[1:33])
if err != nil || wgPubKey != peer.PubKey() {
return
}
wgPort := binary.BigEndian.Uint16(payload[33:35])
endpoint := netip.AddrPortFrom(e.src, wgPort)
if !endpoint.IsValid() {
return
}
var v4, v6 netip.AddrPort
if e.endpoint.Addr().Is4() {
v4 = e.endpoint
if e.src.Is4() {
v4 = endpoint
} else {
v6 = e.endpoint
v6 = endpoint
}
a.addProbe(peer, v4, v6)