package multicast import ( "log" "net" "net/netip" "time" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) func Broadcast( selfVPNIP netip.Addr, pubKey wgtypes.Key, wgPort uint16, signKey *[64]byte, ) { for { broadcast(selfVPNIP, pubKey, wgPort, signKey) time.Sleep(errorTimeout) } } func broadcast(selfVPNIP netip.Addr, pubKey wgtypes.Key, wgPort uint16, signKey *[64]byte) { addr := multicastAddr(selfVPNIP) log.Printf("[MC Broadcast] Sending on %v.", addr) conn, err := net.ListenMulticastUDP("udp", nil, addr) if err != nil { log.Printf("[MC Broadcast] 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("[MC Broadcast] write: %v", err) } for range time.Tick(broadcastInterval) { if err := send(); err != nil { log.Printf("[MC Broadcast] write: %v", err) return } } }