From 9a640fd884910801c2c3695fb453c3b2ab5b81d4 Mon Sep 17 00:00:00 2001 From: Will Scott Date: Wed, 26 Feb 2020 10:50:47 -0800 Subject: [PATCH] add ToIP to complement ToNetAddr The specific implementations of net.Addr are internal implementation details of this package, and a downstream consumner shouldn't relay on the internal use of net.IPAddr / net.TCPAddr to implement that interface for direct extraction of IP. The consumer would instead need to go through a round of string conversion to retreive IP safely. Adding an IP extraction function to the interface here will allow the IP to be retreived more efficiently. --- convert.go | 19 +++++++++++++++++++ convert_test.go | 15 ++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/convert.go b/convert.go index 65f1444..8aa42fa 100644 --- a/convert.go +++ b/convert.go @@ -98,6 +98,25 @@ func FromIP(ip net.IP) (ma.Multiaddr, error) { return FromIPAndZone(ip, "") } +// ToIP converts a Multiaddr to a net.IP when possible +func ToIP(addr ma.Multiaddr) (net.IP, error) { + n, err := ToNetAddr(addr) + if err != nil { + return nil, err + } + + switch netAddr := n.(type) { + case *net.UDPAddr: + return netAddr.IP, nil + case *net.TCPAddr: + return netAddr.IP, nil + case *net.IPAddr: + return netAddr.IP, nil + default: + return nil, fmt.Errorf("non IP Multiaddr: %T", netAddr) + } +} + // DialArgs is a convenience function that returns network and address as // expected by net.Dial. See https://godoc.org/net#Dial for an overview of // possible return values (we do not support the unixpacket ones yet). Unix diff --git a/convert_test.go b/convert_test.go index 33e3332..1701824 100644 --- a/convert_test.go +++ b/convert_test.go @@ -51,11 +51,20 @@ func testToNetAddr(t *testing.T, maddr, ntwk, addr string) { // should convert properly switch ntwk { case "tcp": - _ = naddr.(*net.TCPAddr) + taddr := naddr.(*net.TCPAddr) + if ip, err := ToIP(m); err != nil || !taddr.IP.Equal(ip) { + t.Fatalf("ToIP() and ToNetAddr diverged: %s != %s", taddr, ip) + } case "udp": - _ = naddr.(*net.UDPAddr) + uaddr := naddr.(*net.UDPAddr) + if ip, err := ToIP(m); err != nil || !uaddr.IP.Equal(ip) { + t.Fatalf("ToIP() and ToNetAddr diverged: %s != %s", uaddr, ip) + } case "ip": - _ = naddr.(*net.IPAddr) + ipaddr := naddr.(*net.IPAddr) + if ip, err := ToIP(m); err != nil || !ipaddr.IP.Equal(ip) { + t.Fatalf("ToIP() and ToNetAddr diverged: %s != %s", ipaddr, ip) + } } }