/
resolver.go
96 lines (80 loc) · 1.96 KB
/
resolver.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
package resolver
import (
"fmt"
"net"
"sync"
"google.golang.org/grpc/resolver"
"github.com/ngalayko/p2p/instance/peers"
)
// Builder returns a resolver for a client addrs.
type Builder struct {
secure bool
guard *sync.RWMutex
addrsStore map[string][]string
}
// New returns a new resolver for the peer.
func New(secure bool) *Builder {
return &Builder{
guard: &sync.RWMutex{},
addrsStore: map[string][]string{},
secure: secure,
}
}
// Add adds peer resolution rules.
func (b *Builder) Add(peer *peers.Peer) {
m := peer.Addrs.Map()
addrs := make([]string, 0, len(m))
for _, addr := range m {
if b.secure {
addrs = append(addrs, makeAddr(addr, peer.Port))
} else {
addrs = append(addrs, makeAddr(addr, peer.InsecurePort))
}
}
b.guard.Lock()
b.addrsStore[peer.ID] = addrs
b.guard.Unlock()
}
func makeAddr(ip net.IP, port int) string {
if ip.To4() == nil {
return fmt.Sprintf("[%s]:%d", ip.String(), port)
}
return fmt.Sprintf("%s:%d", ip.String(), port)
}
// Build implements grpc.Builder.
func (b *Builder) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOption) (resolver.Resolver, error) {
b.guard.RLock()
defer b.guard.RUnlock()
r := &Resolver{
target: target,
cc: cc,
addrsStore: b.addrsStore,
}
r.start()
return r, nil
}
// Scheme implements grpc.Builder.
func (b *Builder) Scheme() string {
if b.secure {
return "peer"
}
return "greet"
}
// Resolver implements grpc.Resolver.
type Resolver struct {
target resolver.Target
cc resolver.ClientConn
addrsStore map[string][]string
}
func (r *Resolver) start() {
addrStrs := r.addrsStore[r.target.Endpoint]
addrs := make([]resolver.Address, len(addrStrs))
for i, s := range addrStrs {
addrs[i] = resolver.Address{Addr: s}
}
r.cc.NewAddress(addrs)
}
// ResolveNow implements grpc.Resolver.
func (*Resolver) ResolveNow(o resolver.ResolveNowOption) {}
// Close implements grpc.Resolver.
func (*Resolver) Close() {}