forked from libp2p/go-libp2p-kad-dht
-
Notifications
You must be signed in to change notification settings - Fork 1
/
message.go
171 lines (150 loc) · 4.56 KB
/
message.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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package dht_pb
import (
"github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-core/peer"
logging "github.com/ipfs/go-log"
ma "github.com/multiformats/go-multiaddr"
)
var log = logging.Logger("dht.pb")
type PeerRoutingInfo struct {
peer.AddrInfo
network.Connectedness
}
// NewMessage constructs a new dht message with given type, key, and level
func NewMessage(typ Message_MessageType, key []byte, level int) *Message {
m := &Message{
Type: typ,
Key: key,
}
m.SetClusterLevel(level)
return m
}
func peerRoutingInfoToPBPeer(p PeerRoutingInfo) Message_Peer {
var pbp Message_Peer
pbp.Addrs = make([][]byte, len(p.Addrs))
for i, maddr := range p.Addrs {
pbp.Addrs[i] = maddr.Bytes() // Bytes, not String. Compressed.
}
pbp.Id = byteString(p.ID)
pbp.Connection = ConnectionType(p.Connectedness)
return pbp
}
func peerInfoToPBPeer(p peer.AddrInfo) Message_Peer {
var pbp Message_Peer
pbp.Addrs = make([][]byte, len(p.Addrs))
for i, maddr := range p.Addrs {
pbp.Addrs[i] = maddr.Bytes() // Bytes, not String. Compressed.
}
pbp.Id = byteString(p.ID)
return pbp
}
// PBPeerToPeer turns a *Message_Peer into its peer.AddrInfo counterpart
func PBPeerToPeerInfo(pbp Message_Peer) peer.AddrInfo {
return peer.AddrInfo{
ID: peer.ID(pbp.Id),
Addrs: pbp.Addresses(),
}
}
// RawPeerInfosToPBPeers converts a slice of Peers into a slice of *Message_Peers,
// ready to go out on the wire.
func RawPeerInfosToPBPeers(peers []peer.AddrInfo) []Message_Peer {
pbpeers := make([]Message_Peer, len(peers))
for i, p := range peers {
pbpeers[i] = peerInfoToPBPeer(p)
}
return pbpeers
}
// PeersToPBPeers converts given []peer.Peer into a set of []*Message_Peer,
// which can be written to a message and sent out. the key thing this function
// does (in addition to PeersToPBPeers) is set the ConnectionType with
// information from the given network.Network.
func PeerInfosToPBPeers(n network.Network, peers []peer.AddrInfo) []Message_Peer {
pbps := RawPeerInfosToPBPeers(peers)
for i, pbp := range pbps {
c := ConnectionType(n.Connectedness(peers[i].ID))
pbp.Connection = c
}
return pbps
}
func PeerRoutingInfosToPBPeers(peers []PeerRoutingInfo) []Message_Peer {
pbpeers := make([]Message_Peer, len(peers))
for i, p := range peers {
pbpeers[i] = peerRoutingInfoToPBPeer(p)
}
return pbpeers
}
// PBPeersToPeerInfos converts given []*Message_Peer into []peer.AddrInfo
// Invalid addresses will be silently omitted.
func PBPeersToPeerInfos(pbps []Message_Peer) []*peer.AddrInfo {
peers := make([]*peer.AddrInfo, 0, len(pbps))
for _, pbp := range pbps {
ai := PBPeerToPeerInfo(pbp)
peers = append(peers, &ai)
}
return peers
}
// Addresses returns a multiaddr associated with the Message_Peer entry
func (m *Message_Peer) Addresses() []ma.Multiaddr {
if m == nil {
return nil
}
maddrs := make([]ma.Multiaddr, 0, len(m.Addrs))
for _, addr := range m.Addrs {
maddr, err := ma.NewMultiaddrBytes(addr)
if err != nil {
log.Debugw("error decoding multiaddr for peer", "peer", peer.ID(m.Id), "error", err)
continue
}
maddrs = append(maddrs, maddr)
}
return maddrs
}
// GetClusterLevel gets and adjusts the cluster level on the message.
// a +/- 1 adjustment is needed to distinguish a valid first level (1) and
// default "no value" protobuf behavior (0)
func (m *Message) GetClusterLevel() int {
level := m.GetClusterLevelRaw() - 1
if level < 0 {
return 0
}
return int(level)
}
// SetClusterLevel adjusts and sets the cluster level on the message.
// a +/- 1 adjustment is needed to distinguish a valid first level (1) and
// default "no value" protobuf behavior (0)
func (m *Message) SetClusterLevel(level int) {
lvl := int32(level)
m.ClusterLevelRaw = lvl + 1
}
// ConnectionType returns a Message_ConnectionType associated with the
// network.Connectedness.
func ConnectionType(c network.Connectedness) Message_ConnectionType {
switch c {
default:
return Message_NOT_CONNECTED
case network.NotConnected:
return Message_NOT_CONNECTED
case network.Connected:
return Message_CONNECTED
case network.CanConnect:
return Message_CAN_CONNECT
case network.CannotConnect:
return Message_CANNOT_CONNECT
}
}
// Connectedness returns an network.Connectedness associated with the
// Message_ConnectionType.
func Connectedness(c Message_ConnectionType) network.Connectedness {
switch c {
default:
return network.NotConnected
case Message_NOT_CONNECTED:
return network.NotConnected
case Message_CONNECTED:
return network.Connected
case Message_CAN_CONNECT:
return network.CanConnect
case Message_CANNOT_CONNECT:
return network.CannotConnect
}
}