|
|
@@ -0,0 +1,126 @@
|
|
|
+// Copyright (C) 2016 The Syncthing Authors.
|
|
|
+//
|
|
|
+// This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
+// You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
+
|
|
|
+package main
|
|
|
+
|
|
|
+import (
|
|
|
+ "bytes"
|
|
|
+ "crypto/rand"
|
|
|
+ "flag"
|
|
|
+ "log"
|
|
|
+ "strings"
|
|
|
+ "time"
|
|
|
+
|
|
|
+ "github.com/syncthing/syncthing/lib/beacon"
|
|
|
+ "github.com/syncthing/syncthing/lib/discover"
|
|
|
+ "github.com/syncthing/syncthing/lib/protocol"
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ all = false // print all packets, not just first from each device/source
|
|
|
+ fake = false // send fake packets to lure out other devices faster
|
|
|
+ mc = "[ff12::8384]:21027"
|
|
|
+ bc = 21027
|
|
|
+)
|
|
|
+
|
|
|
+var (
|
|
|
+ // Static prefix that we use when generating fake device IDs, so that we
|
|
|
+ // can recognize them ourselves. Also makes the device ID start with
|
|
|
+ // "STPROBE-" which is humanly recognizeable.
|
|
|
+ randomPrefix = []byte{148, 223, 23, 4, 148}
|
|
|
+
|
|
|
+ // Our random, fake, device ID that we use when sending announcements.
|
|
|
+ myID = randomDeviceID()
|
|
|
+)
|
|
|
+
|
|
|
+func main() {
|
|
|
+ flag.BoolVar(&all, "all", all, "Print all received announcements (not only first)")
|
|
|
+ flag.BoolVar(&fake, "fake", fake, "Send fake announcements")
|
|
|
+ flag.StringVar(&mc, "mc", mc, "IPv6 multicast address")
|
|
|
+ flag.IntVar(&bc, "bc", bc, "IPv4 broadcast port number")
|
|
|
+ flag.Parse()
|
|
|
+
|
|
|
+ if fake {
|
|
|
+ log.Println("My ID:", protocol.DeviceIDFromBytes(myID))
|
|
|
+ }
|
|
|
+
|
|
|
+ runbeacon(beacon.NewMulticast(mc), fake)
|
|
|
+ runbeacon(beacon.NewBroadcast(bc), fake)
|
|
|
+
|
|
|
+ select {}
|
|
|
+}
|
|
|
+
|
|
|
+func runbeacon(bc beacon.Interface, fake bool) {
|
|
|
+ go bc.Serve()
|
|
|
+ go recv(bc)
|
|
|
+ if fake {
|
|
|
+ go send(bc)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// receives and prints discovery announcements
|
|
|
+func recv(bc beacon.Interface) {
|
|
|
+ seen := make(map[string]bool)
|
|
|
+ for {
|
|
|
+ data, src := bc.Recv()
|
|
|
+ var ann discover.Announce
|
|
|
+ ann.UnmarshalXDR(data)
|
|
|
+
|
|
|
+ if bytes.Equal(ann.This.ID, myID) {
|
|
|
+ // This is one of our own fake packets, don't print it.
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // Print announcement details for the first packet from a given
|
|
|
+ // device ID and source address, or if -all was given.
|
|
|
+ key := string(ann.This.ID) + src.String()
|
|
|
+ if all || !seen[key] {
|
|
|
+ log.Printf("Announcement from %v\n", src)
|
|
|
+ log.Printf(" %v at %s\n", protocol.DeviceIDFromBytes(ann.This.ID), strings.Join(addrStrs(ann.This), ", "))
|
|
|
+
|
|
|
+ for _, dev := range ann.Extra {
|
|
|
+ log.Printf(" %v at %s\n", protocol.DeviceIDFromBytes(dev.ID), strings.Join(addrStrs(dev), ", "))
|
|
|
+ }
|
|
|
+ seen[key] = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// sends fake discovery announcements once every second
|
|
|
+func send(bc beacon.Interface) {
|
|
|
+ ann := discover.Announce{
|
|
|
+ Magic: discover.AnnouncementMagic,
|
|
|
+ This: discover.Device{
|
|
|
+ ID: myID,
|
|
|
+ Addresses: []discover.Address{
|
|
|
+ {URL: "tcp://fake.example.com:12345"},
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+ bs, _ := ann.MarshalXDR()
|
|
|
+
|
|
|
+ for {
|
|
|
+ bc.Send(bs)
|
|
|
+ time.Sleep(time.Second)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// returns the list of address URLs
|
|
|
+func addrStrs(dev discover.Device) []string {
|
|
|
+ ss := make([]string, len(dev.Addresses))
|
|
|
+ for i, addr := range dev.Addresses {
|
|
|
+ ss[i] = addr.URL
|
|
|
+ }
|
|
|
+ return ss
|
|
|
+}
|
|
|
+
|
|
|
+// returns a random but recognizeable device ID
|
|
|
+func randomDeviceID() []byte {
|
|
|
+ var id [32]byte
|
|
|
+ copy(id[:], randomPrefix)
|
|
|
+ rand.Read(id[len(randomPrefix):])
|
|
|
+ return id[:]
|
|
|
+}
|