Skip to content

Commit

Permalink
peer/wire: Relay TORv3 addresses.
Browse files Browse the repository at this point in the history
This commit relays TORv3 addresses across the peer to peer network and
bumps the wire protocol version to 11.
  • Loading branch information
sefbkn committed Jan 5, 2022
1 parent 227a68f commit 4bf338f
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 21 deletions.
2 changes: 1 addition & 1 deletion peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

const (
// MaxProtocolVersion is the max protocol version the peer supports.
MaxProtocolVersion = wire.AddrV2Version
MaxProtocolVersion = wire.RelayTORv3Version

// outputBufferSize is the number of elements the output channels use.
outputBufferSize = 5000
Expand Down
5 changes: 3 additions & 2 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const (
connectionRetryInterval = time.Second * 5

// maxProtocolVersion is the max protocol version the server supports.
maxProtocolVersion = wire.AddrV2Version
maxProtocolVersion = wire.RelayTORv3Version

// These fields are used to track known addresses on a per-peer basis.
//
Expand Down Expand Up @@ -785,6 +785,7 @@ func isSupportedNetAddressTypeV2(netAddressType addrmgr.NetAddressType) bool {
case addrmgr.IPv4Address:
case addrmgr.IPv6Address:
case addrmgr.TORv2Address:
case addrmgr.TORv3Address:
return true
}
return false
Expand All @@ -794,7 +795,7 @@ func isSupportedNetAddressTypeV2(netAddressType addrmgr.NetAddressType) bool {
// specific address manager network address type is supported by the
// provided protocol version.
func getNetAddressTypeFilter(protocolVersion uint32) addrmgr.NetAddressTypeFilter {
if protocolVersion < wire.AddrV2Version {
if protocolVersion < wire.RelayTORv3Version {
return isSupportedNetAddressTypeV1
} else {
return isSupportedNetAddressTypeV2
Expand Down
62 changes: 47 additions & 15 deletions wire/msgaddrv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,30 +90,38 @@ func readNetAddressV2(op string, r io.Reader, pver uint32) (*NetAddressV2, error

// Read the ip bytes with a length varying by the network id type.
var ipBytes []byte
switch na.Type {
case IPv4Address:
switch {
case na.Type == IPv4Address:
var ip [4]byte
err := readElement(r, &ip)
if err != nil {
return nil, err
}
ipBytes = ip[:]
case TORv2Address:
case na.Type == TORv2Address:
var ip [10]byte
err := readElement(r, &ip)
if err != nil {
return nil, err
}
ipBytes = ip[:]
case IPv6Address:
case na.Type == IPv6Address:
var ip [16]byte
err := readElement(r, &ip)
if err != nil {
return nil, err
}
ipBytes = ip[:]
case na.Type == TORv3Address && pver >= RelayTORv3Version:
var ip [32]byte
err := readElement(r, &ip)
if err != nil {
return nil, err
}
ipBytes = ip[:]
default:
msg := fmt.Sprintf("unsupported network address type %v", na.Type)
msg := fmt.Sprintf("unsupported network address type %v for "+
"protocol version %d", na.Type, pver)
return nil, messageError(op, ErrInvalidMsg, msg)
}

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

netAddrIP := na.IP
switch na.Type {
case IPv4Address:
switch {
case na.Type == IPv4Address:
var ip [4]byte
if netAddrIP != nil {
copy(ip[:], netAddrIP)
Expand All @@ -150,7 +158,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
if err != nil {
return err
}
case TORv2Address:
case na.Type == TORv2Address:
var ip [10]byte
if netAddrIP != nil {
pubkey := netAddrIP[6:]
Expand All @@ -160,7 +168,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
if err != nil {
return err
}
case IPv6Address:
case na.Type == IPv6Address:
var ip [16]byte
if netAddrIP != nil {
copy(ip[:], net.IP(netAddrIP).To16())
Expand All @@ -169,8 +177,18 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
if err != nil {
return err
}
case na.Type == TORv3Address && pver >= RelayTORv3Version:
var ip [32]byte
if len(na.IP) == 32 {
copy(ip[:], net.IP(na.IP))
}
err = writeElement(w, ip)
if err != nil {
return err
}
default:
msg := fmt.Sprintf("unrecognized network address type %v", na.Type)
msg := fmt.Sprintf("unsupported network address type %v for "+
"protocol version %d", na.Type, pver)
return messageError(op, ErrInvalidMsg, msg)
}

Expand All @@ -180,11 +198,25 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er
// maxNetAddressPayloadV2 returns the max payload size for an address manager
// network address based on the protocol version.
func maxNetAddressPayloadV2(pver uint32) uint32 {
const timestampSize = 8
const servicesSize = 8
const addressTypeSize = 1
const maxAddressSize = 16
const portSize = 2
if pver < RelayTORv3Version {
const (
timestampSize = 8
servicesSize = 8
addressTypeSize = 1
maxAddressSize = 16
portSize = 2
)
return timestampSize + servicesSize + addressTypeSize + maxAddressSize +
portSize
}

const (
timestampSize = 8
servicesSize = 8
addressTypeSize = 1
maxAddressSize = 32
portSize = 2
)
return timestampSize + servicesSize + addressTypeSize + maxAddressSize +
portSize
}
Expand Down
38 changes: 36 additions & 2 deletions wire/msgaddrv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ var (
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}

torV3IpBytes = []byte{
0xb8, 0x39, 0x1d, 0x20, 0x03, 0xbb, 0x3b, 0xd2,
0x85, 0xb0, 0x35, 0xac, 0x8e, 0xb3, 0x0c, 0x80,
0xc4, 0xe2, 0xa2, 0x9b, 0xb7, 0xa2, 0xf0, 0xce,
0x0d, 0xf8, 0x74, 0x3c, 0x37, 0xec, 0x35, 0x93,
}

serializedIPv4NetAddressBytes = []byte{
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Services
Expand All @@ -60,12 +67,24 @@ var (
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x8f, 0x20,
}

serializedTORv3NetAddressBytes = []byte{
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x04,
0xb8, 0x39, 0x1d, 0x20, 0x03, 0xbb, 0x3b, 0xd2,
0x85, 0xb0, 0x35, 0xac, 0x8e, 0xb3, 0x0c, 0x80,
0xc4, 0xe2, 0xa2, 0x9b, 0xb7, 0xa2, 0xf0, 0xce,
0x0d, 0xf8, 0x74, 0x3c, 0x37, 0xec, 0x35, 0x93,
0x90, 0x20,
}
)

var (
ipv4Address = newNetAddressV2(IPv4Address, ipv4IpBytes, 8333)
ipv6Address = newNetAddressV2(IPv6Address, ipv6IpBytes, 8334)
torv2Address = newNetAddressV2(TORv2Address, torV2IpBytes, 8335)
torv3Address = newNetAddressV2(TORv3Address, torV3IpBytes, 8336)
)

// TestMaxPayloadLength verifies the maximum payload length equals the expected
Expand All @@ -84,10 +103,14 @@ func TestMaxPayloadLength(t *testing.T) {
name: "protocol version 10",
pver: AddrV2Version,
want: 35003,
}, {
name: "protocol version 11",
pver: RelayTORv3Version,
want: 51003,
}, {
name: "latest protocol version",
pver: ProtocolVersion,
want: 35003,
want: 51003,
}}

for _, test := range tests {
Expand Down Expand Up @@ -179,12 +202,14 @@ func TestAddrV2Wire(t *testing.T) {
ipv4Address,
ipv6Address,
torv2Address,
torv3Address,
},
wantBytes: bytes.Join([][]byte{
{0x03},
{0x04},
serializedIPv4NetAddressBytes,
serializedIPv6NetAddressBytes,
serializedTORv2NetAddressBytes,
serializedTORv3NetAddressBytes,
}, []byte{}),
}}

Expand Down Expand Up @@ -230,6 +255,7 @@ func TestAddrV2WireErrors(t *testing.T) {
pver := ProtocolVersion
na := ipv4Address
addrs := []*NetAddressV2{na}
addrv2 := NewMsgAddrV2()

tests := []struct {
name string
Expand Down Expand Up @@ -285,6 +311,14 @@ func TestAddrV2WireErrors(t *testing.T) {
ioLimit: 3,
writeErr: ErrTooManyAddrs,
readErr: ErrTooManyAddrs,
}, {
name: "torv3 address invalid on protocol version 10",
pver: RelayTORv3Version - 1,
addrs: []*NetAddressV2{torv3Address},
bytes: []byte{0x01},
ioLimit: int(addrv2.MaxPayloadLength(RelayTORv3Version - 1)),
writeErr: ErrInvalidMsg,
readErr: ErrInvalidMsg,
}}

t.Logf("Running %d tests", len(tests))
Expand Down
1 change: 1 addition & 0 deletions wire/netaddressv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
IPv4Address
IPv6Address
TORv2Address
TORv3Address
)

// NetAddressV2 defines information about a peer on the network.
Expand Down
6 changes: 5 additions & 1 deletion wire/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const (
InitialProcotolVersion uint32 = 1

// ProtocolVersion is the latest protocol version this package supports.
ProtocolVersion uint32 = 10
ProtocolVersion uint32 = 11

// NodeBloomVersion is the protocol version which added the SFNodeBloom
// service flag (unused).
Expand Down Expand Up @@ -55,6 +55,10 @@ const (
// AddrV2Version is the protocol version which adds the addrv2 and
// getaddrv2 messages.
AddrV2Version uint32 = 10

// RelayTORv3Version is the protocol version which adds support for relaying
// TORv3 addresses.
RelayTORv3Version uint32 = 11
)

// ServiceFlag identifies services supported by a Decred peer.
Expand Down

0 comments on commit 4bf338f

Please sign in to comment.