1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- 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
- }
- }
- }
- }()
- }
|