diff --git a/go/lib/snet/addrutil/BUILD.bazel b/go/lib/snet/addrutil/BUILD.bazel index bcc1c9bf81..d0b2a4f5d2 100644 --- a/go/lib/snet/addrutil/BUILD.bazel +++ b/go/lib/snet/addrutil/BUILD.bazel @@ -8,6 +8,7 @@ go_library( deps = [ "//go/lib/addr:go_default_library", "//go/lib/ctrl/seg:go_default_library", + "//go/lib/sciond:go_default_library", "//go/lib/serrors:go_default_library", "//go/lib/slayers:go_default_library", "//go/lib/slayers/path:go_default_library", diff --git a/go/lib/snet/addrutil/addrutil.go b/go/lib/snet/addrutil/addrutil.go index fa74c0726e..7502e503ed 100644 --- a/go/lib/snet/addrutil/addrutil.go +++ b/go/lib/snet/addrutil/addrutil.go @@ -15,11 +15,13 @@ package addrutil import ( + "context" "encoding/binary" "net" "github.com/scionproto/scion/go/lib/addr" "github.com/scionproto/scion/go/lib/ctrl/seg" + "github.com/scionproto/scion/go/lib/sciond" "github.com/scionproto/scion/go/lib/serrors" "github.com/scionproto/scion/go/lib/slayers" "github.com/scionproto/scion/go/lib/slayers/path" @@ -94,6 +96,25 @@ func (p Pather) GetPath(svc addr.HostSVC, ps *seg.PathSegment) (*snet.SVCAddr, e } +// DefaultLocalIP returns _an_ IP of this host in the local AS. +// +// This returns a sensible but arbitrary local IP. In the general case the +// local IP would depend on the next hop of selected path. This approach will +// not work in more complicated setups where e.g. different network interfaces +// are used to talk to different AS interfaces. +// +// This is a simple workaround for not being able to use wildcard addresses +// with snet. Once available, a wildcard address should be used instead and +// this should be removed. +func DefaultLocalIP(ctx context.Context, sdConn sciond.Connector) (net.IP, error) { + // Choose CS as default routing "target". Using any of the interfaces would also make sense. + csAddr, err := sciond.TopoQuerier{Connector: sdConn}.UnderlayAnycast(ctx, addr.SvcCS) + if err != nil { + return nil, err + } + return ResolveLocal(csAddr.IP) +} + // ResolveLocal returns the local IP address used for traffic destined to dst. func ResolveLocal(dst net.IP) (net.IP, error) { udpAddr := net.UDPAddr{IP: dst, Port: 1} diff --git a/go/pkg/showpaths/showpaths.go b/go/pkg/showpaths/showpaths.go index c6fa614f87..ea19844e1f 100644 --- a/go/pkg/showpaths/showpaths.go +++ b/go/pkg/showpaths/showpaths.go @@ -159,7 +159,7 @@ func Run(ctx context.Context, dst addr.IA, cfg Config) (*Result, error) { if !cfg.NoProbe { // Resolve local IP in case it is not configured. if localIP = cfg.Local; localIP == nil { - localIP, err = findDefaultLocalIP(ctx, sdConn) + localIP, err = addrutil.DefaultLocalIP(ctx, sdConn) if err != nil { return nil, serrors.WrapStr("failed to determine local IP", err) } @@ -206,30 +206,3 @@ func Run(ctx context.Context, dst addr.IA, cfg Config) (*Result, error) { } return res, nil } - -// TODO(matzf): this is a simple, hopefully temporary, workaround to not having -// wildcard addresses in snet. -// Here we just use a seemingly sensible default IP, but in the general case -// the local IP would depend on the next hop of selected path. This approach -// will not work in more complicated setups where e.g. different network -// interface are used to talk to different AS interfaces. -// Once a available, a wildcard address should be used and this should simply -// be removed. -// -// findDefaultLocalIP returns _a_ IP of this host in the local AS. -func findDefaultLocalIP(ctx context.Context, sciondConn sciond.Connector) (net.IP, error) { - hostInLocalAS, err := findAnyHostInLocalAS(ctx, sciondConn) - if err != nil { - return nil, err - } - return addrutil.ResolveLocal(hostInLocalAS) -} - -// findAnyHostInLocalAS returns the IP address of some (infrastructure) host in the local AS. -func findAnyHostInLocalAS(ctx context.Context, sciondConn sciond.Connector) (net.IP, error) { - addr, err := sciond.TopoQuerier{Connector: sciondConn}.UnderlayAnycast(ctx, addr.SvcCS) - if err != nil { - return nil, err - } - return addr.IP, nil -} diff --git a/go/posix-gateway/BUILD.bazel b/go/posix-gateway/BUILD.bazel index 579967ce0e..fcd241c4e3 100644 --- a/go/posix-gateway/BUILD.bazel +++ b/go/posix-gateway/BUILD.bazel @@ -14,6 +14,7 @@ go_library( "//go/lib/prom:go_default_library", "//go/lib/sciond:go_default_library", "//go/lib/serrors:go_default_library", + "//go/lib/snet/addrutil:go_default_library", "//go/lib/sock/reliable:go_default_library", "//go/pkg/command:go_default_library", "//go/pkg/gateway:go_default_library", diff --git a/go/posix-gateway/main.go b/go/posix-gateway/main.go index 6af5d9e8ce..ee845203c9 100644 --- a/go/posix-gateway/main.go +++ b/go/posix-gateway/main.go @@ -35,6 +35,7 @@ import ( "github.com/scionproto/scion/go/lib/prom" "github.com/scionproto/scion/go/lib/sciond" "github.com/scionproto/scion/go/lib/serrors" + "github.com/scionproto/scion/go/lib/snet/addrutil" "github.com/scionproto/scion/go/lib/sock/reliable" "github.com/scionproto/scion/go/pkg/command" "github.com/scionproto/scion/go/pkg/gateway" @@ -115,6 +116,12 @@ func run(file string) error { if err != nil { return serrors.WrapStr("parsing control address", err) } + if len(controlAddress.IP) == 0 { + controlAddress.IP, err = addrutil.DefaultLocalIP(context.Background(), daemon) + if err != nil { + return serrors.WrapStr("determine default local IP", err) + } + } dataAddress, err := net.ResolveUDPAddr("udp", cfg.Gateway.DataAddr) if err != nil { return serrors.WrapStr("parsing data address", err) diff --git a/go/scion-pki/certs/renew.go b/go/scion-pki/certs/renew.go index 4835a20d85..bb7691814c 100644 --- a/go/scion-pki/certs/renew.go +++ b/go/scion-pki/certs/renew.go @@ -507,11 +507,7 @@ func findLocalAddr(ctx context.Context, sds sciond.Service) (*snet.UDPAddr, erro if err != nil { return nil, err } - csAddr, err := sciond.TopoQuerier{Connector: sdConn}.UnderlayAnycast(ctx, addr.SvcCS) - if err != nil { - return nil, err - } - localIP, err := addrutil.ResolveLocal(csAddr.IP) + localIP, err := addrutil.DefaultLocalIP(ctx, sdConn) if err != nil { return nil, err }