This can occur on Linux with an interface with an ipv6 address when a user specifies their own hostname as a special peer. In this situation net.LookupHost(address) in Peer.Init() on line 51 of p2p/peer.go returns an array of both the ipv6 and the ipv4 address as this custom debug output shows:
As you can see, the resolver for Linux is returning an ipv6 address with the interface appended: fe80::f6:ecff:fe05:5ffc%eth0.
Next, on line 65Peer.LocationFromAddress() is called and this again calls net.LookupHost(p.Address). But since this relies on the same Linux resolver, this does not return an error and just returns the same IP address it was given, still including the appended %eth0. Now when net.ParseIP(p.Address) is called again, it returns nil because it does not handle the appended interface name. Again, this custom debug output shows this:
This is not checked for, and we proceed to deference the nil pointer on line 141, causing the panic.
Solutions
The simplest thing to do here is just check if ip == nil after line 135 and return 0 if so.
More niche things could be done to handle this like stripping out everything after % from addresses, but this is an edge case that doesn't matter since we don't need to peer with ourselves anyway.
When Peer.Address contains an address like "fe80::f6:ecff:fe05:5ffc%eth0", Peer.LocationFromAddress panics due to
index out of range
.The full panic is:
This can occur on Linux with an interface with an ipv6 address when a user specifies their own hostname as a special peer. In this situation
net.LookupHost(address)
inPeer.Init()
on line 51 ofp2p/peer.go
returns an array of both the ipv6 and the ipv4 address as this custom debug output shows:As you can see, the resolver for Linux is returning an ipv6 address with the interface appended:
fe80::f6:ecff:fe05:5ffc%eth0
.Next, on line 65
Peer.LocationFromAddress()
is called and this again callsnet.LookupHost(p.Address)
. But since this relies on the same Linux resolver, this does not return an error and just returns the same IP address it was given, still including the appended%eth0
. Now whennet.ParseIP(p.Address)
is called again, it returnsnil
because it does not handle the appended interface name. Again, this custom debug output shows this:This is not checked for, and we proceed to deference the nil pointer on line 141, causing the panic.
Solutions
The simplest thing to do here is just check if
ip == nil
after line 135 and return 0 if so.More niche things could be done to handle this like stripping out everything after
%
from addresses, but this is an edge case that doesn't matter since we don't need to peer with ourselves anyway.