Skip to content

Commit 7e8f939

Browse files
authored
Merge pull request #20 from arduino/scerza/handle-no-network
Fix discovery returning errors if not connected to network
2 parents ff9f349 + f27a2c6 commit 7e8f939

File tree

1 file changed

+42
-8
lines changed

1 file changed

+42
-8
lines changed

main.go

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"io/ioutil"
2424
"log"
25+
"net"
2526
"os"
2627
"strconv"
2728
"strings"
@@ -51,6 +52,18 @@ const portsTTL = time.Second * 60
5152
// This is interval at which mDNS queries are made.
5253
const discoveryInterval = time.Second * 15
5354

55+
// IP address used to check if we're connected to a local network
56+
var ipv4Addr = &net.UDPAddr{
57+
IP: net.ParseIP("224.0.0.251"),
58+
Port: 5353,
59+
}
60+
61+
// IP address used to check if IPv6 is supported by the local network
62+
var ipv6Addr = &net.UDPAddr{
63+
IP: net.ParseIP("ff02::fb"),
64+
Port: 5353,
65+
}
66+
5467
// MDNSDiscovery is the implementation of the network pluggable-discovery
5568
type MDNSDiscovery struct {
5669
cancelFunc func()
@@ -120,18 +133,39 @@ func (d *MDNSDiscovery) StartSync(eventCB discovery.EventCallback, errorCB disco
120133
// neither we have to any to do it, we can only wait for it
121134
// to return.
122135
queriesChan := make(chan *mdns.ServiceEntry)
123-
params := &mdns.QueryParam{
124-
Service: mdnsServiceName,
125-
Domain: "local",
126-
Timeout: discoveryInterval,
127-
Entries: queriesChan,
128-
WantUnicastResponse: false,
129-
DisableIPv6: true,
130-
}
131136

132137
ctx, cancel := context.WithCancel(context.Background())
133138
go func() {
134139
defer close(queriesChan)
140+
141+
disableIPv6 := false
142+
// Check if the current network supports IPv6
143+
mconn6, err := net.ListenMulticastUDP("udp6", nil, ipv6Addr)
144+
if err != nil {
145+
disableIPv6 = true
146+
} else {
147+
mconn6.Close()
148+
}
149+
150+
// We must check if we're connected to a local network, if we don't
151+
// the subsequent mDNS query would fail and return an error.
152+
mconn4, err := net.ListenMulticastUDP("udp4", nil, ipv4Addr)
153+
if err != nil {
154+
return
155+
}
156+
// If we managed to open a connection close it, mdns.Query opens
157+
// another one on the same IP address we use and it would fail
158+
// if we leave this open.
159+
mconn4.Close()
160+
161+
params := &mdns.QueryParam{
162+
Service: mdnsServiceName,
163+
Domain: "local",
164+
Timeout: discoveryInterval,
165+
Entries: queriesChan,
166+
WantUnicastResponse: false,
167+
DisableIPv6: disableIPv6,
168+
}
135169
for {
136170
if err := mdns.Query(params); err != nil {
137171
errorCB("mdns lookup error: " + err.Error())

0 commit comments

Comments
 (0)