@cryptotaxi247 / kubo / commits / 309cf7057

fix(swarm): add dnsaddr support in swarm connect

License: MIT Signed-off-by: Overbool <overbool.xu@gmail.com>

Overbool committed Oct 5, 2018 at 13:12 UTC 309cf70570bd5b7b614e9718c4f0c38c3595f050
1 file changed +78 -1
core/commands/swarm.go
+78 -1
@@ -1,11 +1,15 @@
1 package commands
2
3 import (
4 + "context"
5 "errors"
6 "fmt"
7 "io"
8 "path"
9 "sort"
10 + "strings"
11 + "sync"
12 + "time"
13
14 commands "github.com/ipfs/go-ipfs/commands"
15 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
@@ -24,6 +28,10 @@ import (
28 mafilter "github.com/whyrusleeping/multiaddr-filter"
29 )
30
31 +const (
32 + dnsResolveTimeout = 10 * time.Second
33 +)
34 +
35 type stringList struct {
36 Strings []string
37 }
@@ -444,10 +452,29 @@ func parseAddresses(addrs []string) (iaddrs []iaddr.IPFSAddr, err error) {
452 return
453 }
454
455 +// parseMultiaddrs is a function that takes in a slice of peer multiaddr
456 +// and returns slices of multiaddrs and peerids
457 +func parseMultiaddrs(maddrs []ma.Multiaddr) (iaddrs []iaddr.IPFSAddr, err error) {
458 + iaddrs = make([]iaddr.IPFSAddr, len(maddrs))
459 + for i, maddr := range maddrs {
460 + iaddrs[i], err = iaddr.ParseMultiaddr(maddr)
461 + if err != nil {
462 + return nil, cmds.ClientError("invalid peer address: " + err.Error())
463 + }
464 + }
465 + return
466 +}
467 +
468 // peersWithAddresses is a function that takes in a slice of string peer addresses
469 // (multiaddr + peerid) and returns a slice of properly constructed peers
470 func peersWithAddresses(addrs []string) ([]pstore.PeerInfo, error) {
450 - iaddrs, err := parseAddresses(addrs)
471 + // resolve addresses
472 + maddrs, err := resolveAddresses(addrs)
473 + if err != nil {
474 + return nil, err
475 + }
476 +
477 + iaddrs, err := parseMultiaddrs(maddrs)
478 if err != nil {
479 return nil, err
480 }
@@ -472,6 +499,56 @@ func peersWithAddresses(addrs []string) ([]pstore.PeerInfo, error) {
499 return pis, nil
500 }
501
502 +// resolveAddresses resolves addresses parallelly
503 +func resolveAddresses(addrs []string) ([]ma.Multiaddr, error) {
504 + var maddrs []ma.Multiaddr
505 + var wg sync.WaitGroup
506 + resolveErrC := make(chan error, len(addrs))
507 +
508 + for _, addr := range addrs {
509 + maddr, err := ma.NewMultiaddr(addr)
510 + if err != nil {
511 + return nil, err
512 + }
513 + // check whether address ends in `ipfs/Qm...`
514 + if _, err := maddr.ValueForProtocol(ma.P_IPFS); err != ma.ErrProtocolNotFound {
515 + maddrs = append(maddrs, maddr)
516 + continue
517 + }
518 + wg.Add(1)
519 + go func(maddr ma.Multiaddr) {
520 + defer wg.Done()
521 + ctx, cancel := context.WithTimeout(context.Background(), dnsResolveTimeout)
522 + raddrs, err := madns.Resolve(ctx, maddr)
523 + cancel()
524 + if err != nil {
525 + resolveErrC <- err
526 + return
527 + }
528 + if len(raddrs) == 0 {
529 + resolveErrC <- fmt.Errorf("non-resolvable multiaddr about %v", maddr)
530 + return
531 + }
532 + // filter out addresses that still doesn't end in `ipfs/Qm...`
533 + for _, raddr := range raddrs {
534 + if _, err := raddr.ValueForProtocol(ma.P_IPFS); err != ma.ErrProtocolNotFound {
535 + maddrs = append(maddrs, raddr)
536 + }
537 + }
538 + }(maddr)
539 + }
540 + // wait for address resolving
541 + wg.Wait()
542 +
543 + select {
544 + case err := <-resolveErrC:
545 + return nil, err
546 + default:
547 + }
548 +
549 + return maddrs, nil
550 +}
551 +
552 var swarmFiltersCmd = &cmds.Command{
553 Helptext: cmdkit.HelpText{
554 Tagline: "Manipulate address filters.",