-
Notifications
You must be signed in to change notification settings - Fork 376
/
helper.go
107 lines (96 loc) · 2.31 KB
/
helper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package ipfsutil
import (
"context"
"errors"
"fmt"
"sync"
peer "github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
madns "github.com/multiformats/go-multiaddr-dns"
"go.uber.org/multierr"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)
func ParseAndResolveIpfsAddr(ctx context.Context, addr string) (*peer.AddrInfo, error) {
maddr, err := ma.NewMultiaddr(addr)
if err != nil {
return nil, err
}
if !madns.Matches(maddr) {
return peer.AddrInfoFromP2pAddr(maddr)
}
addrs, err := madns.Resolve(ctx, maddr)
if err != nil {
return nil, err
}
if len(addrs) == 0 {
return nil, errors.New("fail to resolve the multiaddr:" + maddr.String())
}
var info peer.AddrInfo
for _, addr := range addrs {
taddr, id := peer.SplitAddr(addr)
if id == "" {
// not an ipfs addr, skipping.
continue
}
switch info.ID {
case "":
info.ID = id
case id:
default:
return nil, fmt.Errorf(
"ambiguous maddr %s could refer to %s or %s",
maddr,
info.ID,
id,
)
}
info.Addrs = append(info.Addrs, taddr)
}
return &info, nil
}
func ParseAndResolveRdvpMaddrs(ctx context.Context, log *zap.Logger, addrs []string) ([]*peer.AddrInfo, error) {
// Resolve all addresses
outPeersUnmatched := make([]*peer.AddrInfo, len(addrs))
var errs error
var outLock sync.Mutex
var wg sync.WaitGroup
wg.Add(len(addrs))
for i, v := range addrs {
go func(j int, addr string) {
defer wg.Done()
rdvpeer, err := ParseAndResolveIpfsAddr(ctx, addr)
if err != nil {
outLock.Lock()
defer outLock.Unlock()
errs = multierr.Append(errs, err)
return
}
fds := make([]zapcore.Field, len(rdvpeer.Addrs))
for i, maddr := range rdvpeer.Addrs {
key := fmt.Sprintf("#%d", i)
fds[i] = zap.String(key, maddr.String())
}
log.Debug("rdvp peer resolved addrs", fds...)
outPeersUnmatched[j] = rdvpeer
}(i, v)
}
wg.Wait()
if errs != nil {
return nil, errs
}
// Match peers by ID
outPeersMatched := make(map[peer.ID][]ma.Multiaddr)
for _, v := range outPeersUnmatched {
outPeersMatched[v.ID] = append(outPeersMatched[v.ID], v.Addrs...)
}
// Create the ultimate *peer.AddrInfo
var outPeers []*peer.AddrInfo
for id, maddrs := range outPeersMatched {
outPeers = append(outPeers, &peer.AddrInfo{
ID: id,
Addrs: maddrs,
})
}
return outPeers, nil
}