Skip to content

Commit

Permalink
allow unspecified address fon SCIONNetwork.Listen
Browse files Browse the repository at this point in the history
  • Loading branch information
JordiSubira committed Dec 5, 2023
1 parent 3e99676 commit 5cd34db
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 31 deletions.
14 changes: 1 addition & 13 deletions pkg/snet/addrutil/addrutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,5 @@ func DefaultLocalIP(ctx context.Context, sdConn daemon.Connector) (net.IP, error
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}
udpConn, err := net.DialUDP(udpAddr.Network(), nil, &udpAddr)
if err != nil {
return nil, err
}
defer udpConn.Close()
srcIP := udpConn.LocalAddr().(*net.UDPAddr).IP
return srcIP, nil
return snet.ResolveLocal(csAddr.IP)
}
29 changes: 24 additions & 5 deletions pkg/snet/snet.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ type Controller interface {
}

type Connector interface {
// OpenUDP returns a PacketConn which listens on the specified address.
// If address is nil or unspecified it listens on all available interfaces except
// for multicast IP addresses.
// If the address port is 0 a valid and free SCION/UDP port is automatically chosen. Otherwise,
// the specified port must be a valid SCION/UDP port.
OpenUDP(ctx context.Context, address *net.UDPAddr) (PacketConn, error)
}

Expand Down Expand Up @@ -133,10 +138,10 @@ type SCIONNetwork struct {
Metrics SCIONNetworkMetrics
}

// Dial returns a SCION connection to remote. Nil values for listen are not
// supported yet. Parameter network must be "udp". The returned connection's
// Read and Write methods can be used to receive and send SCION packets.
// Remote address requires a path and the underlay net hop to be set if the
// Dial returns a SCION connection to remote. Parameter network must be "udp".
// The returned connection's Read and Write methods can be used to receive
// and send SCION packets.
// Remote address requires a path and the underlay next hop to be set if the
// destination is in a remote AS.
//
// The context is used for connection setup, it doesn't affect the returned
Expand All @@ -158,7 +163,9 @@ func (n *SCIONNetwork) Dial(ctx context.Context, network string, listen *net.UDP

// Listen opens a PacketConn. The returned connection's ReadFrom and WriteTo methods
// can be used to receive and send SCION packets with per-packet addressing.
// Parameter network must be "udp".
// Parameter network must be "udp". If listen is unspecified address a suitable address
// will be chosen independently per packet. For finer-grained control, bind to a specific
// anycast address only.
//
// The context is used for connection setup, it doesn't affect the returned
// connection.
Expand Down Expand Up @@ -197,3 +204,15 @@ func (n *SCIONNetwork) Listen(ctx context.Context, network string, listen *net.U
}
return newConn(conn, packetConn, replyPather, start, end), nil
}

// 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}
udpConn, err := net.DialUDP(udpAddr.Network(), nil, &udpAddr)
if err != nil {
return nil, err
}
defer udpConn.Close()
srcIP := udpConn.LocalAddr().(*net.UDPAddr).IP
return srcIP, nil
}
17 changes: 15 additions & 2 deletions pkg/snet/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,26 @@ func (c *scionConnWriter) WriteTo(b []byte, raddr net.Addr) (int, error) {
return 0, serrors.New("invalid listen host IP", "ip", c.base.listen.Host.IP)
}

// XXX(JordiSubira): This simulates dynamic local address selection transparent to
// the application, if it decides to configure an unspecified address. For finer-grained
// control, the application should bind to a specific address only.
if listenHostIP.Unmap().IsUnspecified() {
resolvedLocal, err := ResolveLocal(nextHop.IP)
if err != nil {
return 0, err
}
listenHostIP, ok = netip.AddrFromSlice(resolvedLocal)
if !ok {
return 0, serrors.New("invalid resolved local addr", "ip", resolvedLocal)
}
}

pkt := &Packet{
Bytes: Bytes(c.buffer),
PacketInfo: PacketInfo{
Destination: dst,
Source: SCIONAddress{
IA: c.base.scionNet.LocalIA,
// FIXME(JordiSubira): Resolve local address which reaches nextHop.
IA: c.base.scionNet.LocalIA,
Host: addr.HostIP(listenHostIP),
},
Path: path,
Expand Down
1 change: 0 additions & 1 deletion private/app/path/pathprobe/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ go_library(
"//pkg/private/serrors:go_default_library",
"//pkg/slayers/path/scion:go_default_library",
"//pkg/snet:go_default_library",
"//pkg/snet/addrutil:go_default_library",
"//pkg/snet/path:go_default_library",
"@org_golang_x_sync//errgroup:go_default_library",
],
Expand Down
3 changes: 1 addition & 2 deletions private/app/path/pathprobe/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
"github.com/scionproto/scion/pkg/private/serrors"
"github.com/scionproto/scion/pkg/slayers/path/scion"
"github.com/scionproto/scion/pkg/snet"
"github.com/scionproto/scion/pkg/snet/addrutil"
snetpath "github.com/scionproto/scion/pkg/snet/path"
)

Expand Down Expand Up @@ -286,7 +285,7 @@ func (p Prober) resolveLocalIP(target *net.UDPAddr) (net.IP, error) {
if target == nil {
return nil, serrors.New("underlay nexthop missing")
}
localIP, err := addrutil.ResolveLocal(target.IP)
localIP, err := snet.ResolveLocal(target.IP)
if err != nil {
return nil, serrors.WrapStr("resolving local IP", err)
}
Expand Down
2 changes: 1 addition & 1 deletion scion-pki/certs/renew.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ func (r *renewer) requestRemote(
if localIP == nil {
// Resolve local IP based on underlay next hop
if nexthop != nil {
if localIP, err = addrutil.ResolveLocal(nexthop.IP); err != nil {
if localIP, err = snet.ResolveLocal(nexthop.IP); err != nil {
return nil, serrors.WrapStr("resolving local address", err)
}
} else {
Expand Down
3 changes: 1 addition & 2 deletions scion/cmd/scion/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"github.com/scionproto/scion/pkg/log"
"github.com/scionproto/scion/pkg/private/serrors"
"github.com/scionproto/scion/pkg/snet"
"github.com/scionproto/scion/pkg/snet/addrutil"
snetpath "github.com/scionproto/scion/pkg/snet/path"
"github.com/scionproto/scion/private/app"
"github.com/scionproto/scion/private/app/flag"
Expand Down Expand Up @@ -198,7 +197,7 @@ On other errors, ping will exit with code 2.
if remote.NextHop != nil {
target = remote.NextHop.IP
}
if localIP, err = addrutil.ResolveLocal(target); err != nil {
if localIP, err = snet.ResolveLocal(target); err != nil {
return serrors.WrapStr("resolving local address", err)

}
Expand Down
3 changes: 1 addition & 2 deletions scion/cmd/scion/traceroute.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/scionproto/scion/pkg/log"
"github.com/scionproto/scion/pkg/private/serrors"
"github.com/scionproto/scion/pkg/snet"
"github.com/scionproto/scion/pkg/snet/addrutil"
"github.com/scionproto/scion/private/app"
"github.com/scionproto/scion/private/app/flag"
"github.com/scionproto/scion/private/app/path"
Expand Down Expand Up @@ -152,7 +151,7 @@ On other errors, traceroute will exit with code 2.
if remote.NextHop != nil {
target = remote.NextHop.IP
}
if localIP, err = addrutil.ResolveLocal(target); err != nil {
if localIP, err = snet.ResolveLocal(target); err != nil {
return serrors.WrapStr("resolving local address", err)
}
printf("Resolved local address:\n %s\n", localIP)
Expand Down
10 changes: 10 additions & 0 deletions tools/end2end/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,16 @@ func (c *client) ping(ctx context.Context, n int, path snet.Path) error {
if !ok {
return serrors.New("invalid local host IP", "ip", integration.Local.Host.IP)
}
if localHostIP.Unmap().IsUnspecified() {
resolvedLocal, err := snet.ResolveLocal(remote.Host.IP)
if err != nil {
return err
}
localHostIP, ok = netip.AddrFromSlice(resolvedLocal)
if !ok {
return serrors.New("invalid resolved local addr", "ip", resolvedLocal)
}
}
pkt := &snet.Packet{
PacketInfo: snet.PacketInfo{
Destination: snet.SCIONAddress{
Expand Down
1 change: 0 additions & 1 deletion tools/pktgen/cmd/pktgen/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ go_library(
"//pkg/slayers:go_default_library",
"//pkg/slayers/path/scion:go_default_library",
"//pkg/snet:go_default_library",
"//pkg/snet/addrutil:go_default_library",
"//pkg/snet/path:go_default_library",
"//private/app:go_default_library",
"//private/app/command:go_default_library",
Expand Down
3 changes: 1 addition & 2 deletions tools/pktgen/cmd/pktgen/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
"github.com/scionproto/scion/pkg/slayers"
"github.com/scionproto/scion/pkg/slayers/path/scion"
"github.com/scionproto/scion/pkg/snet"
"github.com/scionproto/scion/pkg/snet/addrutil"
snetpath "github.com/scionproto/scion/pkg/snet/path"
"github.com/scionproto/scion/private/app"
"github.com/scionproto/scion/private/app/command"
Expand Down Expand Up @@ -194,7 +193,7 @@ func resolveLocal(dst *snet.UDPAddr) (netip.Addr, error) {
if dst.NextHop != nil {
target = dst.NextHop.IP
}
resolvedIP, err := addrutil.ResolveLocal(target)
resolvedIP, err := snet.ResolveLocal(target)
if err != nil {
return netip.Addr{}, serrors.WrapStr("resolving local address", err)
}
Expand Down

0 comments on commit 5cd34db

Please sign in to comment.