Skip to content

Commit

Permalink
fix(swarm): add dnsaddr support in swarm connect
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Overbool <overbool.xu@gmail.com>
  • Loading branch information
overbool committed Oct 25, 2018
1 parent 7ecd675 commit 8c0fe02
Showing 1 changed file with 82 additions and 6 deletions.
88 changes: 82 additions & 6 deletions core/commands/swarm.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
package commands

import (
"context"
"errors"
"fmt"
"io"
"path"
"sort"
"strings"
"sync"
"time"

"github.com/ipfs/go-ipfs/commands"
"github.com/ipfs/go-ipfs/core/commands/cmdenv"
"github.com/ipfs/go-ipfs/core/commands/e"
"github.com/ipfs/go-ipfs/repo"
"github.com/ipfs/go-ipfs/repo/fsrepo"
commands "github.com/ipfs/go-ipfs/commands"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
e "github.com/ipfs/go-ipfs/core/commands/e"
repo "github.com/ipfs/go-ipfs/repo"
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"

"gx/ipfs/QmNUhkTWN7iynJZTj1RcTsQDSRGGkh87zMo9ELypxhY8Y6/go-ipfs-config"
"gx/ipfs/QmRRovo1DE6i5cMjCbf19mQCSuszF6SKwdZNUMS7MtBnH1/go-ipfs-cmds"
Expand All @@ -26,6 +29,10 @@ import (
"gx/ipfs/Qmde5VP1qUkyQXKCfmEUA7bP64V2HAptbJ7phuPp7jXWwg/go-ipfs-cmdkit"
)

const (
dnsResolveTimeout = 10 * time.Second
)

type stringList struct {
Strings []string
}
Expand Down Expand Up @@ -460,10 +467,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)
// resolve addresses
maddrs, err := resolveAddresses(addrs)
if err != nil {
return nil, err
}

iaddrs, err := parseMultiaddrs(maddrs)
if err != nil {
return nil, err
}
Expand All @@ -488,6 +514,56 @@ func peersWithAddresses(addrs []string) ([]pstore.PeerInfo, error) {
return pis, nil
}

// resolveAddresses resolves addresses parallelly
func resolveAddresses(addrs []string) ([]ma.Multiaddr, error) {
var maddrs []ma.Multiaddr
var wg sync.WaitGroup
resolveErrC := make(chan error, len(addrs))

for _, addr := range addrs {
maddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, err
}
// check whether address ends in `ipfs/Qm...`
if _, err := maddr.ValueForProtocol(ma.P_IPFS); err != ma.ErrProtocolNotFound {
maddrs = append(maddrs, maddr)
continue
}
wg.Add(1)
go func(maddr ma.Multiaddr) {
defer wg.Done()
ctx, cancel := context.WithTimeout(context.Background(), dnsResolveTimeout)
raddrs, err := madns.Resolve(ctx, maddr)
cancel()
if err != nil {
resolveErrC <- err
return
}
if len(raddrs) == 0 {
resolveErrC <- fmt.Errorf("non-resolvable multiaddr about %v", maddr)
return
}
// filter out addresses that still doesn't end in `ipfs/Qm...`
for _, raddr := range raddrs {
if _, err := raddr.ValueForProtocol(ma.P_IPFS); err != ma.ErrProtocolNotFound {
maddrs = append(maddrs, raddr)
}
}
}(maddr)
}
// wait for address resolving
wg.Wait()

select {
case err := <-resolveErrC:
return nil, err
default:
}

return maddrs, nil
}

var swarmFiltersCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Manipulate address filters.",
Expand Down

0 comments on commit 8c0fe02

Please sign in to comment.