Giter Site home page Giter Site logo

zeroconf's Introduction

ZeroConf: Service Discovery with mDNS

ZeroConf is a pure Golang library that employs Multicast DNS-SD for

  • browsing and resolving services in your network
  • registering own services

in the local network.

It basically implements aspects of the standards RFC 6762 (mDNS) and RFC 6763 (DNS-SD). Though it does not support all requirements yet, the aim is to provide a compliant solution in the long-term with the community.

By now, it should be compatible to Avahi (tested) and Apple's Bonjour (untested). Target environments: private LAN/Wifi, small or isolated networks.

GoDoc Go Report Card Tests

Install

Nothing is as easy as that:

$ go get -u github.com/grandcat/zeroconf

This package requires Go 1.7 (context in std lib) or later.

Browse for services in your local network

// Discover all services on the network (e.g. _workstation._tcp)
resolver, err := zeroconf.NewResolver(nil)
if err != nil {
    log.Fatalln("Failed to initialize resolver:", err.Error())
}

entries := make(chan *zeroconf.ServiceEntry)
go func(results <-chan *zeroconf.ServiceEntry) {
    for entry := range results {
        log.Println(entry)
    }
    log.Println("No more entries.")
}(entries)

ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
defer cancel()
err = resolver.Browse(ctx, "_workstation._tcp", "local.", entries)
if err != nil {
    log.Fatalln("Failed to browse:", err.Error())
}

<-ctx.Done()

A subtype may added to service name to narrow the set of results. E.g. to browse _workstation._tcp with subtype _windows, use_workstation._tcp,_windows.

See https://github.com/grandcat/zeroconf/blob/master/examples/resolv/client.go.

Lookup a specific service instance

// Example filled soon.

Register a service

server, err := zeroconf.Register("GoZeroconf", "_workstation._tcp", "local.", 42424, []string{"txtv=0", "lo=1", "la=2"}, nil)
if err != nil {
    panic(err)
}
defer server.Shutdown()

// Clean exit.
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
select {
case <-sig:
    // Exit by user
case <-time.After(time.Second * 120):
    // Exit by timeout
}

log.Println("Shutting down.")

Multiple subtypes may be added to service name, separated by commas. E.g _workstation._tcp,_windows has subtype _windows.

See https://github.com/grandcat/zeroconf/blob/master/examples/register/server.go.

Features and ToDo's

This list gives a quick impression about the state of this library. See what needs to be done and submit a pull request :)

  • Browse / Lookup / Register services
  • Multiple IPv6 / IPv4 addresses support
  • Send multiple probes (exp. back-off) if no service answers (*)
  • Timestamp entries for TTL checks
  • Compare new multicasts with already received services

Notes:

(*) The denoted features might not be perfectly standards compliant, but shouldn't cause any problems. Some tests showed improvements in overall robustness and performance with the features enabled.

Credits

Great thanks to hashicorp and to oleksandr and all contributing authors for the code this projects bases upon. Large parts of the code are still the same.

However, there are several reasons why I decided to create a fork of the original project: The previous project seems to be unmaintained. There are several useful pull requests waiting. I merged most of them in this project. Still, the implementation has some bugs and lacks some other features that make it quite unreliable in real LAN environments when running continously. Last but not least, the aim for this project is to build a solution that targets standard conformance in the long term with the support of the community. Though, resiliency should remain a top goal.

zeroconf's People

Contributors

a13xb avatar alice-samsara avatar brijohn avatar brutella avatar davidflowerday avatar derandereandi avatar ernoaapa avatar farshidtz avatar fuhrmannb avatar grandcat avatar jspiro avatar lanrat avatar leslie-wang avatar marten-seemann avatar nasuku avatar neilalexander avatar norbell avatar project0 avatar rdleon avatar tfheen avatar themihai avatar tmm1 avatar willstott101 avatar zephvr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zeroconf's Issues

Not able to discover/browse service using service subtype

  1. I have publish service with type and subtype by parsing comma separated list as (_os._udp , _windows) using
    example (https://github.com/grandcat/zeroconf/blob/master/examples/register/server.go)

  2. Able to discover/browse service using (https://github.com/grandcat/zeroconf/blob/master/examples/resolv/client.go) with default type as "_os._udp"

  3. But not able to discover service with the subtype.
    Provide comma separated list as (service = flag.String("service", "_os._udp, _windows", "Set the service type of the new service.")
    This gives result as "No more entries".

Devices not responding in time for Browse()

I'm trying to adapt the client example to my code and am finding that some of the devices I am browsing for do not always respond to the browse. (I'm testing with two devices that both identify as _osc._udp but even when both are up and running, grandcat/zeroconf Browse() sometimes only sees one of them).

My initial thought was to lengthen the timeout of the context to give the devices more time to respond, but that doesn't seem to help. In fact it seems that if a response is not received almost immediately after the Browse() query, it won't ever be received (I've tried increasing browse time up to 30seconds).

Thinking that it might be that the devices are sometimes slow to "wake up", I tried running two back to back browses - a short one to get their attention, and then a longer one to pick up the full set of responses. That also doesn't seem to help. In fact, sometimes the short 3second browse picks up both devices, but then the following longer 15second browse picks up only one of them.

My application can't "know" how many devices it might find, so I can't just keep browsing until I find "n" devices; I need to find some way to make the query and have reasonable confidence that I've found all the available devices.

I'm running a Bonjour browser (Discovery on macos) and it displays the devices practically in real time - as devices come online they get displayed as the go offline they disappear from its list -- unfortunately it's not open sourced so I can't see exactly how it's working internally.

Can anyone advise on best practice on the most reliable way to ensure a Browse() gets accurate response?

Any luck with Windows?

Seems like the UDP packet is never sent when running on a Windows platform (works fine with an RPi). Anyone aware of issues regarding Windows?

I'm using Wireshark to try and capture the packets, but there is nothing.

c:\repo\src\github.com\grandcat\zeroconf>go run examples/resolv/client.go
[DEBUG] sending the query
[DEBUG] 224.0.0.251:5353
[DEBUG] 224.0.0.251:5353
[DEBUG] 224.0.0.251:5353
[DEBUG] sending the query
[DEBUG] 224.0.0.251:5353
[DEBUG] 224.0.0.251:5353
[DEBUG] 224.0.0.251:5353
[DEBUG] sending the query
[DEBUG] 224.0.0.251:5353
[DEBUG] 224.0.0.251:5353
[DEBUG] 224.0.0.251:5353
2020/04/01 10:27:48 No more entries.

localhost only

Is it possible to only publish on localhost and not lan-wide, i.e. the equivalent of dns-sd -lo -P... ?
Use case is to prevent vpn addresses used by some clients from leaking onto the lan.

dns-sd -lo                          (Run dns-sd cmd using local only interface)

Wrong IP returned when querying from multiple interfaces

When multiple network interfaces are present (like with docker) zeroconf can return the wrong result.

I registered my server on the wlp2s0 interface only. However this is the result of a query:

avahi-browse -rv _test._tcp

= docker0 IPv4 myserver                                    _test._tcp     local
hostname = [comp.local]
address = [172.17.0.1]
port = [2808]
txt = ["txtv=0"]
= wlp2s0 IPv6 myserver                                    _test._tcp     local
hostname = [comp.local]
address = [192.168.193.138]
port = [2808]
txt = ["txtv=0"]
= wlp2s0 IPv4 myserver                                    _test._tcp     local
hostname = [comp.local]
address = [192.168.193.138]
port = [2808]
txt = ["txtv=0"]

The address returned by the docker0 interface is the IP of the docker0 interface which my service is not registered with.

The issue looks to be when a query originates from 172.17.0.1 the appendAddr function - https://github.com/grandcat/zeroconf/blob/master/server.go#L600 is passed the interface index of the caller as ifIndex.

For some reason the code gets the IP of this interface to add to the answer section:

	iface, _ := net.InterfaceByIndex(ifIndex)
	if iface != nil {
		v4, v6 = addrsForInterface(iface)
	} else {
		v4 = s.service.AddrIPv4
		v6 = s.service.AddrIPv6
	}

It seems like the code should only ever be using the else condition there:

		v4 = s.service.AddrIPv4
		v6 = s.service.AddrIPv6

I can create a pull request for this if this is the right fix?

Prevent package from data races

Before all, thanks for your helpful package!

I have a problem when I am launching (or testing) an app using this package: some data race appears when I activate data race detection (using -race argument).

An example, based on two examples of the README:

package main

import (
	"context"
	"github.com/grandcat/zeroconf"
	"log"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	// Preparing resolver
	resolver, err := zeroconf.NewResolver(nil)
	if err != nil {
		log.Fatalln("Failed to initialize resolver:", err.Error())
	}
	entries := make(chan *zeroconf.ServiceEntry)
	go func(results <-chan *zeroconf.ServiceEntry) {
		for entry := range results {
			log.Println(entry)
		}
		log.Println("No more entries.")
	}(entries)

	// Launching server
	server, err := zeroconf.Register("GoZeroconf", "_workstation._tcp", "local.", 42424, []string{"txtv=0", "lo=1", "la=2"}, nil)
	if err != nil {
		panic(err)
	}
	defer server.Shutdown()

	err = resolver.Browse(context.Background(), "_workstation._tcp", "local.", entries)
	if err != nil {
		log.Fatalln("Failed to browse:", err.Error())
	}

	sig := make(chan os.Signal, 1)
	signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
	select {
	case <-sig:
		// Exit by user
	}

	log.Println("Shutting down.")
}

On start, I've got these data races:

==================
WARNING: DATA RACE
Read at 0x00c4200849f0 by goroutine 12:
  github.com/grandcat/zeroconf.(*ServiceRecord).ServiceName()
      $GOPATH/src/github.com/grandcat/zeroconf/service.go:24 +0x5c
  github.com/grandcat/zeroconf.(*Server).handleQuestion()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:361 +0xab
  github.com/grandcat/zeroconf.(*Server).handleQuery()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:296 +0x345
  github.com/grandcat/zeroconf.(*Server).parsePacket()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:276 +0x1bd
  github.com/grandcat/zeroconf.(*Server).recv6()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:263 +0x18e

Previous write at 0x00c4200849f0 by goroutine 9:
  github.com/grandcat/zeroconf.(*ServiceRecord).ServiceName()
      $GOPATH/src/github.com/grandcat/zeroconf/service.go:25 +0x27d
  github.com/grandcat/zeroconf.(*ServiceRecord).ServiceInstanceName()
      $GOPATH/src/github.com/grandcat/zeroconf/service.go:39 +0x133
  github.com/grandcat/zeroconf.(*Server).probe()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:487 +0x96

Goroutine 12 (running) created at:
  github.com/grandcat/zeroconf.(*Server).mainloop()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:186 +0xc1

Goroutine 9 (running) created at:
  github.com/grandcat/zeroconf.Register()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:77 +0x8dd
  main.main()
      $GOPATH/src/sandbox/mdns/zeroconf_race.go:27 +0x1db
==================
==================
WARNING: DATA RACE
Read at 0x00c420084a10 by goroutine 11:
  github.com/grandcat/zeroconf.(*ServiceRecord).ServiceTypeName()
      $GOPATH/src/github.com/grandcat/zeroconf/service.go:47 +0x5c
  github.com/grandcat/zeroconf.(*Server).handleQuestion()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:355 +0x6f
  github.com/grandcat/zeroconf.(*Server).handleQuery()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:296 +0x345
  github.com/grandcat/zeroconf.(*Server).parsePacket()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:276 +0x1bd
  github.com/grandcat/zeroconf.(*Server).recv4()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:242 +0x18e

Previous write at 0x00c420084a10 by goroutine 12:
  github.com/grandcat/zeroconf.(*ServiceRecord).ServiceTypeName()
      $GOPATH/src/github.com/grandcat/zeroconf/service.go:52 +0x1c2
  github.com/grandcat/zeroconf.(*Server).handleQuestion()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:355 +0x6f
  github.com/grandcat/zeroconf.(*Server).handleQuery()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:296 +0x345
  github.com/grandcat/zeroconf.(*Server).parsePacket()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:276 +0x1bd
  github.com/grandcat/zeroconf.(*Server).recv6()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:263 +0x18e

Goroutine 11 (running) created at:
  github.com/grandcat/zeroconf.(*Server).mainloop()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:183 +0xfc

Goroutine 12 (running) created at:
  github.com/grandcat/zeroconf.(*Server).mainloop()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:186 +0xc1
==================
==================
WARNING: DATA RACE
Read at 0x00c420084a00 by goroutine 12:
  github.com/grandcat/zeroconf.(*ServiceRecord).ServiceInstanceName()
      $GOPATH/src/github.com/grandcat/zeroconf/service.go:38 +0x7d
  github.com/grandcat/zeroconf.(*Server).composeBrowsingAnswers()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:382 +0xaa
  github.com/grandcat/zeroconf.(*Server).handleQuestion()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:362 +0x1d9
  github.com/grandcat/zeroconf.(*Server).handleQuery()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:296 +0x345
  github.com/grandcat/zeroconf.(*Server).parsePacket()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:276 +0x1bd
  github.com/grandcat/zeroconf.(*Server).recv6()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:263 +0x18e

Previous write at 0x00c420084a00 by goroutine 9:
  github.com/grandcat/zeroconf.(*ServiceRecord).ServiceInstanceName()
      $GOPATH/src/github.com/grandcat/zeroconf/service.go:39 +0x27a
  github.com/grandcat/zeroconf.(*Server).probe()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:487 +0x96

Goroutine 12 (running) created at:
  github.com/grandcat/zeroconf.(*Server).mainloop()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:186 +0xc1

Goroutine 9 (running) created at:
  github.com/grandcat/zeroconf.Register()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:77 +0x8dd
  main.main()
      $GOPATH/src/sandbox/mdns/zeroconf_race.go:27 +0x1db
==================
2017/08/07 22:40:09 &{{GoZeroconf _workstation._tcp local.   } my-desktop.local. 42424 [txtv=0 lo=1 la=2] 3200 [192.168.0.1] [fe80::aaaa:bbbb:cccc:dddd]}

It seems that IPv4 thread and IPv6 thread are sharing some stuff together and can access it at the same time.

On exit (with SIGTERM signal), I've also another data race:

2017/08/07 22:41:27 Shutting down.
==================
WARNING: DATA RACE
Read at 0x00c420082f70 by goroutine 11:
  github.com/grandcat/zeroconf.(*Server).recv4()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:233 +0xa8

Previous write at 0x00c420082f70 by main goroutine:
  github.com/grandcat/zeroconf.(*Server).shutdown()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:216 +0xd1
  github.com/grandcat/zeroconf.(*Server).Shutdown()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:192 +0x38
  main.main()
      $GOPATH/src/sandbox/mdns/zeroconf_race.go:46 +0x49a

Goroutine 11 (running) created at:
  github.com/grandcat/zeroconf.(*Server).mainloop()
      $GOPATH/src/github.com/grandcat/zeroconf/server.go:183 +0xfc
==================
Found 4 data race(s)
exit status 66

Same kind of issue here between the main thread (calling s.ShutDown()) and the IPv4 thread.

My question is: how can we prevent application from data races?
I can try to propose a PR to prevent them but I'm not sure I have listed all the data races present in the library...

Using the client in parallel race condition

Currently the client's main loop calls the clients shutdown() method when the context is done preventing the client from being reused for multiple lookups.

If multiple clients are created and Browse() or Lookup() are called at near enough of the same time, or in parallel, occasionally one call may return the data from the other.

List all services

Was just taking a quick look, and I tried to write a quick sample to list all services on the network, but couldn't figure out how to do so. Any pointers of where I should read up or code I should check out to figure that out?

published ip address not change when I switch network

One mdns daemon service published ip address 10.240.138.74, which is its current ip address. like the screen shot
Screen Shot 2019-04-23 at 11 14 19 PM

After switch over network, its ip has changed to 10.0.1.2, but published ip address is still 10.240.138.74
Screen Shot 2019-04-23 at 10 59 58 PM

Resolver API design

I'm working on a clean shutdown procedure for the client / resolver, and I'm unsure how to proceed because I'm a bit confused by the API.

To start a mDNS client, you first create a new resolver, and then call Lookup or Browse:

r, _ := NewResolver()
entries := make(chan *ServiceEntry)
err := r.Browse(ctx, "service", "domain", entries)

This raises 2 problems:

  1. Both Browse and Lookup return immediately. The go routines started by these methods (including the Go routine that reads from the connection) is stopped eventually after the context is done, but there's no way to deterministically tell when this happened.
  2. Although the API seems to suggest otherwise, it's only possible to call Lookup / Browse once per Resolver instance, as both of them start reading from the UDPConn (and it only makes sense to read from a connection with a single Go routine).

I can see 2 fundamentally different ways to resolve this:

  1. Change the API in a way that doesn't suggest that Browse and Lookup can be called multiple times.
    1. This would probably mean to remove the Resolver, and expose Browse and Lookup as top-level functions.
    2. Make Browse and Lookup block until all Go routines have stopped.
  2. Make it possible to call Browse and Lookup concurrently. This would require us to have some demultiplexing logic, to associate received message with a particular lookup. This is easy for responses to a query (they come with an ID), but I'm not sure how one would implement this for the unrequested announcements that servers send out regularly.

Any thoughts, @grandcat and @Stebalien?

Service replies doesn't work correctly (in Windows?)

When I register a service and zeroconf is about to reply to queries it will try to send a response to all available network interfaces, however this doesn't seem to work correctly on Windows.
The message is sent multiple times to the loopback interface and not to any of the external interfaces.
I can therefore discover my service correctly on the local machine (using the dns-sd command line tool), but other machines cannot see the service.
If i look in Wireshark I can see that the incoming query is on my network interface but the replies are only ever sent to the loopback interface.

Is this a known problem? Any work-arounds or solutions?

IPv4 is sometimes empty in found service entries

Hi,

I have a question. With provided example code, if I start and stop client.go a couple times, IPv4 array would be empty in found service entry sometimes.

&{{service _foobar._tcp local. } router.home.local. 9000 [txtv=0 lo=1 la=2] 3200 [192.168.1.154] [fe80::ca2:1095:d9ab:c3e3]}

&{{service _foobar._tcp local. } router.home.local. 9000 [txtv=0 lo=1 la=2] 3200 [] [fe80::fe3a:efd5:f3dd:a9b6]}

Is this normal or a bug?

Thank you.

Cannot browse different domain than "local".

I managed to create a domain ("XXX.local"), where all my machines are registered, with AVAHI configuration. I'm able to see all of them with avahi-browse, no issue there.

None is listed with "client -domain "XXX.local".
(I compiled the "examples/resolv/client.go" as "client")

Adding some traces in the code, and trying to see where/how this can be fixed.
Possibly, a proposal for a fix can come before end of this week.

Provide custom ports for mdns server and client

I want to use server in network that already have mdns server.
To not interference with other servers I want to listen nonstandard ports.
Does it suitable for this package or I need to get own fork?

context cancelation is misused

Currently Register makes use of context but it doesn't seem to use the cancellation channel properly. Currently Browse doesn't return on context cancelation. Is it a known issue? At the first look I've found a lot of statements like this . I believe they are technically wrong as the code can't cancel the parent context. It cancels the child context which you basically ignore with _

_, cancel := context.WithCancel(ctx)
cancel()

Dropped mdns results

The latest package for us is always giving us inconsistent results from our devices.

Whereas this package:

https://github.com/hashicorp/mdns

This works every single time.

For anyone reading this, I would just choose to use hashicorp's library over this library until this is fixed. I dont mind recompiling a new build and re-running on my mdns devices shown here. Essentially I should get 5 unique models of omnistream shown which hashicorp's library consistently returns 5 items for us.

Here are my logs:

$ go run mdnsDiscover.go 


192.168.1.202 velocity.local.
192.168.1.252 model=at-omni-121
192.168.1.232 model=at-omni-521

192.168.1.253 model=at-omni-111
192.168.1.248 model=at-omni-122







Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.232 model=at-omni-521
192.168.1.230 model=at-omni-512
192.168.1.253 model=at-omni-111



Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.232 model=at-omni-521
192.168.1.230 model=at-omni-512
192.168.1.253 model=at-omni-111

Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.232 model=at-omni-521
192.168.1.253 model=at-omni-111
192.168.1.230 model=at-omni-512
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.230 model=at-omni-512
192.168.1.252 model=at-omni-121
192.168.1.232 model=at-omni-521
192.168.1.253 model=at-omni-111
192.168.1.248 model=at-omni-122
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.252 model=at-omni-121
192.168.1.232 model=at-omni-521
192.168.1.253 model=at-omni-111
192.168.1.248 model=at-omni-122
192.168.1.230 model=at-omni-512


Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.252 model=at-omni-121
192.168.1.232 model=at-omni-521
192.168.1.230 model=at-omni-512
192.168.1.248 model=at-omni-122
192.168.1.253 model=at-omni-111

Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.252 model=at-omni-121
192.168.1.232 model=at-omni-521
192.168.1.248 model=at-omni-122
192.168.1.253 model=at-omni-111
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.230 model=at-omni-512
192.168.1.248 model=at-omni-122
192.168.1.232 model=at-omni-521
192.168.1.253 model=at-omni-111
192.168.1.252 model=at-omni-121

Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.230 model=at-omni-512
192.168.1.232 model=at-omni-521
192.168.1.253 model=at-omni-111



Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
192.168.1.202 velocity.local.
192.168.1.230 model=at-omni-512
192.168.1.248 model=at-omni-122
192.168.1.232 model=at-omni-521
192.168.1.252 model=at-omni-121
Davids-MacBook-Pro:Downloads davidrenne$ go get github.com/hashicorp/mdns
Davids-MacBook-Pro:Downloads davidrenne$ vim mdnsDiscover.go 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
# command-line-arguments
./mdnsDiscover.go:12:9: undefined: fmt
Davids-MacBook-Pro:Downloads davidrenne$ vim mdnsDiscover.go 
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:52:21 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:52:22 [INFO] mdns: Closing client {0xc42000e030 0xc42000e038 0xc42000e040 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:52:22 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:61268: use of closed network connection
2018/12/20 15:52:22 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:52:41 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{VelocityGateway._ajows._tcp.local. velocity.local. 192.168.1.202 <nil> 42424 txtv=0|lo=1|la=2 [txtv=0 lo=1 la=2] 192.168.1.202 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:52:42 [INFO] mdns: Closing client {0xc42000e030 0xc42000e038 0xc42000e040 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:52:42 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:63117: use of closed network connection
2018/12/20 15:52:42 [ERR] mdns: Failed to read packet: read udp6 [::]:63118: use of closed network connection
2018/12/20 15:52:42 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:52:47 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:52:48 [INFO] mdns: Closing client {0xc4200ba020 0xc4200ba028 0xc4200ba030 <nil> true 0xc4200981e0 {1 0}}
2018/12/20 15:52:48 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:64006: use of closed network connection
2018/12/20 15:52:48 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
2018/12/20 15:52:48 [ERR] mdns: Failed to read packet: read udp6 [::]:64007: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:03 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
Got new entry: &{amzn\.dmgr:1E8EA5E8B62252574495D8E11427F98D:BtOSCVJEPv:922114._amzn-wplay._tcp.local. 192-168-1-12.local. 192.168.1.12 <nil> 40682 s=0|at=RCpejAcaXTm+|n=Fire TV|tr=tcp|sp=39759|pv=1|mv=2|v=2|a=0|u=1E8EA5E8B62252574495D8E11427F98D|ad=A2LWARUGJLBYEW|dpv=1|t=8|f=0 [s=0 at=RCpejAcaXTm+ n=Fire TV tr=tcp sp=39759 pv=1 mv=2 v=2 a=0 u=1E8EA5E8B62252574495D8E11427F98D ad=A2LWARUGJLBYEW dpv=1 t=8 f=0] 192.168.1.12 true true}
2018/12/20 15:53:04 [INFO] mdns: Closing client {0xc4200ac020 0xc4200ac028 0xc4200ac030 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:53:04 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:53944: use of closed network connection
2018/12/20 15:53:04 [ERR] mdns: Failed to read packet: read udp6 [::]:53945: use of closed network connection
2018/12/20 15:53:04 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:06 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:53:07 [INFO] mdns: Closing client {0xc4200ba020 0xc4200ba028 0xc4200ba030 <nil> true 0xc4200981e0 {1 0}}
2018/12/20 15:53:07 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:50376: use of closed network connection
2018/12/20 15:53:07 [ERR] mdns: Failed to read packet: read udp6 [::]:50377: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:09 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:53:10 [INFO] mdns: Closing client {0xc42000e030 0xc42000e038 0xc42000e040 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:53:10 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:64024: use of closed network connection
2018/12/20 15:53:10 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:13 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{VelocityGateway._ajows._tcp.local. velocity.local. 192.168.1.202 <nil> 42424 txtv=0|lo=1|la=2 [txtv=0 lo=1 la=2] 192.168.1.202 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
Got new entry: &{amzn\.dmgr:1E8EA5E8B62252574495D8E11427F98D:BtOSCVJEPv:922114._amzn-wplay._tcp.local. 192-168-1-12.local. 192.168.1.12 <nil> 40682 s=0|at=RCpejAcaXTm+|n=Fire TV|tr=tcp|sp=39759|pv=1|mv=2|v=2|a=0|u=1E8EA5E8B62252574495D8E11427F98D|ad=A2LWARUGJLBYEW|dpv=1|t=8|f=0 [s=0 at=RCpejAcaXTm+ n=Fire TV tr=tcp sp=39759 pv=1 mv=2 v=2 a=0 u=1E8EA5E8B62252574495D8E11427F98D ad=A2LWARUGJLBYEW dpv=1 t=8 f=0] 192.168.1.12 true true}
2018/12/20 15:53:14 [INFO] mdns: Closing client {0xc4200b2020 0xc4200b2028 0xc4200b2030 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:53:14 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:55832: use of closed network connection
2018/12/20 15:53:14 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:15 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{VelocityGateway._ajows._tcp.local. velocity.local. 192.168.1.202 <nil> 42424 txtv=0|lo=1|la=2 [txtv=0 lo=1 la=2] 192.168.1.202 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:53:16 [INFO] mdns: Closing client {0xc42000e030 0xc42000e038 0xc42000e040 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:53:16 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:49407: use of closed network connection
2018/12/20 15:53:16 [ERR] mdns: Failed to read packet: read udp6 [::]:49408: use of closed network connection
2018/12/20 15:53:16 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:18 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:53:19 [INFO] mdns: Closing client {0xc42000e030 0xc42000e038 0xc42000e040 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:53:19 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:51138: use of closed network connection
2018/12/20 15:53:19 [ERR] mdns: Failed to read packet: read udp6 [::]:51139: use of closed network connection
2018/12/20 15:53:19 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:27 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:53:28 [INFO] mdns: Closing client {0xc4200ac020 0xc4200ac028 0xc4200ac030 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:53:28 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:56674: use of closed network connection
2018/12/20 15:53:28 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:35 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{VelocityGateway._ajows._tcp.local. velocity.local. 192.168.1.202 <nil> 42424 txtv=0|lo=1|la=2 [txtv=0 lo=1 la=2] 192.168.1.202 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:53:36 [INFO] mdns: Closing client {0xc4200ba020 0xc4200ba028 0xc4200ba030 <nil> true 0xc4200981e0 {1 0}}
2018/12/20 15:53:36 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:65089: use of closed network connection
2018/12/20 15:53:36 [ERR] mdns: Failed to read packet: read udp6 [::]:65090: use of closed network connection
2018/12/20 15:53:36 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:53:53 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
Got new entry: &{amzn\.dmgr:1E8EA5E8B62252574495D8E11427F98D:BtOSCVJEPv:922114._amzn-wplay._tcp.local. 192-168-1-12.local. 192.168.1.12 <nil> 40682 s=0|at=RCpejAcaXTm+|n=Fire TV|tr=tcp|sp=39759|pv=1|mv=2|v=2|a=0|u=1E8EA5E8B62252574495D8E11427F98D|ad=A2LWARUGJLBYEW|dpv=1|t=8|f=0 [s=0 at=RCpejAcaXTm+ n=Fire TV tr=tcp sp=39759 pv=1 mv=2 v=2 a=0 u=1E8EA5E8B62252574495D8E11427F98D ad=A2LWARUGJLBYEW dpv=1 t=8 f=0] 192.168.1.12 true true}
2018/12/20 15:53:54 [INFO] mdns: Closing client {0xc42000e030 0xc42000e038 0xc42000e040 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:53:54 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:64112: use of closed network connection
2018/12/20 15:53:54 [ERR] mdns: Failed to read packet: read udp6 [::]:64113: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:54:21 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:54:22 [INFO] mdns: Closing client {0xc4200ba020 0xc4200ba028 0xc4200ba030 <nil> true 0xc4200981e0 {1 0}}
2018/12/20 15:54:22 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:59558: use of closed network connection
2018/12/20 15:54:22 [ERR] mdns: Failed to read packet: read udp6 [::]:59559: use of closed network connection
2018/12/20 15:54:22 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:55:12 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{VelocityGateway._ajows._tcp.local. velocity.local. 192.168.1.202 <nil> 42424 txtv=0|lo=1|la=2 [txtv=0 lo=1 la=2] 192.168.1.202 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:55:13 [INFO] mdns: Closing client {0xc4200b2020 0xc4200b2028 0xc4200b2030 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:55:13 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:50644: use of closed network connection
2018/12/20 15:55:13 [ERR] mdns: Failed to read packet: read udp6 [::]:50645: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:55:21 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:55:22 [INFO] mdns: Closing client {0xc4200ac020 0xc4200ac028 0xc4200ac030 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:55:22 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:61069: use of closed network connection
2018/12/20 15:55:22 [ERR] mdns: Failed to read packet: read udp6 [::]:61070: use of closed network connection
Davids-MacBook-Pro:Downloads davidrenne$ go run mdnsDiscover.go 
2018/12/20 15:55:27 [ERR] mdns: Failed to bind to udp6 port: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
Got new entry: &{at-omni-122-00487._ajows._tcp.local. at-omni-122-00487.local. 192.168.1.248 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-122|uniqueID=at-omni-122-00487 [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00487] 192.168.1.248 true true}
Got new entry: &{at-omni-121-00706._ajows._tcp.local. at-omni-121-00706.local. 192.168.1.252 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-121|uniqueID=at-omni-121-00706 [txtvers=1 ws=/wsapp/ model=at-omni-121 uniqueID=at-omni-121-00706] 192.168.1.252 true true}
Got new entry: &{at-omni-111-00459._ajows._tcp.local. at-omni-111-00459.local. 192.168.1.253 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-111|uniqueID=at-omni-111-00459 [txtvers=1 ws=/wsapp/ model=at-omni-111 uniqueID=at-omni-111-00459] 192.168.1.253 true true}
Got new entry: &{at-omni-512-00010._ajows._tcp.local. at-omni-512-00010.local. 192.168.1.230 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-512|uniqueID=at-omni-512-00010 [txtvers=1 ws=/wsapp/ model=at-omni-512 uniqueID=at-omni-512-00010] 192.168.1.230 true true}
Got new entry: &{at-omni-521-00046._ajows._tcp.local. at-omni-521-00046.local. 192.168.1.232 <nil> 80 txtvers=1|ws=/wsapp/|model=at-omni-521|uniqueID=at-omni-521-00046 [txtvers=1 ws=/wsapp/ model=at-omni-521 uniqueID=at-omni-521-00046] 192.168.1.232 true true}
Got new entry: &{ATL-UHD-CLSO-824._ahttp._tcp.local. ATL-UHD-CLSO-824.local. 192.168.1.99 <nil> 80  [] 192.168.1.99 true true}
2018/12/20 15:55:28 [INFO] mdns: Closing client {0xc4200b2020 0xc4200b2028 0xc4200b2030 <nil> true 0xc42008a1e0 {1 0}}
2018/12/20 15:55:28 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:58464: use of closed network connection
2018/12/20 15:55:28 [ERR] mdns: Failed to read packet: read udp6 [::]:58465: use of closed network connection
2018/12/20 15:55:28 [ERR] mdns: Failed to read packet: read udp4 0.0.0.0:5353: use of closed network connectio

The version which is your library is:

package main

import (
	"context"
	"fmt"
	"runtime/debug"
	"time"

	"github.com/grandcat/zeroconf"
)

// Runs the MDNS Scan once, waiting for 10 seconds for any MDNS packets to come in before closing
func queryMDNS() {
	// for i := 0; i < 1; i++ {
	resolver, err := zeroconf.NewResolver(nil)
	if err != nil {
		fmt.Println("drivers.go->queryMDNS", "Failed to initialize mdns resolver:"+err.Error())
	}

	if resolver == nil { //On a machine that cannot resolve a network interface.
		return
	}

	ajowsTCP := make(chan int)

	ajowsEntries := make(chan *zeroconf.ServiceEntry)
	go processMDNSResults(ajowsEntries, ajowsTCP)
	// go processMDNSResults(ajowsEntries)

	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*5000)
	// ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	err = resolver.Browse(ctx, "_ajows._tcp", "local.", ajowsEntries)
	if err != nil {
		fmt.Println("drivers.go->queryMDNS", "Failed to browse:"+err.Error())
		ajowsTCP <- 0
	}

	<-ajowsTCP
	// time.Sleep(time.Millisecond * 2000)
	// }

}

// Process the responses from the mdns scan
// func processMDNSResults(results <-chan *zeroconf.ServiceEntry) {
func processMDNSResults(results <-chan *zeroconf.ServiceEntry, wait chan int) {

	defer func() {
		if r := recover(); r != nil {
			fmt.Println("\n\nPanic Stack: " + string(debug.Stack()))
			return
		}
	}()

	// for omni latest firmwares, it has more than 3 Text fields including the model
	// and unique id fields
	for entry := range results {
		if len(entry.Text) > 3 {
			// entry.Text: [txtvers=1 ws=/wsapp/ model=at-omni-122 uniqueID=at-omni-122-00381]
			// entry.Text[2]: model=at-omni-122
			fmt.Println(entry.AddrIPv4[0], entry.Text[2])
		} else {
			fmt.Println(entry.AddrIPv4[0], entry.HostName)
		}
	}

	wait <- 0
}

func main() {

	queryMDNS()

}

And then I swapped the example with this better library:

package main

import (
	"fmt"
	"github.com/hashicorp/mdns"
)

func main() {

entriesCh := make(chan *mdns.ServiceEntry, 4)
go func() {
    for entry := range entriesCh {
        fmt.Printf("Got new entry: %v\n", entry)
    }
}()

// Start the lookup
mdns.Lookup("_ajows._tcp", entriesCh)
close(entriesCh)

}

I can not register in MacOS

The errors:

➜  mdns sudo ./server
Password:
2017/03/22 09:01:54 Remember linklocal IPv6: fe80::1
2017/03/22 09:01:54 Remember linklocal IPv6: fe80::c55:58e1:90f4:f802
2017/03/22 09:01:54 Remember linklocal IPv6: fe80::1429:cfff:fea0:ae11
2017/03/22 09:01:54 Remember linklocal IPv6: fe80::d4f:ac2e:41e4:dfd7
2017/03/22 09:01:54 Added global IPv6: fd1b:e880:6bdc:6975:d4f:ac2e:41e4:dfd7
2017/03/22 09:01:54 Remember linklocal IPv6: fe80::36c4:1de0:8605:a903
2017/03/22 09:01:54 Remember linklocal IPv6: fe80::444f:4c9:3ac7:6f77
2017/03/22 09:01:54 Remember linklocal IPv6: fe80::67e4:a86a:3ab3:7fa6
2017/03/22 09:01:54 Using multicast interfaces:  [{1 16384 lo0  up|loopback|multicast} {2 1280 gif0  pointtopoint|multicast} {4 1500 en0 4c:8d:79:f3:4d:0e up|broadcast|multicast} {6 2304 p2p0 0e:8d:79:f3:4d:0e up|broadcast|multicast} {7 1484 awdl0 16:29:cf:a0:ae:11 up|broadcast|multicast} {8 1500 bridge0 32:00:13:6a:fe:20 up|broadcast|multicast} {9 1380 utun0  up|pointtopoint|multicast} {10 2000 utun1  up|pointtopoint|multicast} {12 1380 utun3  up|pointtopoint|multicast} {11 1380 utun2  up|pointtopoint|multicast}]
2017/03/22 09:01:54 Udp4 JoinGroup failed for iface  {6 2304 p2p0 0e:8d:79:f3:4d:0e up|broadcast|multicast}
2017/03/22 09:01:54 Udp4 JoinGroup failed for iface  {7 1484 awdl0 16:29:cf:a0:ae:11 up|broadcast|multicast}
2017/03/22 09:01:54 Using multicast interfaces:  [{1 16384 lo0  up|loopback|multicast} {2 1280 gif0  pointtopoint|multicast} {4 1500 en0 4c:8d:79:f3:4d:0e up|broadcast|multicast} {6 2304 p2p0 0e:8d:79:f3:4d:0e up|broadcast|multicast} {7 1484 awdl0 16:29:cf:a0:ae:11 up|broadcast|multicast} {8 1500 bridge0 32:00:13:6a:fe:20 up|broadcast|multicast} {9 1380 utun0  up|pointtopoint|multicast} {10 2000 utun1  up|pointtopoint|multicast} {12 1380 utun3  up|pointtopoint|multicast} {11 1380 utun2  up|pointtopoint|multicast}]
2017/03/22 09:01:54 Udp6 JoinGroup failed for iface  {2 1280 gif0  pointtopoint|multicast}
2017/03/22 09:01:54 Udp6 JoinGroup failed for iface  {6 2304 p2p0 0e:8d:79:f3:4d:0e up|broadcast|multicast}
2017/03/22 09:01:54 Published service:
2017/03/22 09:01:54 - Name: GoZeroconfGo
2017/03/22 09:01:54 - Type: _workstation._tcp
2017/03/22 09:01:54 - Domain: local.
2017/03/22 09:01:54 - Port: 42424
2017/03/22 09:02:24 Shutting down.

unable to find device

I'm running the examples from readMe to register a service and browse the services on my network. For some reasons it's unable to find any service. Both programs (register and browse) are running on the same machine (a Mac OSX Sierra). Any idea could be wrong or how to debug it?


2017/03/07 19:20:05 Using multicast interfaces:  [{1 16384 lo0  up|loopback|multicast} {2 1280 gif0  pointtopoint|multicast} {4 1500 en0 04:0c:ce:dc:e1:d8 up|broadcast|multicast} {6 2304 p2p0 06:0c:ce:dc:e1:d8 up|broadcast|multicast} {7 1500 bridge0 b2:00:1f:26:e1:e0 broadcast|multicast} {8 2000 utun0  up|pointtopoint|multicast}]
2017/03/07 19:20:05 Udp4 JoinGroup failed for iface  {6 2304 p2p0 06:0c:ce:dc:e1:d8 up|broadcast|multicast}
2017/03/07 19:20:05 Udp4 JoinGroup failed for iface  {7 1500 bridge0 b2:00:1f:26:e1:e0 broadcast|multicast}
2017/03/07 19:20:05 Using multicast interfaces:  [{1 16384 lo0  up|loopback|multicast} {2 1280 gif0  pointtopoint|multicast} {4 1500 en0 04:0c:ce:dc:e1:d8 up|broadcast|multicast} {6 2304 p2p0 06:0c:ce:dc:e1:d8 up|broadcast|multicast} {7 1500 bridge0 b2:00:1f:26:e1:e0 broadcast|multicast} {8 2000 utun0  up|pointtopoint|multicast}]
2017/03/07 19:20:05 Udp6 JoinGroup failed for iface  {2 1280 gif0  pointtopoint|multicast}
2017/03/07 19:20:05 Udp6 JoinGroup failed for iface  {6 2304 p2p0 06:0c:ce:dc:e1:d8 up|broadcast|multicast}
2017/03/07 19:20:05 Udp6 JoinGroup failed for iface  {7 1500 bridge0 b2:00:1f:26:e1:e0 broadcast|multicast}

server.Shutdown() should print errors

zeroconf/server.go

Lines 195 to 198 in c2d1b41

// Shutdown closes all udp connections and unregisters the service
func (s *Server) Shutdown() {
s.shutdown()
}

Should be

if err := s.shutdown(); err != nil {
  log.Printf("Error shutting down the server: %v", err)
}

shutdown() itself should propagate or print errors from closing ipv4conn and ipv6conn.

os.hostname() returns hostname + tld on osx

This leads to strange hostnames with double tlds like machine.local.local, machine.lan.local etc when registering services on the macs I've tested (10.11 through 10.14, go v1.13.1).
hostname on the cli appears to exhibit the same behaviour, i.e. on a mac it returns machine.lan vs machine on linux, so maybe the issue is that os.Hostname() doesn't accept flags.
Not sure where this should be fixed. I've "hacked" a solution which seems to work: entry.HostName = strings.Split(entry.HostName, ".")[0], but am pretty sure this will break at some point.
Any ideas?

resolve failure

I have below test cases (based on gopkg.in/check.v1 framework), which 1st resolve happened before publish, and 2nd resolve after publish. If using same resolver instance, it will fail

	// by default mdns is not enabled
	mdnsName := "test--xxxxxxxxxxxx"
	mdnsService := "test--xxxx.tcp"
	mdnsDomain := "local."

	resolver, err := zeroconf.NewResolver(nil)
	c.Assert(err, IsNil)

	entries1 := make(chan *zeroconf.ServiceEntry)
	go func(results <-chan *zeroconf.ServiceEntry) {
		s := <-results
		c.Assert(s, IsNil)
	}(entries1)

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	c.Assert(resolver.Browse(ctx, mdnsService, mdnsDomain, entries1), IsNil)

	<-ctx.Done()
	cancel()

	go startMDNS(context.Background(), mdnsName, mdnsService, mdnsDomain)

	time.Sleep(time.Second)

	entries2 := make(chan *zeroconf.ServiceEntry)
	expectedResult := []*zeroconf.ServiceEntry{}
	go func(results <-chan *zeroconf.ServiceEntry) {
		s := <-results
		expectedResult = append(expectedResult, s)
	}(entries2)

	ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
	c.Assert(resolver.Browse(ctx, mdnsService, mdnsDomain, entries2), IsNil)

	<-ctx.Done()
	cancel()

	c.Assert(len(expectedResult), Equals, 1)
	c.Assert(expectedResult[0].Domain, Equals, mdnsDomain)
	c.Assert(expectedResult[0].Service, Equals, mdnsService)
	c.Assert(expectedResult[0].Instance, Equals, mdnsName)

but if 2nd resolve uses new resolver instance like below, it will success. Not sure if it is an issue, or it is designed like this way.

func (ts *mainSuite) TestMDNS(c *C) {
	// by default mdns is not enabled
	mdnsName := "test--xxxxxxxxxxxx"
	mdnsService := "test--xxxx.tcp"
	mdnsDomain := "local."

	resolver, err := zeroconf.NewResolver(nil)
	c.Assert(err, IsNil)

	entries1 := make(chan *zeroconf.ServiceEntry)
	go func(results <-chan *zeroconf.ServiceEntry) {
		s := <-results
		c.Assert(s, IsNil)
	}(entries1)

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	c.Assert(resolver.Browse(ctx, mdnsService, mdnsDomain, entries1), IsNil)

	<-ctx.Done()
	cancel()

	go startMDNS(context.Background(), mdnsName, mdnsService, mdnsDomain)

	time.Sleep(time.Second)

	resolver2, err := zeroconf.NewResolver(nil)
	c.Assert(err, IsNil)
	entries2 := make(chan *zeroconf.ServiceEntry)
	expectedResult := []*zeroconf.ServiceEntry{}
	go func(results <-chan *zeroconf.ServiceEntry) {
		s := <-results
		expectedResult = append(expectedResult, s)
	}(entries2)

	ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
	c.Assert(resolver2.Browse(ctx, mdnsService, mdnsDomain, entries2), IsNil)

	<-ctx.Done()
	cancel()

	c.Assert(len(expectedResult), Equals, 1)
	c.Assert(expectedResult[0].Domain, Equals, mdnsDomain)
	c.Assert(expectedResult[0].Service, Equals, mdnsService)
	c.Assert(expectedResult[0].Instance, Equals, mdnsName)
}

Query: TTL value set to 120

As per code https://github.com/grandcat/zeroconf/blob/c2d1b4121200e6bf8490af806aa6f3dc6d37446b/server.go#L613 TTL value is set as 120 always, with a comment that states RFC6762 Section 10 says A/AAAA records SHOULD use TTL of 120s

RFC6762 Section 10 further says - The recommended TTL value for other Multicast DNS resource records is 75 minutes

I wanted to know if the TTL value for other DNS resource records is accounted for here?

How to exit resolver.Browse func safely

// Browse for all services of a given type in a given domain.
func (r *Resolver) Browse(ctx context.Context, service, domain string, entries chan<- *ServiceEntry) error {
params := defaultParams(service)
if domain != "" {
params.Domain = domain
}
params.Entries = entries
ctx, cancel := context.WithCancel(ctx)
go r.c.mainloop(ctx, params)

err := r.c.query(params)
if err != nil {
	cancel()
	return err
}
// If previous probe was ok, it should be fine now. In case of an error later on,
// the entries' queue is closed.
go func() {
	if err := r.c.periodicQuery(ctx, params); err != nil {
		cancel()
	}
}()

return nil

}

This function creates two main coroutines. When the two coroutines exit from browse, how can they exit safely

Data Race when calling Server.SetText() from another goroutine.

The Go Data Race Detector detects a data race.
More specifically, the data race is in Server.composeBrowsingAnswers().

	txt := &dns.TXT{
		Hdr: dns.RR_Header{
			Name:   s.service.ServiceInstanceName(),
			Rrtype: dns.TypeTXT,
			Class:  dns.ClassINET,
			Ttl:    s.ttl,
		},
		Txt: s.service.Text, // Data race here
	}

I think this is because the Server runs on it's own goroutine.
So when you modify the Service field from another goroutine, a data race will occur.

adding ip to .local dns zone

Announcing services is easy and works fine - but does zerconf also allow for adding IPs to the zones like e.g. .local? Similar to what dnsmasq does.

return only one record

I'm compile example resolver and server to test. I'm run server on two host and on third run resolver.
I'm always get only one record from one host. But not two. May be resolver after receives single response for query does not return others?

IPv6 link-local addresses lose interface information

As a client using the browse API, I receive a list of IPv6 address in the ServiceEntry.
An IPv6 link-local address is only useful when the corresponding interface (e.g., eth1) is known as well. The ServiceEntry contains link-local IPv6 address, but the interface name is missing.

Is there a way to retrieve the interface name for each IPv6 address (link-local ones at least)?

Only one entry returned for servers with the same name

If there are multiple instances of the same server (same name) running either on different hosts or, for example, on the same host listening on different ports, then only one entry is returned by resolver.

I think it is the same problem as described by closed issue 39

Resolve mdns address support?

Is it possible to use this library to resolve mdns .local addresses?

As far as I can tell this is not possible with this library, but its part of mdns and probably should be supported if its not currently.

For example, can I resolve foo.local. to an A or AAAA address? irregardless of instance or service?

android support

any idea why the client is not finding any records on Android?

Registering a service on multiple interfaces

Please try to publish a service on a system with multiple network interfaces, for example on my system I have this

ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 48:2a:e3:2c:9b:1b brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.50/24 brd 192.168.1.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet 192.168.10.25/24 brd 192.168.10.255 scope global noprefixroute enp0s31f6
       valid_lft forever preferred_lft forever
    inet6 fe80::c268:29fe:cfb4:b590/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: wlp0s20f3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 48:f1:7f:72:a8:17 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.230/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp0s20f3
       valid_lft 83098sec preferred_lft 83098sec
    inet6 fe80::cf06:8821:ab8a:f08a/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

so basically two network interfaces and the wired network interface has 2 ip address.

I tryed something like this:

service, err := zeroconf.Register(
	"SFTPGo portable",  
	"_sftp-ssh._tcp",   
	"local.",           
	sftpdConf.BindPort,
	meta,               
	nil,    // register on all network interfaces
)

the service can be found but the ip address are wrong:

avahi-browse -ar
+ wlp0s20f3 IPv6 SFTPGo portable                               SFTP File Transfer   local
+ wlp0s20f3 IPv4 SFTPGo portable                               SFTP File Transfer   local
+ enp0s31f6 IPv6 SFTPGo portable                               SFTP File Transfer   local
+ enp0s31f6 IPv4 SFTPGo portable                               SFTP File Transfer   local
= wlp0s20f3 IPv6 SFTPGo portable                               SFTP File Transfer   local
   hostname = [p1.local]
   address = [192.168.1.230]
   port = [50399]
   txt = ["password=world" "version=0.1.0"]
= wlp0s20f3 IPv4 SFTPGo portable                               SFTP File Transfer   local
   hostname = [p1.local]
   address = [192.168.1.230]
   port = [50399]
   txt = ["password=world" "version=0.1.0"]
= enp0s31f6 IPv6 SFTPGo portable                               SFTP File Transfer   local
   hostname = [p1.local]
   address = [192.168.1.230]
   port = [50399]
   txt = ["password=world" "version=0.1.0"]
= enp0s31f6 IPv4 SFTPGo portable                               SFTP File Transfer   local
   hostname = [p1.local]
   address = [192.168.1.230]
   port = [50399]
   txt = ["password=world" "version=0.1.0"]

the network interface enp0s31f6 is advertised with the ip of wlp0s20f3 and ip 192.168.1.50 and 192.168.10.25 are not advertised

zeroconf: failed to send probe: dns: bad rdata

Using this library as a dependency to brutella/hc#86, after the commit 4b2319b there appear to be issues with MDNS:

2017/08/20 12:13:10 [ERR] zeroconf: failed to send probe: dns: bad rdata
2017/08/20 12:13:11 [ERR] zeroconf: failed to send probe: dns: bad rdata
2017/08/20 12:13:11 [ERR] zeroconf: failed to send announcement: dns: bad rdata
2017/08/20 12:13:12 [ERR] zeroconf: failed to send announcement: dns: bad rdata

The last working revision was 8ad40c89978a7b2102ff98743831bf5cdb454f9f.

I am not entirely sure if this is a usage error or an issue with the library.

Service discovery doesn't work without internet

I'm trying to run the zeroconf server to broadcast on a WiFi network that doesn't have internet, but it doesn't seem to work properly.

As soon as I broadcast on a network that has internet, I can discover the broadcasted server/service.

Is this a known issue?

Known issues?

The readme says:

the implementation has some bugs and lacks some other features that make it quite unreliable in real LAN environments when running continously

Can you elaborate on what these bugs/missing features are? I would like to help fix them. I am currently using a fork of oleksandr/bonjour and seeing similar reliability issues after running for a few hours.

Fatal error if no IPv6 support

Hello there,

Found a problem when trying to register a service on a kernel that's missing IPv6 support.

2016/12/11 18:03:54 Using multicast interfaces:  [{2 1500 enp0s3 08:00:27:03:67:19 up|broadcast|multicast}]
2016/12/11 18:03:54 [ERR] bonjour: Failed to bind to udp6 mutlicast: listen udp6 [ff02::]:5353: socket: address family not supported by protocol
2016/12/11 18:03:54 Fatal error: listen udp6 [ff02::]:5353: socket: address family not supported by protocol
exit status 1

It's probably due to these lines where it tries to join on UDP6:
https://github.com/grandcat/zeroconf/blob/master/server.go#L173

Looked into how to fix this, but couldn't find a platform agnostic solution.
One way would be to do it like: https://github.com/abursavich/ipsupport
Maybe make it possible to disable IPv6 in the library, or just ignore the error if IPv4 succeeds?

Duplicate domain in HostName entry if os.Hostname() already contains domain

Given the examples I see the following output on MacOS 10.14.6

# go run examples/register/server.go --wait 0     
2020/10/23 05:30:54 Published service:
2020/10/23 05:30:54 - Name: GoZeroconfGo
2020/10/23 05:30:54 - Type: _workstation._tcp
2020/10/23 05:30:54 - Domain: local.
2020/10/23 05:30:54 - Port: 42424
# go run examples/resolv/client.go
2020/10/23 05:31:34 &{{GoZeroconfGo _workstation._tcp [] local _workstation._tcp.local. GoZeroconfGo._workstation._tcp.local. _services._dns-sd._udp.local.} studios-iMac.local.local. 42424 [txtv=0 lo=1 la=2] 3200 [192.168.9.102] [fe80::1 2a02:8070:d380:5900:2b:59f6:77ac:63d7 2a02:8070:d380:5900:4c95:9246:35b5:3886 fe80::f1ec:e3e6:f4ad:5413]}
2020/10/23 05:31:36 No more entries.

I expected to HostName of the entry to be studios-iMac.local. instead of studios-iMac.local.local..

The hostname returned by the kernel at https://github.com/grandcat/zeroconf/blob/master/server.go#L46 is studios-iMac.local and the domain suffix is added at https://github.com/grandcat/zeroconf/blob/master/server.go#L53.

Multiple interfaces: associate IPs with interface

If there are multiple interfaces, all IPs are merged together and send as a list of addresses to all clients.
As some addresses from one interface may not be reachable via an other interface, outgoing packets have to be personalized by egress interface.

Pluggable Logging

Thank you for this package, first.

The only thing that is currently bothering me is the excessive amount of logging in the package code: this somehow pollutes my own display :-)
When will the code be considered stable, will it be possible to reduce or eliminate this logging, or be able to adjust the display?

Cannot discover service - how to debug?

I'm exposing a service using Python zeroconf library but I'm not able to discover it in the client written in Go with this library. I'm able to discover the Python service using avahi-browse on Linux, Bonjour Browser for Windows and Discovery for iOS. I've tried to run it on the same machine or on different machines (Linux, Windows), no way. Do you have any hint to debug this issue?
This is the source code I written:

Server:

import logging
import socket
import sys
from time import sleep
import netifaces as ni

from zeroconf import ServiceInfo, Zeroconf

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    if len(sys.argv) > 1:
        assert sys.argv[1:] == ['--debug']
        logging.getLogger('zeroconf').setLevel(logging.DEBUG)
    
    desc = {'path': '/~paulsm/'}

    info = ServiceInfo("_http._tcp.local.",
                       "A web server._http._tcp.local.",
                       socket.inet_aton("192.168.1.101"), 80, 1,10,
                       desc, "webserver.local.")

    zeroconf = Zeroconf()
    print("Registration of a service, press Ctrl-C to exit...")
    zeroconf.register_service(info)
    try:
        while True:
            sleep(0.1)
    except KeyboardInterrupt:
        pass
    finally:
        print("Unregistering...")
        zeroconf.unregister_service(info)
        zeroconf.close()

Client:

package main

import (
	"context"
	"flag"
	"log"
	"time"
	"fmt"
	"github.com/grandcat/zeroconf"
)

func main() {
	// Discover all services on the network (e.g. _workstation._tcp)
	resolver, err := zeroconf.NewResolver(nil)
	if err != nil {
		log.Fatalln("Failed to initialize resolver:", err.Error())
	}

	entries := make(chan *zeroconf.ServiceEntry)
	go func(results <-chan *zeroconf.ServiceEntry) {
		for entry := range results {
			str := fmt.Sprintf("Service: %s - Text: %s - Address: %s - Hostname: %s - Domain: %s", entry.Service, entry.Text, entry.AddrIPv4, entry.HostName, entry.Domain)
			log.Println(str)
		}
		log.Println("No more entries.")
	}(entries)

	ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
	defer cancel()
	err = resolver.Browse(ctx, "_http._tcp", "local.", entries)
	if err != nil {
		log.Fatalln("Failed to browse:", err.Error())
	}
	<-ctx.Done()
}

Thanks for your help.

Allow custom host name in registration

Not sure if this is compliant or not, but it would be cool to set a custom host name when registering a service. This would allow creating a server, which can be found under a predefined domain - e.g. through a web browser.

Right now it looks like this case will always be true, because you cannot actually set HostName. It will thus fallback to os.Hostname() and thus depends on the environment. I have tested it using other values and it resolves and works fine under macOS.

I would be more than happy to create a PR, if you don't mind.

This would probably also help with the use case in #42.

Client does not find the server

If the client starts after the server, the client does not find the service.
The server needs to start after the client for it to work....
I'm using the server on a Linux and the client on a windows.
Any solutions?

Ability to custom logger

It would be nice to be able to customize the logger in the package depending on the logger used by the top project. It is useful to have a unique way to log thing in the same application. By default, logger should be the standard Go log.

For instance, I mostly use in my projects logrus that uses the same methods as standard Go logger but with a different render.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.