From 35b91cb66a41e36fc8c32eaf52da5aa143bf14b7 Mon Sep 17 00:00:00 2001 From: Andrew Dunham Date: Thu, 15 Aug 2024 14:09:44 -0400 Subject: [PATCH] fixup! wgengine/magicsock: actually use AF_PACKET socket for raw disco Signed-off-by: Andrew Dunham Change-Id: I769276478e5b2e62ee0cb25ccc76e96d34fadc88 --- wgengine/magicsock/magicsock_linux.go | 30 ++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/wgengine/magicsock/magicsock_linux.go b/wgengine/magicsock/magicsock_linux.go index 64b7e2645..ebb0988d1 100644 --- a/wgengine/magicsock/magicsock_linux.go +++ b/wgengine/magicsock/magicsock_linux.go @@ -11,6 +11,7 @@ import ( "io" "net" "net/netip" + "strings" "syscall" "time" @@ -364,7 +365,7 @@ func (c *Conn) receiveDisco(pc *socket.Conn, isIPV6 bool) { for { n, src, err := pc.Recvfrom(ctx, buf[:], 0) if debugRawDiscoReads() { - logf("read from %v = (%v, %v)", src, n, err) + logf("read from %s = (%v, %v)", printSockaddr(src), n, err) } if err != nil && (errors.Is(err, net.ErrClosed) || err.Error() == "use of closed file") { // EOF; no need to print an error @@ -420,6 +421,33 @@ func (c *Conn) receiveDisco(pc *socket.Conn, isIPV6 bool) { } } +// printSockaddr is a helper function to pretty-print various sockaddr types. +func printSockaddr(sa unix.Sockaddr) string { + switch sa := sa.(type) { + case *unix.SockaddrInet4: + addr := netip.AddrFrom4(sa.Addr) + return netip.AddrPortFrom(addr, uint16(sa.Port)).String() + case *unix.SockaddrInet6: + addr := netip.AddrFrom16(sa.Addr) + return netip.AddrPortFrom(addr, uint16(sa.Port)).String() + case *unix.SockaddrLinklayer: + hwaddr := sa.Addr[:sa.Halen] + + var buf strings.Builder + fmt.Fprintf(&buf, "link(%d):[", sa.Protocol) + for i, b := range hwaddr { + if i > 0 { + buf.WriteByte(':') + } + fmt.Fprintf(&buf, "%02x", b) + } + buf.WriteByte(']') + return buf.String() + default: + return fmt.Sprintf("unknown(%T)", sa) + } +} + // trySetSocketBuffer attempts to set SO_SNDBUFFORCE and SO_RECVBUFFORCE which // can overcome the limit of net.core.{r,w}mem_max, but require CAP_NET_ADMIN. // It falls back to the portable implementation if that fails, which may be