Skip to content

Commit

Permalink
pkg/snet: always use topology to resolve interfaces
Browse files Browse the repository at this point in the history
This way we can resolve interfaces even if they are dynamically
changing.
  • Loading branch information
lukedirtwalker committed Dec 23, 2024
1 parent 105ab1b commit bf0807a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 24 deletions.
37 changes: 21 additions & 16 deletions pkg/snet/packet_conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
package snet

import (
"context"
"net"
"net/netip"
"syscall"
"time"

Expand Down Expand Up @@ -121,8 +121,9 @@ type SCIONPacketConn struct {
// SCMP message is received.
SCMPHandler SCMPHandler
// Metrics are the metrics exported by the conn.
Metrics SCIONPacketConnMetrics
interfaceMap interfaceMap
Metrics SCIONPacketConnMetrics
// Topology provides interface information for the local AS.
Topology Topology
}

func (c *SCIONPacketConn) SetReadBuffer(bytes int) error {
Expand Down Expand Up @@ -286,7 +287,7 @@ func (c *SCIONPacketConn) lastHop(p *Packet) (*net.UDPAddr, error) {
if !path.Info.ConsDir {
ifID = path.SecondHop.ConsEgress
}
return c.interfaceMap.get(ifID)
return c.interfaceIDToAddr(ifID)
case epic.PathType:
var path epic.Path
if err := path.DecodeFromBytes(rpath.Raw); err != nil {
Expand All @@ -304,7 +305,7 @@ func (c *SCIONPacketConn) lastHop(p *Packet) (*net.UDPAddr, error) {
if !infoField.ConsDir {
ifID = hf.ConsEgress
}
return c.interfaceMap.get(ifID)
return c.interfaceIDToAddr(ifID)
case scion.PathType:
var path scion.Raw
if err := path.DecodeFromBytes(rpath.Raw); err != nil {
Expand All @@ -322,12 +323,26 @@ func (c *SCIONPacketConn) lastHop(p *Packet) (*net.UDPAddr, error) {
if !infoField.ConsDir {
ifID = hf.ConsEgress
}
return c.interfaceMap.get(ifID)
return c.interfaceIDToAddr(ifID)
default:
return nil, serrors.New("unknown path type", "type", rpath.PathType.String())
}
}

func (c *SCIONPacketConn) interfaceIDToAddr(ifID uint16) (*net.UDPAddr, error) {
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
intfs, err := c.Topology.Interfaces(ctx)
if err != nil {
return nil, serrors.Wrap("resolving interfaces address (fetching interfaces)", err, "interface", ifID)
}
addrPort, ok := intfs[ifID]
if !ok {
return nil, serrors.New("interface number not found", "interface", ifID)
}
return net.UDPAddrFromAddrPort(addrPort), nil
}

type SerializationOptions struct {
// If ComputeChecksums is true, the checksums in sent Packets are
// recomputed. Otherwise, the checksum value is left intact.
Expand All @@ -342,13 +357,3 @@ type SerializationOptions struct {
// unchanged.
InitializePaths bool
}

type interfaceMap map[uint16]netip.AddrPort

func (m interfaceMap) get(id uint16) (*net.UDPAddr, error) {
addrPort, ok := m[id]
if !ok {
return nil, serrors.New("interface number not found", "interface", id)
}
return net.UDPAddrFromAddrPort(addrPort), nil
}
12 changes: 4 additions & 8 deletions pkg/snet/snet.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ func (n *SCIONNetwork) OpenRaw(ctx context.Context, addr *net.UDPAddr) (PacketCo
if err != nil {
return nil, err
}
ifAddrs, err := n.Topology.Interfaces(ctx)
if err != nil {
return nil, err
}
if addr.Port == 0 {
pconn, err = listenUDPRange(addr, start, end)
} else {
Expand All @@ -118,10 +114,10 @@ func (n *SCIONNetwork) OpenRaw(ctx context.Context, addr *net.UDPAddr) (PacketCo
return nil, err
}
return &SCIONPacketConn{
Conn: pconn,
SCMPHandler: n.SCMPHandler,
Metrics: n.PacketConnMetrics,
interfaceMap: ifAddrs,
Conn: pconn,
SCMPHandler: n.SCMPHandler,
Metrics: n.PacketConnMetrics,
Topology: n.Topology,
}, nil
}

Expand Down

0 comments on commit bf0807a

Please sign in to comment.