Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

multi: Add getaddrv2 and addrv2. #2627

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
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 @@ -783,6 +783,7 @@ func isSupportedNetAddressTypeV2(netAddressType addrmgr.NetAddressType) bool {
switch netAddressType {
case addrmgr.IPv4Address:
case addrmgr.IPv6Address:
case addrmgr.TORv3Address:
return true
}
return false
Expand All @@ -792,7 +793,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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep pver. It's used everywhere and is thus consistent.

if protocolVersion < wire.AddrV2Version {
if protocolVersion < wire.RelayTORv3Version {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this still be AddrV2Version? It's v1 before that point, not v2.

return isSupportedNetAddressTypeV1
} else {
return isSupportedNetAddressTypeV2
Expand Down
58 changes: 45 additions & 13 deletions wire/msgaddrv2.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,31 @@ 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 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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a new error code ErrUnknownNetAddrType since ErrInvalidMsg is intended more for a message having an invalid structure and it is more consistent with the case of invalid types in transactions ErrUnknownTxType.

}

Expand All @@ -133,8 +141,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 @@ -143,7 +151,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 link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems incorrect to me. An entry without a valid address for an expected net address type is an error.

copy(ip[:], net.IP(netAddrIP).To16())
Expand All @@ -152,8 +160,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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ErrUnknownNetAddrType per previous.

}

Expand All @@ -163,11 +181,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 (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These could all go outside of the if and be reused since all of them are the same except maxAddressSize.

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
42 changes: 38 additions & 4 deletions wire/msgaddrv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ var (
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
}

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 @@ -48,11 +55,23 @@ var (
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x8e, 0x20,
}

serializedTORv3NetAddressBytes = []byte{
0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03,
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)
ipv4Address = newNetAddressV2(IPv4Address, ipv4IpBytes, 8333)
ipv6Address = newNetAddressV2(IPv6Address, ipv6IpBytes, 8334)
torv3Address = newNetAddressV2(TORv3Address, torV3IpBytes, 8336)
)

// TestMaxPayloadLength verifies the maximum payload length equals the expected
Expand All @@ -71,10 +90,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 @@ -165,11 +188,13 @@ func TestAddrV2Wire(t *testing.T) {
addrs: []*NetAddressV2{
ipv4Address,
ipv6Address,
torv3Address,
},
wantBytes: bytes.Join([][]byte{
{0x02},
{0x03},
serializedIPv4NetAddressBytes,
serializedIPv6NetAddressBytes,
serializedTORv3NetAddressBytes,
}, []byte{}),
}}

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

tests := []struct {
name string
Expand Down Expand Up @@ -270,6 +296,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 @@ -16,6 +16,7 @@ const (
UnknownAddressType NetAddressType = iota
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use iota for constants that can't be changed as it's too easy to accidentally change them when new items are added.

IPv4Address
IPv6Address
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