// 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 } } }
// receives and prints discovery announcements func recv(bc beacon.Interface) { seen := make(map[string]bool) for { data, src := bc.Recv() if m := binary.BigEndian.Uint32(data); m != discover.Magic { log.Printf("Incorrect magic %x in announcement from %v", m, src) continue } var ann discover.Announce ann.Unmarshal(data[4:]) if ann.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 := ann.ID.String() + src.String() if all || !seen[key] { log.Printf("Announcement from %v\n", src) log.Printf(" %v at %s\n", ann.ID, strings.Join(ann.Addresses, ", ")) seen[key] = true } } }
// sends fake discovery announcements once every second func send(bc beacon.Interface) { ann := discover.Announce{ ID: myID, Addresses: []string{"tcp://fake.example.com:12345"}, } bs, _ := ann.Marshal() for { bc.Send(bs) time.Sleep(time.Second) } }
func handleAnnounceV2(db *leveldb.DB, addr *net.UDPAddr, buf []byte) error { var pkt discover.Announce err := pkt.UnmarshalXDR(buf) if err != nil && err != io.EOF { return err } if debug { log.Printf("<- %v %#v", addr, pkt) } lock.Lock() announces++ lock.Unlock() ip := addr.IP.To4() if ip == nil { ip = addr.IP.To16() } var addrs []address now := time.Now().Unix() for _, addr := range pkt.This.Addresses { tip := addr.IP if len(tip) == 0 { tip = ip } addrs = append(addrs, address{ ip: tip, port: addr.Port, seen: now, }) } var id protocol.DeviceID if len(pkt.This.ID) == 32 { // Raw node ID copy(id[:], pkt.This.ID) } else { err = id.UnmarshalText(pkt.This.ID) if err != nil { return err } } update(db, id, addrs) return nil }
// 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) } }
func (s *querysrv) handleQuery(conn *net.UDPConn, addr *net.UDPAddr, buf []byte) error { var pkt discover.Query err := pkt.UnmarshalXDR(buf) if err != nil { return err } var id protocol.DeviceID copy(id[:], pkt.DeviceID) addrs, err := s.getAddresses(id) if err != nil { return err } relays, err := s.getRelays(id) if err != nil { return err } if len(addrs) > 0 { ann := discover.Announce{ Magic: discover.AnnouncementMagic, This: discover.Device{ ID: pkt.DeviceID, Addresses: addrs, Relays: relays, }, } tb, err := ann.MarshalXDR() if err != nil { return fmt.Errorf("QueryV2 response marshal: %v", err) } _, err = conn.WriteToUDP(tb, addr) if err != nil { return fmt.Errorf("QueryV2 response write: %v", err) } globalStats.Answer() } return nil }
func (s *querysrv) handleAnnounce(addr *net.UDPAddr, buf []byte) error { var pkt discover.Announce err := pkt.UnmarshalXDR(buf) if err != nil && err != io.EOF { return err } var id protocol.DeviceID copy(id[:], pkt.This.ID) if id == protocol.LocalDeviceID { return fmt.Errorf("Rejecting announce for local device ID from %v", addr) } tx, err := s.db.Begin() if err != nil { return err } for _, annAddr := range pkt.This.Addresses { uri, err := url.Parse(annAddr) if err != nil { continue } host, port, err := net.SplitHostPort(uri.Host) if err != nil { continue } if len(host) == 0 { uri.Host = net.JoinHostPort(addr.IP.String(), port) } if err := s.updateAddress(tx, id, uri.String()); err != nil { tx.Rollback() return err } } _, err = tx.Stmt(s.prep["deleteRelay"]).Exec(id.String()) if err != nil { tx.Rollback() return err } for _, relay := range pkt.This.Relays { uri, err := url.Parse(relay.Address) if err != nil { continue } _, err = tx.Stmt(s.prep["insertRelay"]).Exec(id.String(), uri, relay.Latency) if err != nil { tx.Rollback() return err } } if err := s.updateDevice(tx, id); err != nil { tx.Rollback() return err } return tx.Commit() }
func handleQueryV2(db *leveldb.DB, conn *net.UDPConn, addr *net.UDPAddr, buf []byte) error { var pkt discover.Query err := pkt.UnmarshalXDR(buf) if err != nil { return err } if debug { log.Printf("<- %v %#v", addr, pkt) } var id protocol.DeviceID if len(pkt.DeviceID) == 32 { // Raw node ID copy(id[:], pkt.DeviceID) } else { err = id.UnmarshalText(pkt.DeviceID) if err != nil { return err } } lock.Lock() queries++ lock.Unlock() addrs := get(db, id) now := time.Now().Unix() if len(addrs) > 0 { ann := discover.Announce{ Magic: discover.AnnouncementMagic, This: discover.Device{ ID: pkt.DeviceID, }, } for _, addr := range addrs { if now-addr.seen > cacheLimitSeconds { continue } ann.This.Addresses = append(ann.This.Addresses, discover.Address{IP: addr.ip, Port: addr.port}) } if debug { log.Printf("-> %v %#v", addr, pkt) } if len(ann.This.Addresses) == 0 { return nil } tb, err := ann.MarshalXDR() if err != nil { log.Println("QueryV2 response marshal:", err) return nil } _, err = conn.WriteToUDP(tb, addr) if err != nil { log.Println("QueryV2 response write:", err) return nil } lock.Lock() answered++ lock.Unlock() } return nil }