mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
p2p: fix ports handling, add test cases
This commit is contained in:
parent
09f5fd6983
commit
2f8ab8080f
3 changed files with 110 additions and 25 deletions
|
|
@ -74,6 +74,7 @@ func TestNodeEndpoints(t *testing.T) {
|
||||||
wantUDP int
|
wantUDP int
|
||||||
wantTCP int
|
wantTCP int
|
||||||
wantQUIC int
|
wantQUIC int
|
||||||
|
wantDNS string
|
||||||
}
|
}
|
||||||
tests := []endpointTest{
|
tests := []endpointTest{
|
||||||
{
|
{
|
||||||
|
|
@ -268,6 +269,54 @@ func TestNodeEndpoints(t *testing.T) {
|
||||||
wantIP: netip.MustParseAddr("2001::ff00:0042:8329"),
|
wantIP: netip.MustParseAddr("2001::ff00:0042:8329"),
|
||||||
wantQUIC: 9001,
|
wantQUIC: 9001,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "dns-only",
|
||||||
|
node: func() *Node {
|
||||||
|
var r enr.Record
|
||||||
|
n := SignNull(&r, id)
|
||||||
|
n.dnsName = "example.com"
|
||||||
|
n.tcp = 30303
|
||||||
|
n.udp = 30303
|
||||||
|
return n
|
||||||
|
}(),
|
||||||
|
wantTCP: 30303,
|
||||||
|
wantUDP: 30303,
|
||||||
|
wantDNS: "example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dns-with-ports",
|
||||||
|
node: func() *Node {
|
||||||
|
var r enr.Record
|
||||||
|
r.Set(enr.TCP(9000))
|
||||||
|
r.Set(enr.UDP(9001))
|
||||||
|
n := SignNull(&r, id)
|
||||||
|
n.dnsName = "node.example.org"
|
||||||
|
n.tcp = 9000
|
||||||
|
n.udp = 9001
|
||||||
|
return n
|
||||||
|
}(),
|
||||||
|
wantTCP: 9000,
|
||||||
|
wantUDP: 9001,
|
||||||
|
wantDNS: "node.example.org",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "dns-with-ip-fallback",
|
||||||
|
node: func() *Node {
|
||||||
|
var r enr.Record
|
||||||
|
r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.1.1")))
|
||||||
|
r.Set(enr.TCP(9000))
|
||||||
|
r.Set(enr.UDP(9000))
|
||||||
|
n := SignNull(&r, id)
|
||||||
|
n.dnsName = "node.example.org"
|
||||||
|
n.tcp = 9000
|
||||||
|
n.udp = 9000
|
||||||
|
return n
|
||||||
|
}(),
|
||||||
|
wantIP: netip.MustParseAddr("192.168.1.1"),
|
||||||
|
wantTCP: 9000,
|
||||||
|
wantUDP: 9000,
|
||||||
|
wantDNS: "node.example.org",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
@ -284,6 +333,9 @@ func TestNodeEndpoints(t *testing.T) {
|
||||||
if quic, _ := test.node.QUICEndpoint(); test.wantQUIC != int(quic.Port()) {
|
if quic, _ := test.node.QUICEndpoint(); test.wantQUIC != int(quic.Port()) {
|
||||||
t.Errorf("node has wrong QUIC port %d, want %d", quic.Port(), test.wantQUIC)
|
t.Errorf("node has wrong QUIC port %d, want %d", quic.Port(), test.wantQUIC)
|
||||||
}
|
}
|
||||||
|
if test.wantDNS != test.node.DNSName() {
|
||||||
|
t.Errorf("node has wrong DNS name %s, want %s", test.node.DNSName(), test.wantDNS)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,32 @@ func NewV4(pubkey *ecdsa.PublicKey, ip net.IP, tcp, udp int) *Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewV4WithDNS(pubkey *ecdsa.PublicKey, ip net.IP, dnsName string, tcp, udp int) *Node {
|
||||||
|
var r enr.Record
|
||||||
|
if len(ip) > 0 {
|
||||||
|
r.Set(enr.IP(ip))
|
||||||
|
}
|
||||||
|
// Always set TCP/UDP ports regardless of IP
|
||||||
|
// This is to ensure that the node is always
|
||||||
|
// considered valid even if the IP is not
|
||||||
|
// set.
|
||||||
|
if tcp != 0 {
|
||||||
|
r.Set(enr.TCP(tcp))
|
||||||
|
}
|
||||||
|
if udp != 0 {
|
||||||
|
r.Set(enr.UDP(udp))
|
||||||
|
}
|
||||||
|
signV4Compat(&r, pubkey)
|
||||||
|
n, err := New(v4CompatID{}, &r)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
n.dnsName = dnsName
|
||||||
|
n.tcp = uint16(tcp)
|
||||||
|
n.udp = uint16(udp)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
// isNewV4 returns true for nodes created by NewV4.
|
// isNewV4 returns true for nodes created by NewV4.
|
||||||
func isNewV4(n *Node) bool {
|
func isNewV4(n *Node) bool {
|
||||||
var k s256raw
|
var k s256raw
|
||||||
|
|
@ -139,16 +165,18 @@ func parseComplete(rawurl string) (*Node, error) {
|
||||||
}
|
}
|
||||||
// Check if hostname is an IP address and create node accordingly
|
// Check if hostname is an IP address and create node accordingly
|
||||||
hostname := u.Hostname()
|
hostname := u.Hostname()
|
||||||
if ip := net.ParseIP(hostname); ip != nil {
|
ip := net.ParseIP(hostname)
|
||||||
// Create node with IP
|
if ip == nil {
|
||||||
node := NewV4(id, ip, int(tcpPort), int(udpPort))
|
ips, err := lookupIPFunc(hostname)
|
||||||
return node, nil
|
if err != nil {
|
||||||
|
return NewV4WithDNS(id, nil, hostname, int(tcpPort), int(udpPort)), nil
|
||||||
|
}
|
||||||
|
ip = ips[0]
|
||||||
}
|
}
|
||||||
|
if ipv4 := ip.To4(); ipv4 != nil {
|
||||||
// Create node for DNS name
|
ip = ipv4
|
||||||
node := NewV4(id, nil, int(tcpPort), int(udpPort))
|
}
|
||||||
node.dnsName = hostname
|
return NewV4(id, ip, int(tcpPort), int(udpPort)), nil
|
||||||
return node, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsePubkey parses a hex-encoded secp256k1 public key.
|
// parsePubkey parses a hex-encoded secp256k1 public key.
|
||||||
|
|
@ -178,20 +206,19 @@ func (n *Node) URLv4() string {
|
||||||
nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:])
|
nodeid = fmt.Sprintf("%s.%x", scheme, n.id[:])
|
||||||
}
|
}
|
||||||
u := url.URL{Scheme: "enode"}
|
u := url.URL{Scheme: "enode"}
|
||||||
if !n.ip.IsValid() {
|
if !n.ip.IsValid() && n.dnsName == "" {
|
||||||
u.Host = nodeid
|
u.Host = nodeid
|
||||||
|
return u.String()
|
||||||
|
}
|
||||||
|
u.User = url.User(nodeid)
|
||||||
|
if n.dnsName != "" {
|
||||||
|
u.Host = fmt.Sprintf("%s:%d", n.dnsName, n.TCP())
|
||||||
} else {
|
} else {
|
||||||
u.User = url.User(nodeid)
|
addr := net.TCPAddr{IP: n.IP(), Port: n.TCP()}
|
||||||
// Use DNS name if available, otherwise use IP
|
u.Host = addr.String()
|
||||||
if n.DNSName() != "" {
|
}
|
||||||
u.Host = fmt.Sprintf("%s:%d", n.DNSName(), n.TCP())
|
if n.UDP() != n.TCP() {
|
||||||
} else {
|
u.RawQuery = "discport=" + strconv.Itoa(n.UDP())
|
||||||
addr := net.TCPAddr{IP: n.IP(), Port: n.TCP()}
|
|
||||||
u.Host = addr.String()
|
|
||||||
}
|
|
||||||
if n.UDP() != n.TCP() {
|
|
||||||
u.RawQuery = "discport=" + strconv.Itoa(n.UDP())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return u.String()
|
return u.String()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,10 +70,6 @@ var parseNodeTests = []struct {
|
||||||
wantError: enr.ErrInvalidSig.Error(),
|
wantError: enr.ErrInvalidSig.Error(),
|
||||||
},
|
},
|
||||||
// Complete node URLs with IP address and ports
|
// Complete node URLs with IP address and ports
|
||||||
{
|
|
||||||
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@invalid.:3",
|
|
||||||
wantError: `no such host`,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo",
|
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo",
|
||||||
wantError: `invalid port`,
|
wantError: `invalid port`,
|
||||||
|
|
@ -82,6 +78,16 @@ var parseNodeTests = []struct {
|
||||||
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:3?discport=foo",
|
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:3?discport=foo",
|
||||||
wantError: `invalid discport in query`,
|
wantError: `invalid discport in query`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@valid.:3",
|
||||||
|
wantResult: NewV4WithDNS(
|
||||||
|
hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
|
||||||
|
nil,
|
||||||
|
"valid.",
|
||||||
|
3,
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150",
|
input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150",
|
||||||
wantResult: NewV4(
|
wantResult: NewV4(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue