UDPv4 is sufficient! we always have 100.x overlay. IPv6 is additive

ipAllowed[0] is the v4
This commit is contained in:
riccardom
2026-08-07 17:23:49 +02:00
parent f6e5e17c5f
commit 33559114db
3 changed files with 22 additions and 32 deletions

View File

@@ -17,14 +17,14 @@ type fakePQ struct {
ok bool
}
func (f fakePQ) OfferPayload(string) ([]byte, int) { return nil, 0 }
func (f fakePQ) ShouldSendBootstrapOffer(string) bool { return false }
func (f fakePQ) AnswerPayload(string, []byte) ([]byte, int) { return nil, 0 }
func (f fakePQ) OnAnswer(string, []byte) {}
func (f fakePQ) PSK(string) (wgtypes.Key, bool) { return f.psk, f.ok }
func (f fakePQ) SetRemoteAddr(string, netip.AddrPort) {}
func (f fakePQ) OnDataPathRekeyed(string, time.Duration) {}
func (f fakePQ) OnDataPathDown(string) {}
func (f fakePQ) OfferPayload(string) ([]byte, uint16) { return nil, 0 }
func (f fakePQ) ShouldSendBootstrapOffer(string) bool { return false }
func (f fakePQ) AnswerPayload(string, []byte) ([]byte, uint16) { return nil, 0 }
func (f fakePQ) OnAnswer(string, []byte) {}
func (f fakePQ) PSK(string) (wgtypes.Key, bool) { return f.psk, f.ok }
func (f fakePQ) SetRemoteAddr(string, netip.AddrPort) {}
func (f fakePQ) OnDataPathRekeyed(string, time.Duration) {}
func (f fakePQ) OnDataPathDown(string) {}
// TestConn_presharedKey_PQ covers the post-quantum branch of presharedKey across the
// three states that matter: a derived PSK is programmed, and — before one exists —

View File

@@ -235,23 +235,17 @@ func (h *Handshaker) pqRegisterEndpoint(remotePort uint16) {
h.config.PQ.SetRemoteAddr(h.config.Key, netip.AddrPortFrom(overlay, remotePort))
}
// pqPeerOverlayAddr picks the peer's overlay address for the pq data path. The pq
// transport binds on the local WG overlay IPv4, so an IPv4 AllowedIP is preferred; a v6
// prefix is used only when this interface actually has a v6 overlay, and never in place
// of a usable v4. Returns false when no suitable address exists.
// pqPeerOverlayAddr returns the peer's IPv4 overlay address for the pq data path. A
// RemotePeerConfig carries only the peer overlay (v4 /32, optionally v6 /128) — served
// routes are programmed on WireGuard separately and never land in WgConfig.AllowedIps —
// so AllowedIps[0] is the v4 overlay, matching conn.AllowedIP(). The transport is v4
// (the overlay always has v4; v6 is additive). Returns false when no v4 overlay exists.
func (h *Handshaker) pqPeerOverlayAddr() (netip.Addr, bool) {
var v6 netip.Addr
for _, p := range h.config.WgConfig.AllowedIps {
a := p.Addr().Unmap()
if a.Is4() {
return a, true
}
if a.Is6() && !v6.IsValid() {
v6 = a
}
if len(h.config.WgConfig.AllowedIps) == 0 {
return netip.Addr{}, false
}
if v6.IsValid() && h.config.WgConfig.WgInterface.Address().HasIPv6() {
return v6, true
if a := h.config.WgConfig.AllowedIps[0].Addr().Unmap(); a.Is4() {
return a, true
}
return netip.Addr{}, false
}

View File

@@ -30,19 +30,15 @@ func newPQTransport(overlayIP netip.Addr) (*pqTransport, error) {
if !overlayIP.IsValid() {
return nil, fmt.Errorf("invalid overlay IP for pqkem transport")
}
// Unmap an IPv4-mapped IPv6 address so AsSlice() yields 4 bytes, and pick the UDP
// network matching the overlay family (a hardcoded "udp4" fails on a v6 overlay and
// on a mapped v4 whose AsSlice() is 16 bytes).
// The WG overlay always carries an IPv4 address (v6 is additive, never standalone),
// so the transport binds over IPv4. Unmap first so AsSlice() yields 4 bytes for an
// IPv4-mapped IPv6 address (a hardcoded "udp4" would otherwise fail on its 16 bytes).
overlayIP = overlayIP.Unmap()
network := "udp6"
if overlayIP.Is4() {
network = "udp4"
}
ip := net.IP(overlayIP.AsSlice())
conn, err := net.ListenUDP(network, &net.UDPAddr{IP: ip, Port: DefaultPort})
conn, err := net.ListenUDP("udp4", &net.UDPAddr{IP: ip, Port: DefaultPort})
if err != nil {
log.Debugf("pqkem: default port %d unavailable on %s (%v), using an ephemeral port", DefaultPort, overlayIP, err)
conn, err = net.ListenUDP(network, &net.UDPAddr{IP: ip, Port: 0})
conn, err = net.ListenUDP("udp4", &net.UDPAddr{IP: ip, Port: 0})
if err != nil {
return nil, fmt.Errorf("bind pqkem udp on overlay %s: %w", overlayIP, err)
}