implement a config option for mdns
Jeromy committed
Apr 22, 2015 at 00:55 UTC
001b7ab714533f7c5ff9355f118abbb39921cc0b
5 files changed
+77
-29
core/core.go
+24
-7
@@ -220,7 +220,8 @@ func standardWithRouting(r repo.Repo, online bool, routingOption RoutingOption,
220
}
221
222
if online {
223
- if err := n.startOnlineServices(ctx, routingOption, hostOption); err != nil {
223
+ do := setupDiscoveryOption(n.Repo.Config().Discovery)
224
+ if err := n.startOnlineServices(ctx, routingOption, hostOption, do); err != nil {
225
return nil, err
226
}
227
} else {
@@ -232,7 +233,7 @@ func standardWithRouting(r repo.Repo, online bool, routingOption RoutingOption,
233
}
234
}
235
235
-func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption RoutingOption, hostOption HostOption) error {
236
+func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption RoutingOption, hostOption HostOption, do DiscoveryOption) error {
237
238
if n.PeerHost != nil { // already online.
239
return errors.New("node already online")
@@ -264,16 +265,30 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin
265
go n.Reprovider.ProvideEvery(ctx, kReprovideFrequency)
266
267
// setup local discovery
267
- service, err := discovery.NewMdnsService(n.PeerHost)
268
- if err != nil {
269
- return err
268
+ if do != nil {
269
+ service, err := do(n.PeerHost)
270
+ if err != nil {
271
+ return err
272
+ }
273
+ service.RegisterNotifee(n)
274
+ n.Discovery = service
275
}
271
- service.RegisterNotifee(n)
272
- n.Discovery = service
276
277
return n.Bootstrap(DefaultBootstrapConfig)
278
}
279
280
+func setupDiscoveryOption(d config.Discovery) DiscoveryOption {
281
+ if d.MDNS.Enabled {
282
+ return func(h p2phost.Host) (discovery.Service, error) {
283
+ if d.MDNS.Interval == 0 {
284
+ d.MDNS.Interval = 5
285
+ }
286
+ return discovery.NewMdnsService(h, time.Duration(d.MDNS.Interval)*time.Second)
287
+ }
288
+ }
289
+ return nil
290
+}
291
+
292
func (n *IpfsNode) HandlePeerFound(p peer.PeerInfo) {
293
log.Warning("trying peer info: ", p)
294
ctx, _ := context.WithTimeout(n.Context(), time.Second*10)
@@ -540,4 +555,6 @@ func constructDHTRouting(ctx context.Context, host p2phost.Host, dstore ds.Threa
555
556
type RoutingOption func(context.Context, p2phost.Host, ds.ThreadSafeDatastore) (routing.IpfsRouting, error)
557
558
+type DiscoveryOption func(p2phost.Host) (discovery.Service, error)
559
+
560
var DHTOption RoutingOption = constructDHTRouting
p2p/discovery/mdns.go
+36
-22
@@ -1,13 +1,14 @@
1
package discovery
2
3
import (
4
+ "errors"
5
"fmt"
6
"io"
7
"io/ioutil"
8
golog "log"
9
"net"
9
- "strconv"
10
- "strings"
10
+ //"strconv"
11
+ //"strings"
12
"sync"
13
"time"
14
@@ -22,7 +23,6 @@ import (
23
24
var log = u.Logger("mdns")
25
25
-const LookupFrequency = time.Second * 5
26
const ServiceTag = "discovery.ipfs.io"
27
28
type Service interface {
@@ -42,33 +42,45 @@ type mdnsService struct {
42
43
lk sync.Mutex
44
notifees []Notifee
45
+ interval time.Duration
46
}
47
47
-func NewMdnsService(peerhost host.Host) (Service, error) {
48
+func getDialableListenAddr(ph host.Host) (*net.TCPAddr, error) {
49
+ for _, addr := range ph.Addrs() {
50
+ na, err := manet.ToNetAddr(addr)
51
+ if err != nil {
52
+ continue
53
+ }
54
+ tcp, ok := na.(*net.TCPAddr)
55
+ if ok {
56
+ return tcp, nil
57
+ }
58
+ }
59
+ return nil, errors.New("failed to find good external addr from peerhost")
60
+}
61
+
62
+func NewMdnsService(peerhost host.Host, interval time.Duration) (Service, error) {
63
64
// TODO: dont let mdns use logging...
65
golog.SetOutput(ioutil.Discard)
66
52
- // determine my local swarm port
67
+ var ipaddrs []net.IP
68
port := 4001
54
- for _, addr := range peerhost.Addrs() {
55
- parts := strings.Split(addr.String(), "/")
56
- fmt.Println("parts len: ", len(parts))
57
- if len(parts) == 5 && parts[3] == "tcp" {
58
- n, err := strconv.Atoi(parts[4])
59
- if err != nil {
60
- return nil, err
61
- }
62
- port = n
63
- break
64
- }
69
+
70
+ addr, err := getDialableListenAddr(peerhost)
71
+ if err != nil {
72
+ log.Warning(err)
73
+ } else {
74
+ ipaddrs = []net.IP{addr.IP}
75
+ port = addr.Port
76
}
77
+
78
fmt.Println("using port: ", port)
79
80
myid := peerhost.ID().Pretty()
81
82
info := []string{myid}
71
- service, err := mdns.NewMDNSService(myid, ServiceTag, "", "", port, nil, info)
83
+ service, err := mdns.NewMDNSService(myid, ServiceTag, "", "", port, ipaddrs, info)
84
if err != nil {
85
return nil, err
86
}
@@ -80,9 +92,10 @@ func NewMdnsService(peerhost host.Host) (Service, error) {
92
}
93
94
s := &mdnsService{
83
- server: server,
84
- service: service,
85
- host: peerhost,
95
+ server: server,
96
+ service: service,
97
+ host: peerhost,
98
+ interval: interval,
99
}
100
101
go s.pollForEntries()
@@ -95,7 +108,7 @@ func (m *mdnsService) Close() error {
108
}
109
110
func (m *mdnsService) pollForEntries() {
98
- ticker := time.NewTicker(LookupFrequency)
111
+ ticker := time.NewTicker(m.interval)
112
for {
113
select {
114
case <-ticker.C:
@@ -110,7 +123,7 @@ func (m *mdnsService) pollForEntries() {
123
qp.Domain = "local"
124
qp.Entries = entriesCh
125
qp.Service = ServiceTag
113
- qp.Timeout = time.Second * 3
126
+ qp.Timeout = time.Second * 5
127
128
err := mdns.Query(&qp)
129
if err != nil {
@@ -122,6 +135,7 @@ func (m *mdnsService) pollForEntries() {
135
}
136
137
func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) {
138
+ fmt.Println("handling entry!")
139
mpeer, err := peer.IDB58Decode(e.Info)
140
if err != nil {
141
log.Warning("Error parsing peer ID from mdns entry: ", err)
repo/config/config.go
+1
@@ -21,6 +21,7 @@ type Config struct {
21
Addresses Addresses // local node's addresses
22
Mounts Mounts // local node's mount points
23
Version Version // local node's version management
24
+ Discovery Discovery // local node's discovery mechanisms
25
Bootstrap []string // local nodes's bootstrap peer addresses
26
Tour Tour // local node's tour position
27
Gateway Gateway // local node's gateway server options
repo/config/discovery.go
new
+12
@@ -0,0 +1,12 @@
1
+package config
2
+
3
+type Discovery struct {
4
+ MDNS MDNS
5
+}
6
+
7
+type MDNS struct {
8
+ Enabled bool
9
+
10
+ // Time in seconds between discovery rounds
11
+ Interval int
12
+}
repo/config/init.go
+4
@@ -48,6 +48,10 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) {
48
SupernodeRouting: *snr,
49
Datastore: *ds,
50
Identity: identity,
51
+ Discovery: Discovery{MDNS{
52
+ Enabled: true,
53
+ Interval: 10,
54
+ }},
55
Log: Log{
56
MaxSizeMB: 250,
57
MaxBackups: 1,