Skip to content

Commit 4bf338f

Browse files
committed
peer/wire: Relay TORv3 addresses.
This commit relays TORv3 addresses across the peer to peer network and bumps the wire protocol version to 11.
1 parent 227a68f commit 4bf338f

File tree

6 files changed

+93
-21
lines changed

6 files changed

+93
-21
lines changed

peer/peer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727

2828
const (
2929
// MaxProtocolVersion is the max protocol version the peer supports.
30-
MaxProtocolVersion = wire.AddrV2Version
30+
MaxProtocolVersion = wire.RelayTORv3Version
3131

3232
// outputBufferSize is the number of elements the output channels use.
3333
outputBufferSize = 5000

server.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const (
7474
connectionRetryInterval = time.Second * 5
7575

7676
// maxProtocolVersion is the max protocol version the server supports.
77-
maxProtocolVersion = wire.AddrV2Version
77+
maxProtocolVersion = wire.RelayTORv3Version
7878

7979
// These fields are used to track known addresses on a per-peer basis.
8080
//
@@ -785,6 +785,7 @@ func isSupportedNetAddressTypeV2(netAddressType addrmgr.NetAddressType) bool {
785785
case addrmgr.IPv4Address:
786786
case addrmgr.IPv6Address:
787787
case addrmgr.TORv2Address:
788+
case addrmgr.TORv3Address:
788789
return true
789790
}
790791
return false
@@ -794,7 +795,7 @@ func isSupportedNetAddressTypeV2(netAddressType addrmgr.NetAddressType) bool {
794795
// specific address manager network address type is supported by the
795796
// provided protocol version.
796797
func getNetAddressTypeFilter(protocolVersion uint32) addrmgr.NetAddressTypeFilter {
797-
if protocolVersion < wire.AddrV2Version {
798+
if protocolVersion < wire.RelayTORv3Version {
798799
return isSupportedNetAddressTypeV1
799800
} else {
800801
return isSupportedNetAddressTypeV2

wire/msgaddrv2.go

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,38 @@ func readNetAddressV2(op string, r io.Reader, pver uint32) (*NetAddressV2, error
9090

9191
// Read the ip bytes with a length varying by the network id type.
9292
var ipBytes []byte
93-
switch na.Type {
94-
case IPv4Address:
93+
switch {
94+
case na.Type == IPv4Address:
9595
var ip [4]byte
9696
err := readElement(r, &ip)
9797
if err != nil {
9898
return nil, err
9999
}
100100
ipBytes = ip[:]
101-
case TORv2Address:
101+
case na.Type == TORv2Address:
102102
var ip [10]byte
103103
err := readElement(r, &ip)
104104
if err != nil {
105105
return nil, err
106106
}
107107
ipBytes = ip[:]
108-
case IPv6Address:
108+
case na.Type == IPv6Address:
109109
var ip [16]byte
110110
err := readElement(r, &ip)
111111
if err != nil {
112112
return nil, err
113113
}
114114
ipBytes = ip[:]
115+
case na.Type == TORv3Address && pver >= RelayTORv3Version:
116+
var ip [32]byte
117+
err := readElement(r, &ip)
118+
if err != nil {
119+
return nil, err
120+
}
121+
ipBytes = ip[:]
115122
default:
116-
msg := fmt.Sprintf("unsupported network address type %v", na.Type)
123+
msg := fmt.Sprintf("unsupported network address type %v for "+
124+
"protocol version %d", na.Type, pver)
117125
return nil, messageError(op, ErrInvalidMsg, msg)
118126
}
119127

@@ -140,8 +148,8 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
140148
}
141149

142150
netAddrIP := na.IP
143-
switch na.Type {
144-
case IPv4Address:
151+
switch {
152+
case na.Type == IPv4Address:
145153
var ip [4]byte
146154
if netAddrIP != nil {
147155
copy(ip[:], netAddrIP)
@@ -150,7 +158,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
150158
if err != nil {
151159
return err
152160
}
153-
case TORv2Address:
161+
case na.Type == TORv2Address:
154162
var ip [10]byte
155163
if netAddrIP != nil {
156164
pubkey := netAddrIP[6:]
@@ -160,7 +168,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
160168
if err != nil {
161169
return err
162170
}
163-
case IPv6Address:
171+
case na.Type == IPv6Address:
164172
var ip [16]byte
165173
if netAddrIP != nil {
166174
copy(ip[:], net.IP(netAddrIP).To16())
@@ -169,8 +177,18 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
169177
if err != nil {
170178
return err
171179
}
180+
case na.Type == TORv3Address && pver >= RelayTORv3Version:
181+
var ip [32]byte
182+
if len(na.IP) == 32 {
183+
copy(ip[:], net.IP(na.IP))
184+
}
185+
err = writeElement(w, ip)
186+
if err != nil {
187+
return err
188+
}
172189
default:
173-
msg := fmt.Sprintf("unrecognized network address type %v", na.Type)
190+
msg := fmt.Sprintf("unsupported network address type %v for "+
191+
"protocol version %d", na.Type, pver)
174192
return messageError(op, ErrInvalidMsg, msg)
175193
}
176194

@@ -180,11 +198,25 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
180198
// maxNetAddressPayloadV2 returns the max payload size for an address manager
181199
// network address based on the protocol version.
182200
func maxNetAddressPayloadV2(pver uint32) uint32 {
183-
const timestampSize = 8
184-
const servicesSize = 8
185-
const addressTypeSize = 1
186-
const maxAddressSize = 16
187-
const portSize = 2
201+
if pver < RelayTORv3Version {
202+
const (
203+
timestampSize = 8
204+
servicesSize = 8
205+
addressTypeSize = 1
206+
maxAddressSize = 16
207+
portSize = 2
208+
)
209+
return timestampSize + servicesSize + addressTypeSize + maxAddressSize +
210+
portSize
211+
}
212+
213+
const (
214+
timestampSize = 8
215+
servicesSize = 8
216+
addressTypeSize = 1
217+
maxAddressSize = 32
218+
portSize = 2
219+
)
188220
return timestampSize + servicesSize + addressTypeSize + maxAddressSize +
189221
portSize
190222
}

wire/msgaddrv2_test.go

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ var (
3636
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3737
}
3838

39+
torV3IpBytes = []byte{
40+
0xb8, 0x39, 0x1d, 0x20, 0x03, 0xbb, 0x3b, 0xd2,
41+
0x85, 0xb0, 0x35, 0xac, 0x8e, 0xb3, 0x0c, 0x80,
42+
0xc4, 0xe2, 0xa2, 0x9b, 0xb7, 0xa2, 0xf0, 0xce,
43+
0x0d, 0xf8, 0x74, 0x3c, 0x37, 0xec, 0x35, 0x93,
44+
}
45+
3946
serializedIPv4NetAddressBytes = []byte{
4047
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
4148
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Services
@@ -60,12 +67,24 @@ var (
6067
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6168
0x8f, 0x20,
6269
}
70+
71+
serializedTORv3NetAddressBytes = []byte{
72+
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00,
73+
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74+
0x04,
75+
0xb8, 0x39, 0x1d, 0x20, 0x03, 0xbb, 0x3b, 0xd2,
76+
0x85, 0xb0, 0x35, 0xac, 0x8e, 0xb3, 0x0c, 0x80,
77+
0xc4, 0xe2, 0xa2, 0x9b, 0xb7, 0xa2, 0xf0, 0xce,
78+
0x0d, 0xf8, 0x74, 0x3c, 0x37, 0xec, 0x35, 0x93,
79+
0x90, 0x20,
80+
}
6381
)
6482

6583
var (
6684
ipv4Address = newNetAddressV2(IPv4Address, ipv4IpBytes, 8333)
6785
ipv6Address = newNetAddressV2(IPv6Address, ipv6IpBytes, 8334)
6886
torv2Address = newNetAddressV2(TORv2Address, torV2IpBytes, 8335)
87+
torv3Address = newNetAddressV2(TORv3Address, torV3IpBytes, 8336)
6988
)
7089

7190
// TestMaxPayloadLength verifies the maximum payload length equals the expected
@@ -84,10 +103,14 @@ func TestMaxPayloadLength(t *testing.T) {
84103
name: "protocol version 10",
85104
pver: AddrV2Version,
86105
want: 35003,
106+
}, {
107+
name: "protocol version 11",
108+
pver: RelayTORv3Version,
109+
want: 51003,
87110
}, {
88111
name: "latest protocol version",
89112
pver: ProtocolVersion,
90-
want: 35003,
113+
want: 51003,
91114
}}
92115

93116
for _, test := range tests {
@@ -179,12 +202,14 @@ func TestAddrV2Wire(t *testing.T) {
179202
ipv4Address,
180203
ipv6Address,
181204
torv2Address,
205+
torv3Address,
182206
},
183207
wantBytes: bytes.Join([][]byte{
184-
{0x03},
208+
{0x04},
185209
serializedIPv4NetAddressBytes,
186210
serializedIPv6NetAddressBytes,
187211
serializedTORv2NetAddressBytes,
212+
serializedTORv3NetAddressBytes,
188213
}, []byte{}),
189214
}}
190215

@@ -230,6 +255,7 @@ func TestAddrV2WireErrors(t *testing.T) {
230255
pver := ProtocolVersion
231256
na := ipv4Address
232257
addrs := []*NetAddressV2{na}
258+
addrv2 := NewMsgAddrV2()
233259

234260
tests := []struct {
235261
name string
@@ -285,6 +311,14 @@ func TestAddrV2WireErrors(t *testing.T) {
285311
ioLimit: 3,
286312
writeErr: ErrTooManyAddrs,
287313
readErr: ErrTooManyAddrs,
314+
}, {
315+
name: "torv3 address invalid on protocol version 10",
316+
pver: RelayTORv3Version - 1,
317+
addrs: []*NetAddressV2{torv3Address},
318+
bytes: []byte{0x01},
319+
ioLimit: int(addrv2.MaxPayloadLength(RelayTORv3Version - 1)),
320+
writeErr: ErrInvalidMsg,
321+
readErr: ErrInvalidMsg,
288322
}}
289323

290324
t.Logf("Running %d tests", len(tests))

wire/netaddressv2.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const (
1717
IPv4Address
1818
IPv6Address
1919
TORv2Address
20+
TORv3Address
2021
)
2122

2223
// NetAddressV2 defines information about a peer on the network.

wire/protocol.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const (
1717
InitialProcotolVersion uint32 = 1
1818

1919
// ProtocolVersion is the latest protocol version this package supports.
20-
ProtocolVersion uint32 = 10
20+
ProtocolVersion uint32 = 11
2121

2222
// NodeBloomVersion is the protocol version which added the SFNodeBloom
2323
// service flag (unused).
@@ -55,6 +55,10 @@ const (
5555
// AddrV2Version is the protocol version which adds the addrv2 and
5656
// getaddrv2 messages.
5757
AddrV2Version uint32 = 10
58+
59+
// RelayTORv3Version is the protocol version which adds support for relaying
60+
// TORv3 addresses.
61+
RelayTORv3Version uint32 = 11
5862
)
5963

6064
// ServiceFlag identifies services supported by a Decred peer.

0 commit comments

Comments
 (0)