From 001b7ab714533f7c5ff9355f118abbb39921cc0b Mon Sep 17 00:00:00 2001 From: Jeromy <jeromyj@gmail.com> Date: Wed, 22 Apr 2015 00:55:31 -0700 Subject: [PATCH] implement a config option for mdns --- core/core.go | 31 ++++++++++++++++----- p2p/discovery/mdns.go | 58 +++++++++++++++++++++++++--------------- repo/config/config.go | 1 + repo/config/discovery.go | 12 +++++++++ repo/config/init.go | 4 +++ 5 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 repo/config/discovery.go diff --git a/core/core.go b/core/core.go index 6ab1d2ffc..25ca7a04e 100644 --- a/core/core.go +++ b/core/core.go @@ -220,7 +220,8 @@ func standardWithRouting(r repo.Repo, online bool, routingOption RoutingOption, } if online { - if err := n.startOnlineServices(ctx, routingOption, hostOption); err != nil { + do := setupDiscoveryOption(n.Repo.Config().Discovery) + if err := n.startOnlineServices(ctx, routingOption, hostOption, do); err != nil { return nil, err } } else { @@ -232,7 +233,7 @@ func standardWithRouting(r repo.Repo, online bool, routingOption RoutingOption, } } -func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption RoutingOption, hostOption HostOption) error { +func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption RoutingOption, hostOption HostOption, do DiscoveryOption) error { if n.PeerHost != nil { // already online. return errors.New("node already online") @@ -264,16 +265,30 @@ func (n *IpfsNode) startOnlineServices(ctx context.Context, routingOption Routin go n.Reprovider.ProvideEvery(ctx, kReprovideFrequency) // setup local discovery - service, err := discovery.NewMdnsService(n.PeerHost) - if err != nil { - return err + if do != nil { + service, err := do(n.PeerHost) + if err != nil { + return err + } + service.RegisterNotifee(n) + n.Discovery = service } - service.RegisterNotifee(n) - n.Discovery = service return n.Bootstrap(DefaultBootstrapConfig) } +func setupDiscoveryOption(d config.Discovery) DiscoveryOption { + if d.MDNS.Enabled { + return func(h p2phost.Host) (discovery.Service, error) { + if d.MDNS.Interval == 0 { + d.MDNS.Interval = 5 + } + return discovery.NewMdnsService(h, time.Duration(d.MDNS.Interval)*time.Second) + } + } + return nil +} + func (n *IpfsNode) HandlePeerFound(p peer.PeerInfo) { log.Warning("trying peer info: ", p) ctx, _ := context.WithTimeout(n.Context(), time.Second*10) @@ -540,4 +555,6 @@ func constructDHTRouting(ctx context.Context, host p2phost.Host, dstore ds.Threa type RoutingOption func(context.Context, p2phost.Host, ds.ThreadSafeDatastore) (routing.IpfsRouting, error) +type DiscoveryOption func(p2phost.Host) (discovery.Service, error) + var DHTOption RoutingOption = constructDHTRouting diff --git a/p2p/discovery/mdns.go b/p2p/discovery/mdns.go index 5d57b21cd..234ef5f6b 100644 --- a/p2p/discovery/mdns.go +++ b/p2p/discovery/mdns.go @@ -1,13 +1,14 @@ package discovery import ( + "errors" "fmt" "io" "io/ioutil" golog "log" "net" - "strconv" - "strings" + //"strconv" + //"strings" "sync" "time" @@ -22,7 +23,6 @@ import ( var log = u.Logger("mdns") -const LookupFrequency = time.Second * 5 const ServiceTag = "discovery.ipfs.io" type Service interface { @@ -42,33 +42,45 @@ type mdnsService struct { lk sync.Mutex notifees []Notifee + interval time.Duration } -func NewMdnsService(peerhost host.Host) (Service, error) { +func getDialableListenAddr(ph host.Host) (*net.TCPAddr, error) { + for _, addr := range ph.Addrs() { + na, err := manet.ToNetAddr(addr) + if err != nil { + continue + } + tcp, ok := na.(*net.TCPAddr) + if ok { + return tcp, nil + } + } + return nil, errors.New("failed to find good external addr from peerhost") +} + +func NewMdnsService(peerhost host.Host, interval time.Duration) (Service, error) { // TODO: dont let mdns use logging... golog.SetOutput(ioutil.Discard) - // determine my local swarm port + var ipaddrs []net.IP port := 4001 - for _, addr := range peerhost.Addrs() { - parts := strings.Split(addr.String(), "/") - fmt.Println("parts len: ", len(parts)) - if len(parts) == 5 && parts[3] == "tcp" { - n, err := strconv.Atoi(parts[4]) - if err != nil { - return nil, err - } - port = n - break - } + + addr, err := getDialableListenAddr(peerhost) + if err != nil { + log.Warning(err) + } else { + ipaddrs = []net.IP{addr.IP} + port = addr.Port } + fmt.Println("using port: ", port) myid := peerhost.ID().Pretty() info := []string{myid} - service, err := mdns.NewMDNSService(myid, ServiceTag, "", "", port, nil, info) + service, err := mdns.NewMDNSService(myid, ServiceTag, "", "", port, ipaddrs, info) if err != nil { return nil, err } @@ -80,9 +92,10 @@ func NewMdnsService(peerhost host.Host) (Service, error) { } s := &mdnsService{ - server: server, - service: service, - host: peerhost, + server: server, + service: service, + host: peerhost, + interval: interval, } go s.pollForEntries() @@ -95,7 +108,7 @@ func (m *mdnsService) Close() error { } func (m *mdnsService) pollForEntries() { - ticker := time.NewTicker(LookupFrequency) + ticker := time.NewTicker(m.interval) for { select { case <-ticker.C: @@ -110,7 +123,7 @@ func (m *mdnsService) pollForEntries() { qp.Domain = "local" qp.Entries = entriesCh qp.Service = ServiceTag - qp.Timeout = time.Second * 3 + qp.Timeout = time.Second * 5 err := mdns.Query(&qp) if err != nil { @@ -122,6 +135,7 @@ func (m *mdnsService) pollForEntries() { } func (m *mdnsService) handleEntry(e *mdns.ServiceEntry) { + fmt.Println("handling entry!") mpeer, err := peer.IDB58Decode(e.Info) if err != nil { log.Warning("Error parsing peer ID from mdns entry: ", err) diff --git a/repo/config/config.go b/repo/config/config.go index 83cd2abb9..1d2fa87ad 100644 --- a/repo/config/config.go +++ b/repo/config/config.go @@ -21,6 +21,7 @@ type Config struct { Addresses Addresses // local node's addresses Mounts Mounts // local node's mount points Version Version // local node's version management + Discovery Discovery // local node's discovery mechanisms Bootstrap []string // local nodes's bootstrap peer addresses Tour Tour // local node's tour position Gateway Gateway // local node's gateway server options diff --git a/repo/config/discovery.go b/repo/config/discovery.go new file mode 100644 index 000000000..4fb8508f0 --- /dev/null +++ b/repo/config/discovery.go @@ -0,0 +1,12 @@ +package config + +type Discovery struct { + MDNS MDNS +} + +type MDNS struct { + Enabled bool + + // Time in seconds between discovery rounds + Interval int +} diff --git a/repo/config/init.go b/repo/config/init.go index 2b4bf2a08..76ee1fdc1 100644 --- a/repo/config/init.go +++ b/repo/config/init.go @@ -48,6 +48,10 @@ func Init(out io.Writer, nBitsForKeypair int) (*Config, error) { SupernodeRouting: *snr, Datastore: *ds, Identity: identity, + Discovery: Discovery{MDNS{ + Enabled: true, + Interval: 10, + }}, Log: Log{ MaxSizeMB: 250, MaxBackups: 1, -- GitLab