diff --git a/core/config/config.go b/core/config/config.go index 6d7258a..4fb7e2a 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -14,9 +14,10 @@ type Config struct { path string // tun - TUNName string - MTU int - LocalAddr netip.Prefix + TUNName string + MTU int + LocalAddr netip.Prefix + EnableBroadcast bool // libp2p PrivateKey *PrivateKey diff --git a/core/engine/routine.go b/core/engine/routine.go index 32c66d0..9f7a9a5 100644 --- a/core/engine/routine.go +++ b/core/engine/routine.go @@ -2,6 +2,7 @@ package engine import ( "fmt" + "net/netip" "github.com/wlynxg/NetHive/core/protocol" ) @@ -24,6 +25,12 @@ func (e *Engine) RoutineTUNReader() { e.log.Warnf("[RoutineTUNReader] drop packet, because %s", err) continue } + + if (ip.Dst().IsLinkLocalMulticast() || ip.Dst().IsMulticast()) && !e.cfg.EnableBroadcast { + e.log.Debugf("discard broadcast packets: %s -> %s", ip.Src(), ip.Dst()) + continue + } + payload := Payload{ Src: ip.Src(), Dst: ip.Dst(), @@ -63,6 +70,30 @@ func (e *Engine) RoutineRouteTableWriter() { for payload = range e.devReader { var conn PacketChan + if (payload.Dst.IsLinkLocalMulticast() || payload.Dst.IsMulticast()) && e.cfg.EnableBroadcast { + e.routeTable.m.Range(func(key string, value netip.Prefix) bool { + if c, ok := e.routeTable.id.Load(key); ok { + conn = c + } else { + conn = make(PacketChan, ChanSize) + e.routeTable.id.Store(key, conn) + e.routeTable.addr.Store(value.Addr(), conn) + go func() { + defer e.routeTable.id.Delete(key) + defer e.routeTable.addr.Delete(value.Addr()) + e.addConn(conn, key) + }() + } + select { + case conn <- payload: + default: + e.log.Warnf("[RoutineRouteTableWriter] drop packet: %s, because the sending queue is already full", payload.Dst) + } + return true + }) + continue + } + e.log.Debugf("%s -> %s", payload.Src, payload.Dst) c, ok := e.routeTable.addr.Load(payload.Dst) if ok {