Co-authored-by: jdl <jdl@desktop> Co-authored-by: jdl <jdl@crumpington.com> Reviewed-on: #3
71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
package peer
|
|
|
|
import (
|
|
"log"
|
|
"net"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
func runMCReader(
|
|
rt *atomic.Pointer[routingTable],
|
|
handleControlMsg func(destIP byte, msg any),
|
|
) {
|
|
for {
|
|
runMCReaderInner(rt, handleControlMsg)
|
|
time.Sleep(broadcastErrorTimeoutInterval)
|
|
}
|
|
}
|
|
|
|
func runMCReaderInner(
|
|
rt *atomic.Pointer[routingTable],
|
|
handleControlMsg func(destIP byte, msg any),
|
|
) {
|
|
var (
|
|
raw = newBuf()
|
|
buf = newBuf()
|
|
logf = func(s string, args ...any) {
|
|
log.Printf("[MCReader] "+s, args...)
|
|
}
|
|
)
|
|
|
|
conn, err := net.ListenMulticastUDP("udp", nil, multicastAddr)
|
|
if err != nil {
|
|
logf("Failed to bind to multicast address: %v", err)
|
|
return
|
|
}
|
|
|
|
for {
|
|
conn.SetReadDeadline(time.Now().Add(32 * time.Second))
|
|
n, remoteAddr, err := conn.ReadFromUDPAddrPort(raw[:bufferSize])
|
|
if err != nil {
|
|
logf("Failed to read from UDP port): %v", err)
|
|
return
|
|
}
|
|
|
|
raw = raw[:n]
|
|
h, ok := headerFromLocalDiscoveryPacket(raw)
|
|
if !ok {
|
|
logf("Failed to open discovery packet?")
|
|
continue
|
|
}
|
|
|
|
peer := rt.Load().Peers[h.SourceIP]
|
|
if peer.PubSignKey == nil {
|
|
logf("No signing key for peer %d.", h.SourceIP)
|
|
continue
|
|
}
|
|
|
|
if !verifyLocalDiscoveryPacket(raw, buf, peer.PubSignKey) {
|
|
logf("Invalid signature from peer: %d", h.SourceIP)
|
|
continue
|
|
}
|
|
|
|
msg := controlMsg[packetLocalDiscovery]{
|
|
SrcIP: h.SourceIP,
|
|
SrcAddr: remoteAddr,
|
|
}
|
|
handleControlMsg(h.SourceIP, msg)
|
|
}
|
|
}
|