From e1584975605e59790936d0e986429791a5b8691c Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Thu, 24 Sep 2020 11:27:14 +0300 Subject: [PATCH] [#43] cmd/neofs-node: Support hostnames with dns, ipv4 and ipv6 addresses Signed-off-by: Alex Vanin --- cmd/neofs-node/config.go | 12 +----- pkg/network/address.go | 54 +++++++++++++++++++++++-- pkg/network/address_test.go | 2 +- pkg/services/object/head/remote.go | 2 +- pkg/services/object/put/remote.go | 2 +- pkg/services/object/range/remote.go | 2 +- pkg/services/object/rangehash/remote.go | 2 +- pkg/services/object/search/remote.go | 2 +- 8 files changed, 57 insertions(+), 21 deletions(-) diff --git a/cmd/neofs-node/config.go b/cmd/neofs-node/config.go index ef7973888..e614e3237 100644 --- a/cmd/neofs-node/config.go +++ b/cmd/neofs-node/config.go @@ -154,17 +154,7 @@ func initCfg(path string) *cfg { log, err := logger.NewLogger(viperCfg) fatalOnErr(err) - viperCfg.GetString(cfgListenAddress) - - endpoint, port, err := net.SplitHostPort(viperCfg.GetString(cfgListenAddress)) - fatalOnErr(err) - - netAddr, err := network.AddressFromString(strings.Join([]string{ - "/ip4", - endpoint, - "tcp", - port, - }, "/")) + netAddr, err := network.AddressFromString(viperCfg.GetString(cfgBootstrapAddress)) fatalOnErr(err) return &cfg{ diff --git a/pkg/network/address.go b/pkg/network/address.go index 03ec744fc..1e882bc71 100644 --- a/pkg/network/address.go +++ b/pkg/network/address.go @@ -1,11 +1,24 @@ package network import ( + "net" + "strings" + "github.com/multiformats/go-multiaddr" manet "github.com/multiformats/go-multiaddr-net" "github.com/pkg/errors" ) +/* + HostAddr strings: "localhost:8080", ":8080", "192.168.0.1:8080" + MultiAddr strings: "/dns4/localhost/tcp/8080", "/ip4/192.168.0.1/tcp/8080" + IPAddr strings: "192.168.0.1:8080" +*/ + +const ( + L4Protocol = "tcp" +) + // Address represents the NeoFS node // network address. type Address struct { @@ -18,12 +31,13 @@ type LocalAddressSource interface { LocalAddress() *Address } +// String returns multiaddr string func (a Address) String() string { return a.ma.String() } -// NetAddr returns network endpoint address in string format. -func (a Address) NetAddr() (string, error) { +// IPAddrString returns network endpoint address in string format. +func (a Address) IPAddrString() (string, error) { ip, err := manet.ToNetAddr(a.ma) if err != nil { return "", errors.Wrap(err, "could not get net addr") @@ -32,11 +46,19 @@ func (a Address) NetAddr() (string, error) { return ip.String(), nil } -// AddressFromString restores address from a string representation. +// AddressFromString restores address from a multiaddr string representation. func AddressFromString(s string) (*Address, error) { ma, err := multiaddr.NewMultiaddr(s) if err != nil { - return nil, err + s, err = multiaddrStringFromHostAddr(s) + if err != nil { + return nil, err + } + + ma, err = multiaddr.NewMultiaddr(s) // don't want recursion there + if err != nil { + return nil, err + } } return &Address{ @@ -44,6 +66,30 @@ func AddressFromString(s string) (*Address, error) { }, nil } +// multiaddrStringFromHostAddr converts "localhost:8080" to "/dns4/localhost/tcp/8080" +func multiaddrStringFromHostAddr(host string) (string, error) { + endpoint, port, err := net.SplitHostPort(host) + if err != nil { + return "", err + } + + var ( + prefix = "/dns4" + addr = endpoint + ) + + if ip := net.ParseIP(endpoint); ip != nil { + addr = ip.String() + if ip.To4() == nil { + prefix = "/ip6" + } else { + prefix = "/ip4" + } + } + + return strings.Join([]string{prefix, addr, L4Protocol, port}, "/"), nil +} + // IsLocalAddress returns true if network endpoint from local address // source is equal to network endpoint of passed address. func IsLocalAddress(src LocalAddressSource, addr *Address) bool { diff --git a/pkg/network/address_test.go b/pkg/network/address_test.go index ed2ea0d87..23ea712ad 100644 --- a/pkg/network/address_test.go +++ b/pkg/network/address_test.go @@ -24,7 +24,7 @@ func TestAddress_NetAddr(t *testing.T) { addr, err := AddressFromString(ma.String()) require.NoError(t, err) - netAddr, err := addr.NetAddr() + netAddr, err := addr.IPAddrString() require.NoError(t, err) require.Equal(t, ip+":"+port, netAddr) } diff --git a/pkg/services/object/head/remote.go b/pkg/services/object/head/remote.go index d53aff501..8898c9f22 100644 --- a/pkg/services/object/head/remote.go +++ b/pkg/services/object/head/remote.go @@ -22,7 +22,7 @@ func (h *remoteHeader) head(ctx context.Context, prm *Prm, handler func(*object. return errors.Wrapf(err, "(%T) could not receive private key", h) } - addr, err := h.node.NetAddr() + addr, err := h.node.IPAddrString() if err != nil { return err } diff --git a/pkg/services/object/put/remote.go b/pkg/services/object/put/remote.go index 69b401d8e..e4489a0ab 100644 --- a/pkg/services/object/put/remote.go +++ b/pkg/services/object/put/remote.go @@ -38,7 +38,7 @@ func (t *remoteTarget) Close() (*transformer.AccessIdentifiers, error) { return nil, errors.Wrapf(err, "(%T) could not receive private key", t) } - addr, err := t.addr.NetAddr() + addr, err := t.addr.IPAddrString() if err != nil { return nil, err } diff --git a/pkg/services/object/range/remote.go b/pkg/services/object/range/remote.go index 1d40315fc..9e82932ab 100644 --- a/pkg/services/object/range/remote.go +++ b/pkg/services/object/range/remote.go @@ -32,7 +32,7 @@ func (r *remoteRangeWriter) WriteTo(w io.Writer) (int64, error) { return 0, errors.Wrapf(err, "(%T) could not receive private key", r) } - addr, err := r.node.NetAddr() + addr, err := r.node.IPAddrString() if err != nil { return 0, err } diff --git a/pkg/services/object/rangehash/remote.go b/pkg/services/object/rangehash/remote.go index 1dbcaaf08..f873b4eb1 100644 --- a/pkg/services/object/rangehash/remote.go +++ b/pkg/services/object/rangehash/remote.go @@ -23,7 +23,7 @@ func (h *remoteHasher) hashRange(ctx context.Context, prm *Prm, handler func([][ return errors.Wrapf(err, "(%T) could not receive private key", h) } - addr, err := h.node.NetAddr() + addr, err := h.node.IPAddrString() if err != nil { return err } diff --git a/pkg/services/object/search/remote.go b/pkg/services/object/search/remote.go index f96d50593..f70f41f7a 100644 --- a/pkg/services/object/search/remote.go +++ b/pkg/services/object/search/remote.go @@ -24,7 +24,7 @@ func (s *remoteStream) stream(ctx context.Context, ch chan<- []*object.ID) error return errors.Wrapf(err, "(%T) could not receive private key", s) } - addr, err := s.addr.NetAddr() + addr, err := s.addr.IPAddrString() if err != nil { return err }