package node import ( "log" "net" "net/netip" "time" "golang.org/x/crypto/nacl/sign" ) var ( signOverhead = 64 multicastIP = netip.AddrFrom4([4]byte{224, 0, 0, 157}) multicastAddr = net.UDPAddrFromAddrPort(netip.AddrPortFrom(multicastIP, 4560)) ) func localDiscovery() { conn, err := net.ListenMulticastUDP("udp", nil, multicastAddr) if err != nil { log.Printf("Failed to bind to multicast address: %v", err) return } go sendLocalDiscovery(conn) go recvLocalDiscovery(conn) } func sendLocalDiscovery(conn *net.UDPConn) { var ( buf1 = make([]byte, bufferSize) buf2 = make([]byte, bufferSize) ) for range time.Tick(16 * time.Second) { signed := buildLocalDiscoveryPacket(buf1, buf2) if _, err := conn.WriteToUDP(signed, multicastAddr); err != nil { log.Printf("Failed to write multicast UDP packet: %v", err) } } } func recvLocalDiscovery(conn *net.UDPConn) { var ( raw = make([]byte, bufferSize) buf = make([]byte, bufferSize) ) for { n, remoteAddr, err := conn.ReadFromUDPAddrPort(raw[:bufferSize]) if err != nil { log.Fatalf("Failed to read from UDP port (multicast): %v", err) } raw = raw[:n] h, ok := openLocalDiscoveryPacket(raw, buf) if !ok { continue } pkt := controlPacket{ SrcIP: h.SourceIP, SrcAddr: remoteAddr, Payload: localDiscoveryPacket{}, } select { case controlPackets[h.SourceIP] <- pkt: default: } } } func buildLocalDiscoveryPacket(buf1, buf2 []byte) []byte { h := header{ StreamID: controlStreamID, Counter: 0, SourceIP: localIP, DestIP: 255, } out := buf1[:headerSize] h.Marshal(out) return sign.Sign(buf2[:0], out, (*[64]byte)(privSignKey)) } func openLocalDiscoveryPacket(raw, buf []byte) (h header, ok bool) { if len(raw) != headerSize+signOverhead { ok = false return } h.Parse(raw[signOverhead:]) route := routingTable[h.SourceIP].Load() if route == nil || route.PubSignKey == nil { ok = false return } _, ok = sign.Open(buf[:0], raw, (*[32]byte)(route.PubSignKey)) return }