Unverified Commit 37db5be5 authored by Steven Allen's avatar Steven Allen Committed by GitHub

Merge pull request #5535 from overbool/fix/support-for-dnsaddr

fix(swarm): add dnsaddr support in swarm connect
parents 221d1b13 5fc7b027
package commands
import (
"context"
"errors"
"fmt"
"io"
"path"
"sort"
"sync"
"time"
commands "github.com/ipfs/go-ipfs/commands"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
......@@ -21,9 +24,14 @@ import (
pstore "github.com/libp2p/go-libp2p-peerstore"
swarm "github.com/libp2p/go-libp2p-swarm"
ma "github.com/multiformats/go-multiaddr"
madns "github.com/multiformats/go-multiaddr-dns"
mafilter "github.com/whyrusleeping/multiaddr-filter"
)
const (
dnsResolveTimeout = 10 * time.Second
)
type stringList struct {
Strings []string
}
......@@ -362,7 +370,7 @@ ipfs swarm connect /ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3
addrs := req.Arguments
pis, err := peersWithAddresses(addrs)
pis, err := peersWithAddresses(req.Context, addrs)
if err != nil {
return err
}
......@@ -444,10 +452,29 @@ func parseAddresses(addrs []string) (iaddrs []iaddr.IPFSAddr, err error) {
return
}
// parseMultiaddrs is a function that takes in a slice of peer multiaddr
// and returns slices of multiaddrs and peerids
func parseMultiaddrs(maddrs []ma.Multiaddr) (iaddrs []iaddr.IPFSAddr, err error) {
iaddrs = make([]iaddr.IPFSAddr, len(maddrs))
for i, maddr := range maddrs {
iaddrs[i], err = iaddr.ParseMultiaddr(maddr)
if err != nil {
return nil, cmds.ClientError("invalid peer address: " + err.Error())
}
}
return
}
// peersWithAddresses is a function that takes in a slice of string peer addresses
// (multiaddr + peerid) and returns a slice of properly constructed peers
func peersWithAddresses(addrs []string) ([]pstore.PeerInfo, error) {
iaddrs, err := parseAddresses(addrs)
func peersWithAddresses(ctx context.Context, addrs []string) ([]pstore.PeerInfo, error) {
// resolve addresses
maddrs, err := resolveAddresses(ctx, addrs)
if err != nil {
return nil, err
}
iaddrs, err := parseMultiaddrs(maddrs)
if err != nil {
return nil, err
}
......@@ -472,6 +499,67 @@ func peersWithAddresses(addrs []string) ([]pstore.PeerInfo, error) {
return pis, nil
}
// resolveAddresses resolves addresses parallelly
func resolveAddresses(ctx context.Context, addrs []string) ([]ma.Multiaddr, error) {
ctx, cancel := context.WithTimeout(ctx, dnsResolveTimeout)
defer cancel()
var maddrs []ma.Multiaddr
var wg sync.WaitGroup
resolveErrC := make(chan error, len(addrs))
maddrC := make(chan ma.Multiaddr)
for _, addr := range addrs {
maddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, err
}
// check whether address ends in `ipfs/Qm...`
if _, last := ma.SplitLast(maddr); last.Protocol().Code == ma.P_IPFS {
maddrs = append(maddrs, maddr)
continue
}
wg.Add(1)
go func(maddr ma.Multiaddr) {
defer wg.Done()
raddrs, err := madns.Resolve(ctx, maddr)
if err != nil {
resolveErrC <- err
return
}
// filter out addresses that still doesn't end in `ipfs/Qm...`
found := 0
for _, raddr := range raddrs {
if _, last := ma.SplitLast(raddr); last.Protocol().Code == ma.P_IPFS {
maddrC <- raddr
found++
}
}
if found == 0 {
resolveErrC <- fmt.Errorf("found no ipfs peers at %s", maddr)
}
}(maddr)
}
go func() {
wg.Wait()
close(maddrC)
}()
for maddr := range maddrC {
maddrs = append(maddrs, maddr)
}
select {
case err := <-resolveErrC:
return nil, err
default:
}
return maddrs, nil
}
var swarmFiltersCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Manipulate address filters.",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment