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  }