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) + } } }