diff options
author | Jakob Borg <jakob@nym.se> | 2014-05-15 00:29:18 -0300 |
---|---|---|
committer | Jakob Borg <jakob@nym.se> | 2014-05-15 00:33:40 -0300 |
commit | adbd0b1834861d84552fb3f2843c9fb559f268a5 (patch) | |
tree | 9a78a56e2d80dec854874a843585c26902204ac6 /beacon | |
parent | 3e34fc66e639f96087829ab7980c24fe5441a115 (diff) |
Rename mc -> beacon
Diffstat (limited to 'beacon')
-rw-r--r-- | beacon/beacon.go | 127 | ||||
-rw-r--r-- | beacon/cmd/mctest/main.go | 34 | ||||
-rw-r--r-- | beacon/debug.go | 13 |
3 files changed, 174 insertions, 0 deletions
diff --git a/beacon/beacon.go b/beacon/beacon.go new file mode 100644 index 0000000000..e8ab78bdd9 --- /dev/null +++ b/beacon/beacon.go @@ -0,0 +1,127 @@ +package beacon + +import "net" + +type recv struct { + data []byte + src net.Addr +} + +type dst struct { + intf string + conn *net.UDPConn +} + +type Beacon struct { + conn *net.UDPConn + port int + conns []dst + inbox chan []byte + outbox chan recv +} + +func New(port int) (*Beacon, error) { + conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: port}) + if err != nil { + return nil, err + } + b := &Beacon{ + conn: conn, + port: port, + inbox: make(chan []byte), + outbox: make(chan recv, 16), + } + + go b.reader() + go b.writer() + + return b, nil +} + +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) reader() { + var bs = make([]byte, 65536) + for { + n, addr, err := b.conn.ReadFrom(bs) + if err != nil { + l.Warnln("Beacon read:", err) + return + } + if debug { + l.Debugf("recv %d bytes from %s", n, addr) + } + select { + case b.outbox <- recv{bs[:n], addr}: + default: + if debug { + l.Debugln("dropping message") + } + } + } +} + +func (b *Beacon) writer() { + for bs := range b.inbox { + + addrs, err := net.InterfaceAddrs() + if err != nil { + l.Warnln("Beacon: interface addresses:", err) + continue + } + + var dsts []net.IP + for _, addr := range addrs { + if iaddr, ok := addr.(*net.IPNet); ok && iaddr.IP.IsGlobalUnicast() { + baddr := bcast(iaddr) + dsts = append(dsts, baddr.IP) + } + } + + if len(dsts) == 0 { + // Fall back to the general IPv4 broadcast address + dsts = append(dsts, net.IP{0xff, 0xff, 0xff, 0xff}) + } + + if debug { + l.Debugln("addresses:", dsts) + } + + for _, ip := range dsts { + dst := &net.UDPAddr{IP: ip, Port: b.port} + + _, err := b.conn.WriteTo(bs, dst) + if err != nil { + if debug { + l.Debugln(err) + } + return + } + if debug { + l.Debugf("sent %d bytes to %s", len(bs), dst) + } + } + } +} + +func bcast(ip *net.IPNet) *net.IPNet { + var bc = &net.IPNet{} + bc.IP = make([]byte, len(ip.IP)) + copy(bc.IP, ip.IP) + bc.Mask = ip.Mask + + offset := len(bc.IP) - len(bc.Mask) + for i := range bc.IP { + if i-offset > 0 { + bc.IP[i] = ip.IP[i] | ^ip.Mask[i-offset] + } + } + return bc +} diff --git a/beacon/cmd/mctest/main.go b/beacon/cmd/mctest/main.go new file mode 100644 index 0000000000..d334b4929a --- /dev/null +++ b/beacon/cmd/mctest/main.go @@ -0,0 +1,34 @@ +package main + +import ( + "encoding/binary" + "log" + "time" + + "github.com/calmh/syncthing/mc" +) + +func main() { + b, err := mc.NewBeacon(21025) + if err != nil { + log.Fatal(err) + } + go func() { + for { + bs, addr := b.Recv() + log.Printf("Received %d bytes from %s: %x %x", len(bs), addr, bs[:8], bs[8:]) + } + }() + go func() { + bs := [16]byte{} + binary.BigEndian.PutUint64(bs[:], uint64(time.Now().UnixNano())) + log.Printf("My ID: %x", bs[:8]) + for { + binary.BigEndian.PutUint64(bs[8:], uint64(time.Now().UnixNano())) + b.Send(bs[:]) + log.Printf("Sent %d bytes", len(bs[:])) + time.Sleep(10 * time.Second) + } + }() + select {} +} diff --git a/beacon/debug.go b/beacon/debug.go new file mode 100644 index 0000000000..07c7c4be6b --- /dev/null +++ b/beacon/debug.go @@ -0,0 +1,13 @@ +package beacon + +import ( + "os" + "strings" + + "github.com/calmh/syncthing/logger" +) + +var ( + debug = strings.Contains(os.Getenv("STTRACE"), "beacon") || os.Getenv("STTRACE") == "all" + l = logger.DefaultLogger +) |