Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 42 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"
"io/ioutil"
"log"
"net"
"os"
"strconv"
"strings"
Expand Down Expand Up @@ -51,6 +52,18 @@ const portsTTL = time.Second * 60
// This is interval at which mDNS queries are made.
const discoveryInterval = time.Second * 15

// IP address used to check if we're connected to a local network
var ipv4Addr = &net.UDPAddr{
IP: net.ParseIP("224.0.0.251"),
Port: 5353,
}

// IP address used to check if IPv6 is supported by the local network
var ipv6Addr = &net.UDPAddr{
IP: net.ParseIP("ff02::fb"),
Port: 5353,
}

// MDNSDiscovery is the implementation of the network pluggable-discovery
type MDNSDiscovery struct {
cancelFunc func()
Expand Down Expand Up @@ -120,18 +133,39 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
// neither we have to any to do it, we can only wait for it
// to return.
queriesChan := make(chan *mdns.ServiceEntry)
params := &mdns.QueryParam{
Service: mdnsServiceName,
Domain: "local",
Timeout: discoveryInterval,
Entries: queriesChan,
WantUnicastResponse: false,
DisableIPv6: true,
}

ctx, cancel := context.WithCancel(context.Background())
go func() {
defer close(queriesChan)

disableIPv6 := false
// Check if the current network supports IPv6
mconn6, err := net.ListenMulticastUDP("udp6", nil, ipv6Addr)
if err != nil {
disableIPv6 = true
} else {
mconn6.Close()
}

// We must check if we're connected to a local network, if we don't
// the subsequent mDNS query would fail and return an error.
mconn4, err := net.ListenMulticastUDP("udp4", nil, ipv4Addr)
if err != nil {
return
}
// If we managed to open a connection close it, mdns.Query opens
// another one on the same IP address we use and it would fail
// if we leave this open.
mconn4.Close()

params := &mdns.QueryParam{
Service: mdnsServiceName,
Domain: "local",
Timeout: discoveryInterval,
Entries: queriesChan,
WantUnicastResponse: false,
DisableIPv6: disableIPv6,
}
for {
if err := mdns.Query(params); err != nil {
errorCB("mdns lookup error: " + err.Error())
Expand Down