diff --git a/pkg/snet/packet_conn.go b/pkg/snet/packet_conn.go index f8fd378929..918c209b2d 100644 --- a/pkg/snet/packet_conn.go +++ b/pkg/snet/packet_conn.go @@ -15,8 +15,8 @@ package snet import ( + "context" "net" - "net/netip" "syscall" "time" @@ -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 { @@ -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 { @@ -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 { @@ -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. @@ -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 -} diff --git a/pkg/snet/snet.go b/pkg/snet/snet.go index cc4c13d503..fe2d46a9f9 100644 --- a/pkg/snet/snet.go +++ b/pkg/snet/snet.go @@ -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 { @@ -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 }