Skip to content

Commit

Permalink
run both mDNS services in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
marten-seemann committed Jul 6, 2021
1 parent bdd42c9 commit 623bfd9
Show file tree
Hide file tree
Showing 10 changed files with 394 additions and 20 deletions.
3 changes: 3 additions & 0 deletions examples/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
Expand Down Expand Up @@ -199,6 +200,8 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866 h1:Zhb043u1Nzw/ftKuExAZl3L+O2lc5YkPcQvqM8NknYc=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866/go.mod h1:I6CSXU4zCGL08JOk9NbcT0ofAgnIkS/fVXbYzfSoDic=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
Expand Down
3 changes: 3 additions & 0 deletions examples/ipfs-camp-2019/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
Expand Down Expand Up @@ -199,6 +200,8 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866 h1:Zhb043u1Nzw/ftKuExAZl3L+O2lc5YkPcQvqM8NknYc=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866/go.mod h1:I6CSXU4zCGL08JOk9NbcT0ofAgnIkS/fVXbYzfSoDic=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
Expand Down
3 changes: 3 additions & 0 deletions examples/pubsub/chat/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
Expand Down Expand Up @@ -200,6 +201,8 @@ github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866 h1:Zhb043u1Nzw/ftKuExAZl3L+O2lc5YkPcQvqM8NknYc=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866/go.mod h1:I6CSXU4zCGL08JOk9NbcT0ofAgnIkS/fVXbYzfSoDic=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/btcsuite/btcd v0.21.0-beta // indirect
github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect
github.com/gogo/protobuf v1.3.2
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866
github.com/ipfs/go-cid v0.0.7
github.com/ipfs/go-datastore v0.4.5
github.com/ipfs/go-detect-race v0.0.1
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
Expand Down Expand Up @@ -202,6 +203,8 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866 h1:Zhb043u1Nzw/ftKuExAZl3L+O2lc5YkPcQvqM8NknYc=
github.com/grandcat/zeroconf v1.0.1-0.20210705173249-1df3d2672866/go.mod h1:I6CSXU4zCGL08JOk9NbcT0ofAgnIkS/fVXbYzfSoDic=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
Expand Down
196 changes: 196 additions & 0 deletions p2p/discovery/mdns.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package discovery

import (
"context"
"errors"
"net"
"strings"
"sync"

"github.com/libp2p/go-libp2p-core/host"
"github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"

"github.com/grandcat/zeroconf"
)

const (
mdnsServiceName = "_p2p._udp"
mdnsDomain = "local"
dnsaddrPrefix = "dnsaddr="
)

type mdnsService struct {
host host.Host

// This ctx is passed to the resolver.
// It is closed when Close() is called.
ctx context.Context
ctxCancel context.CancelFunc

server *zeroconf.Server

mutex sync.Mutex
notifees []Notifee
}

func NewMdnsServiceNew(host host.Host) *mdnsService {
ctx, cancel := context.WithCancel(context.Background())
s := &mdnsService{
ctx: ctx,
ctxCancel: cancel,
host: host,
}
s.startServer()
s.startResolver()
return s
}

func (s *mdnsService) Close() error {
s.ctxCancel()
if s.server != nil {
s.server.Shutdown()
}
return nil
}

// We don't really care about the IP addresses, but the spec (and various routers / firewalls) require us
// to send A and AAAA records.
func (s *mdnsService) getIPs(addrs []ma.Multiaddr) ([]string, error) {
var ip4, ip6 string
for _, addr := range addrs {
network, hostport, err := manet.DialArgs(addr)
if err != nil {
continue
}
host, _, err := net.SplitHostPort(hostport)
if err != nil {
continue
}
if ip4 == "" && (network == "udp4" || network == "tcp4") {
ip4 = host
} else if ip6 == "" && (network == "udp6" || network == "tcp6") {
ip6 = host
}
}
ips := make([]string, 0, 2)
if ip4 != "" {
ips = append(ips, ip4)
}
if ip6 != "" {
ips = append(ips, ip6)
}
if len(ips) == 0 {
return nil, errors.New("didn't find any IP addresses")
}
return ips, nil
}

func (s *mdnsService) mdnsInstance() string {
return string(s.host.ID())
}

func (s *mdnsService) startServer() error {
interfaceAddrs, err := s.host.Network().InterfaceListenAddresses()
if err != nil {
return err
}
addrs, err := peer.AddrInfoToP2pAddrs(&peer.AddrInfo{
ID: s.host.ID(),
Addrs: interfaceAddrs,
})
if err != nil {
return err
}
var txts []string
for _, addr := range addrs {
if manet.IsThinWaist(addr) { // don't announce circuit addresses
txts = append(txts, dnsaddrPrefix+addr.String())
}
}

ips, err := s.getIPs(addrs)
if err != nil {
return err
}

server, err := zeroconf.RegisterProxy(
s.mdnsInstance(),
mdnsServiceName,
mdnsDomain,
4001,
s.host.ID().Pretty(), // TODO: deals with peer IDs longer than 63 characters
ips,
txts,
nil,
)
if err != nil {
return err
}
s.server = server
return nil
}

func (s *mdnsService) startResolver() error {
resolver, err := zeroconf.NewResolver()
if err != nil {
return err
}

entryChan := make(chan *zeroconf.ServiceEntry, 1000)
go func() {
for entry := range entryChan {
// We only care about the TXT records.
// Ignore A, AAAA and PTR.
addrs := make([]ma.Multiaddr, 0, len(entry.Text)) // assume that all TXT records are dnsaddrs
for _, s := range entry.Text {
if !strings.HasPrefix(s, dnsaddrPrefix) {
log.Debug("missing dnsaddr prefix")
continue
}
addr, err := ma.NewMultiaddr(s[len(dnsaddrPrefix):])
if err != nil {
log.Debugf("failed to parse multiaddr: %s", err)
continue
}
addrs = append(addrs, addr)
}
infos, err := peer.AddrInfosFromP2pAddrs(addrs...)
if err != nil {
log.Debugf("failed to get peer info: %s", err)
continue
}
s.mutex.Lock()
for _, info := range infos {
for _, notif := range s.notifees {
go notif.HandlePeerFound(info)
}
}
s.mutex.Unlock()
}
}()
return resolver.Browse(s.ctx, mdnsServiceName, mdnsDomain, entryChan)
}

func (s *mdnsService) RegisterNotifee(n Notifee) {
s.mutex.Lock()
s.notifees = append(s.notifees, n)
s.mutex.Unlock()
}

func (s *mdnsService) UnregisterNotifee(n Notifee) {
s.mutex.Lock()
defer s.mutex.Unlock()

found := -1
for i, notif := range s.notifees {
if notif == n {
found = i
break
}
}
if found != -1 {
s.notifees = append(s.notifees[:found], s.notifees[found+1:]...)
}
}
23 changes: 5 additions & 18 deletions p2p/discovery/mdns_legacy.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package discovery
import (
"context"
"errors"
"io"
"net"
"sync"
"time"
Expand All @@ -26,16 +25,6 @@ var log = logging.Logger("mdns")

const ServiceTag = "_ipfs-discovery._udp"

type Service interface {
io.Closer
RegisterNotifee(Notifee)
UnregisterNotifee(Notifee)
}

type Notifee interface {
HandlePeerFound(peer.AddrInfo)
}

type mdnsServiceLegacy struct {
server *mdns.Server
service *mdns.MDNSService
Expand All @@ -47,6 +36,8 @@ type mdnsServiceLegacy struct {
interval time.Duration
}

var _ Service = &mdnsServiceLegacy{}

func getDialableListenAddrs(ph host.Host) ([]*net.TCPAddr, error) {
var out []*net.TCPAddr
addrs, err := ph.Network().InterfaceListenAddresses()
Expand All @@ -69,8 +60,7 @@ func getDialableListenAddrs(ph host.Host) ([]*net.TCPAddr, error) {
return out, nil
}

func NewMdnsService(ctx context.Context, peerhost host.Host, interval time.Duration, serviceTag string) (Service, error) {

func NewMdnsServiceLegacy(ctx context.Context, peerhost host.Host, interval time.Duration) (Service, error) {
var ipaddrs []net.IP
port := 4001

Expand All @@ -87,10 +77,7 @@ func NewMdnsService(ctx context.Context, peerhost host.Host, interval time.Durat
myid := peerhost.ID().Pretty()

info := []string{myid}
if serviceTag == "" {
serviceTag = ServiceTag
}
service, err := mdns.NewMDNSService(myid, serviceTag, "", "", port, ipaddrs, info)
service, err := mdns.NewMDNSService(myid, ServiceTag, "", "", port, ipaddrs, info)
if err != nil {
return nil, err
}
Expand All @@ -106,7 +93,7 @@ func NewMdnsService(ctx context.Context, peerhost host.Host, interval time.Durat
service: service,
host: peerhost,
interval: interval,
tag: serviceTag,
tag: ServiceTag,
}

go s.pollForEntries(ctx)
Expand Down
4 changes: 2 additions & 2 deletions p2p/discovery/mdns_legacy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ func TestMdnsDiscovery(t *testing.T) {
a := bhost.New(swarmt.GenSwarm(t, ctx))
b := bhost.New(swarmt.GenSwarm(t, ctx))

sa, err := NewMdnsService(ctx, a, time.Second, "someTag")
sa, err := NewMdnsService(ctx, a, time.Second)
if err != nil {
t.Fatal(err)
}

sb, err := NewMdnsService(ctx, b, time.Second, "someTag")
sb, err := NewMdnsService(ctx, b, time.Second)
if err != nil {
t.Fatal(err)
}
Expand Down
Loading

0 comments on commit 623bfd9

Please sign in to comment.