github.com/ethersphere/bee/v2@v2.2.0/pkg/p2p/discover.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package p2p 6 7 import ( 8 "context" 9 "errors" 10 "fmt" 11 "math/rand" 12 13 ma "github.com/multiformats/go-multiaddr" 14 madns "github.com/multiformats/go-multiaddr-dns" 15 ) 16 17 func isDNSProtocol(protoCode int) bool { 18 if protoCode == ma.P_DNS || protoCode == ma.P_DNS4 || protoCode == ma.P_DNS6 || protoCode == ma.P_DNSADDR { 19 return true 20 } 21 return false 22 } 23 24 func Discover(ctx context.Context, addr ma.Multiaddr, f func(ma.Multiaddr) (bool, error)) (bool, error) { 25 if comp, _ := ma.SplitFirst(addr); !isDNSProtocol(comp.Protocol().Code) { 26 return f(addr) 27 } 28 29 dnsResolver := madns.DefaultResolver 30 addrs, err := dnsResolver.Resolve(ctx, addr) 31 if err != nil { 32 return false, fmt.Errorf("dns resolve address %s: %w", addr, err) 33 } 34 if len(addrs) == 0 { 35 return false, errors.New("non-resolvable API endpoint") 36 } 37 38 rand.Shuffle(len(addrs), func(i, j int) { 39 addrs[i], addrs[j] = addrs[j], addrs[i] 40 }) 41 for _, addr := range addrs { 42 stopped, err := Discover(ctx, addr, f) 43 if err != nil { 44 return false, fmt.Errorf("discover %s: %w", addr, err) 45 } 46 47 if stopped { 48 return true, nil 49 } 50 } 51 52 return false, nil 53 }