package multicast import ( "log" "net" "net/netip" "time" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) var addr = net.UDPAddrFromAddrPort(netip.AddrPortFrom( netip.AddrFrom4([4]byte{224, 0, 0, 157}), 4560)) func Broadcast( selfVPNIP netip.Addr, pubKey wgtypes.Key, wgPort uint16, signKey *[64]byte, ) { for { broadcastInner(selfVPNIP, pubKey, wgPort, signKey) time.Sleep(errorTimeout) } } func broadcastInner(selfVPNIP netip.Addr, pubKey wgtypes.Key, wgPort uint16, signKey *[64]byte) { conn, err := net.ListenMulticastUDP("udp", nil, addr) if err != nil { log.Printf("[MCBroadcast] bind: %v", err) return } defer conn.Close() buf := make([]byte, BufferSize) packet := Packet{ PeerIP: selfVPNIP.As4()[3], WGPubKey: pubKey, WGPort: wgPort, } // Re-sign on each send so the timestamp is fresh; a stale timestamp would be // dropped by receivers' freshness gate. send := func() error { packet.Timestamp = time.Now().Unix() payload := packet.marshal(buf, signKey) _, err := conn.WriteToUDP(payload, addr) return err } if err := send(); err != nil { log.Printf("[MCBroadcast] write: %v", err) } for range time.Tick(broadcastInterval) { if err := send(); err != nil { log.Printf("[MCBroadcast] write: %v", err) return } } }