Use IPv4 multicast discovery
This commit is contained in:
91
mc/beacon.go
Normal file
91
mc/beacon.go
Normal file
@@ -0,0 +1,91 @@
|
||||
package mc
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
)
|
||||
|
||||
type recv struct {
|
||||
data []byte
|
||||
src net.Addr
|
||||
}
|
||||
|
||||
type Beacon struct {
|
||||
group string
|
||||
port int
|
||||
conns []*net.UDPConn
|
||||
inbox chan []byte
|
||||
outbox chan recv
|
||||
}
|
||||
|
||||
func NewBeacon(group string, port int) *Beacon {
|
||||
b := &Beacon{
|
||||
group: group,
|
||||
port: port,
|
||||
inbox: make(chan []byte),
|
||||
outbox: make(chan recv),
|
||||
}
|
||||
go b.run()
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Beacon) Send(data []byte) {
|
||||
b.inbox <- data
|
||||
}
|
||||
|
||||
func (b *Beacon) Recv() ([]byte, net.Addr) {
|
||||
recv := <-b.outbox
|
||||
return recv.data, recv.src
|
||||
}
|
||||
|
||||
func (b *Beacon) run() {
|
||||
group := &net.UDPAddr{IP: net.ParseIP(b.group), Port: b.port}
|
||||
|
||||
intfs, err := net.Interfaces()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, intf := range intfs {
|
||||
intf := intf
|
||||
|
||||
if debug {
|
||||
dlog.Printf("trying interface %q", intf.Name)
|
||||
}
|
||||
conn, err := net.ListenMulticastUDP("udp4", &intf, group)
|
||||
if err != nil {
|
||||
if debug {
|
||||
dlog.Printf("listen for multicast group on %q: %v", intf.Name, err)
|
||||
}
|
||||
} else {
|
||||
b.conns = append(b.conns, conn)
|
||||
}
|
||||
}
|
||||
|
||||
for _, conn := range b.conns {
|
||||
conn := conn
|
||||
go func() {
|
||||
for {
|
||||
var bs = make([]byte, 1500)
|
||||
n, addr, err := conn.ReadFrom(bs)
|
||||
if err != nil {
|
||||
dlog.Println(err)
|
||||
return
|
||||
}
|
||||
b.outbox <- recv{bs[:n], addr}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
for bs := range b.inbox {
|
||||
for _, conn := range b.conns {
|
||||
_, err := conn.WriteTo(bs, group)
|
||||
if err != nil {
|
||||
dlog.Println(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
Reference in New Issue
Block a user