import (
"fmt"
- "net"
"net/netip"
"github.com/anacrolix/dht/v2/krpc"
)
+type addrPorter interface {
+ AddrPort() netip.AddrPort
+}
+
func ipv4AddrPortFromKrpcNodeAddr(na krpc.NodeAddr) (_ netip.AddrPort, err error) {
ip4 := na.IP.To4()
if ip4 == nil {
func addrPortFromPeerRemoteAddr(pra PeerRemoteAddr) (netip.AddrPort, error) {
switch v := pra.(type) {
- case *net.TCPAddr:
- return v.AddrPort(), nil
- case *net.UDPAddr:
+ case addrPorter:
return v.AddrPort(), nil
case netip.AddrPort:
return v, nil
// This returns the address to use if we want to dial the peer again. It incorporates the peer's
// advertised listen port.
func (c *PeerConn) dialAddr() PeerRemoteAddr {
- if !c.outgoing && c.PeerListenPort != 0 {
- switch addr := c.RemoteAddr.(type) {
- case *net.TCPAddr:
- dialAddr := *addr
- dialAddr.Port = c.PeerListenPort
- return &dialAddr
- case *net.UDPAddr:
- dialAddr := *addr
- dialAddr.Port = c.PeerListenPort
- return &dialAddr
- default:
- panic(addr)
- }
+ if c.outgoing || c.PeerListenPort == 0 {
+ return c.RemoteAddr
}
- return c.RemoteAddr
+ addrPort, err := addrPortFromPeerRemoteAddr(c.RemoteAddr)
+ if err != nil {
+ c.logger.Levelf(
+ log.Warning,
+ "error parsing %q for alternate dial port: %v",
+ c.RemoteAddr,
+ err,
+ )
+ return c.RemoteAddr
+ }
+ return netip.AddrPortFrom(addrPort.Addr(), uint16(c.PeerListenPort))
}
func (c *PeerConn) pexEvent(t pexEventType) pexEvent {
return bytes.HasPrefix(pc.PeerID[:], []byte("-TR")) && pc.PeerID[7] == '-'
}
-func (pc *PeerConn) remoteAddrPort() Option[netip.AddrPort] {
- return Some(pc.conn.RemoteAddr().(interface {
- AddrPort() netip.AddrPort
- }).AddrPort())
-}
-
func (pc *PeerConn) remoteDialAddrPort() (netip.AddrPort, error) {
dialAddr := pc.dialAddr()
return addrPortFromPeerRemoteAddr(dialAddr)