Skip to content

Commit

Permalink
WIP: reintroduce default SCMP Handler in SCIONNetwork
Browse files Browse the repository at this point in the history
  • Loading branch information
matzf committed Jul 3, 2024
1 parent 02eaf69 commit df5c391
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 48 deletions.
44 changes: 19 additions & 25 deletions gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,12 @@ func (dpf DataplaneSessionFactory) New(id uint8, policyID int,
type PacketConnFactory struct {
Network *snet.SCIONNetwork
Addr *net.UDPAddr
Options []snet.ConnOption
}

func (pcf PacketConnFactory) New() (net.PacketConn, error) {
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
conn, err := pcf.Network.Listen(ctx, "udp", pcf.Addr, pcf.Options...)
conn, err := pcf.Network.Listen(ctx, "udp", pcf.Addr)
if err != nil {
return nil, serrors.WrapStr("creating packet conn", err)
}
Expand Down Expand Up @@ -408,23 +407,22 @@ func (g *Gateway) Run(ctx context.Context) error {
}

scionNetwork := &snet.SCIONNetwork{
Topology: g.Daemon,
Topology: g.Daemon,
SCMPHandler: snet.DefaultSCMPHandler{
RevocationHandler: revocationHandler,
SCMPErrors: g.Metrics.SCMPErrors,
Log: log.FromCtx(ctx).Debug,
},
PacketConnMetrics: g.Metrics.SCIONPacketConnMetrics,
Metrics: g.Metrics.SCIONNetworkMetrics,
}
scmpHandler := snet.DefaultSCMPHandler{
RevocationHandler: revocationHandler,
SCMPErrors: g.Metrics.SCMPErrors,
Log: log.FromCtx(ctx).Debug,
}

// Initialize the UDP/SCION QUIC conn for outgoing Gateway Discovery RPCs and outgoing Prefix
// Fetching. Open up a random high port for this.
clientConn, err := scionNetwork.Listen(
context.TODO(),
"udp",
&net.UDPAddr{IP: g.ControlClientIP},
snet.WithSCMPHandler(scmpHandler),
)
if err != nil {
return serrors.WrapStr("unable to initialize client QUIC connection", err)
Expand Down Expand Up @@ -507,7 +505,6 @@ func (g *Gateway) Run(ctx context.Context) error {
context.TODO(),
"udp",
g.ControlServerAddr,
snet.WithSCMPHandler(scmpHandler),
)
if err != nil {
return serrors.WrapStr("unable to initialize server QUIC connection", err)
Expand Down Expand Up @@ -555,8 +552,7 @@ func (g *Gateway) Run(ctx context.Context) error {
// received from the session monitors of the remote gateway.
// *********************************************************************************

probeConn, err := scionNetwork.Listen(context.TODO(), "udp", g.ProbeServerAddr,
snet.WithSCMPHandler(scmpHandler))
probeConn, err := scionNetwork.Listen(context.TODO(), "udp", g.ProbeServerAddr)
if err != nil {
return serrors.WrapStr("creating server probe conn", err)
}
Expand All @@ -571,16 +567,8 @@ func (g *Gateway) Run(ctx context.Context) error {
}()

// Start dataplane ingress
dataplaneServerConn, err := scionNetwork.Listen(
context.TODO(),
"udp",
g.DataServerAddr,
snet.WithSCMPHandler(scmpHandler),
)
if err != nil {
return serrors.WrapStr("creating ingress conn", err)
}
if err := StartIngress(ctx, dataplaneServerConn, deviceManager, g.Metrics); err != nil {
if err := StartIngress(ctx, scionNetwork, g.DataServerAddr, deviceManager,
g.Metrics); err != nil {

return err
}
Expand Down Expand Up @@ -623,14 +611,12 @@ func (g *Gateway) Run(ctx context.Context) error {
ProbeConnFactory: PacketConnFactory{
Network: scionNetwork,
Addr: &net.UDPAddr{IP: g.ProbeClientIP},
Options: []snet.ConnOption{snet.WithSCMPHandler(scmpHandler)},
},
DeviceManager: deviceManager,
DataplaneSessionFactory: DataplaneSessionFactory{
PacketConnFactory: PacketConnFactory{
Network: scionNetwork,
Addr: &net.UDPAddr{IP: g.DataClientIP},
Options: []snet.ConnOption{snet.WithSCMPHandler(scmpHandler)},
},
Metrics: CreateSessionMetrics(g.Metrics),
},
Expand Down Expand Up @@ -756,10 +742,18 @@ func CreateIngressMetrics(m *Metrics) dataplane.IngressMetrics {
}
}

func StartIngress(ctx context.Context, dataplaneServerConn *snet.Conn,
func StartIngress(ctx context.Context, scionNetwork *snet.SCIONNetwork, dataAddr *net.UDPAddr,
deviceManager control.DeviceManager, metrics *Metrics) error {

logger := log.FromCtx(ctx)
dataplaneServerConn, err := scionNetwork.Listen(
context.TODO(),
"udp",
dataAddr,
)
if err != nil {
return serrors.WrapStr("creating ingress conn", err)
}
ingressMetrics := CreateIngressMetrics(metrics)
ingressServer := &dataplane.IngressServer{
Conn: dataplaneServerConn,
Expand Down
2 changes: 1 addition & 1 deletion gateway/pathhealth/pathwatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ type pathWatcher struct {
// conn is the packet conn used to send probes on. The pathwatcher takes
// ownership and will close it on termination.
conn snet.PacketConn
// Handler for non-traceroute SCMP packets received on conn
// scmpHandler handles non-traceroute SCMP packets received on conn
scmpHandler snet.SCMPHandler
// id is used as SCMP traceroute ID. Since each pathwatcher should have it's
// own high port this value can be random.
Expand Down
22 changes: 10 additions & 12 deletions pkg/snet/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,48 +116,46 @@ func (c *Conn) Close() error {
}

// ConnOption is a functional option type for configuring a Conn.
type ConnOption func(o *options)
type ConnOption func(o *connOptions)

// WithReplyPather sets the reply pather for the connection.
// The reply pather is responsible for determining the path to send replies to.
// If this option is not provided, DefaultReplyPather is used.
func WithReplyPather(replyPather ReplyPather) ConnOption {
return func(o *options) {
return func(o *connOptions) {
o.replyPather = replyPather
}
}

// WithSCMPHandler sets the SCMP handler for the connection.
// The SCMP handler is a callback to react to SCMP messages, specifically to error messages.
// If this option is not provided, no SCMP handler is used (equivalent to
// DefaultSCMPHandler with an empty RevocationHandler).
func WithSCMPHandler(scmpHandler SCMPHandler) ConnOption {
return func(o *options) {
return func(o *connOptions) {
o.scmpHandler = scmpHandler
}
}

// WithRemote sets the remote address for the connection.
// This only applies to NewCookedConn, but not Dial/Listen.
func WithRemote(addr *UDPAddr) ConnOption {
return func(o *options) {
return func(o *connOptions) {
o.remote = addr
}
}

type options struct {
type connOptions struct {
replyPather ReplyPather
scmpHandler SCMPHandler
remote *UDPAddr
}

func apply(opts []ConnOption) options {
o := options{
replyPather: DefaultReplyPather{},
scmpHandler: nil,
}
func apply(opts []ConnOption) connOptions {
o := connOptions{}
for _, option := range opts {
option(&o)
}
if o.replyPather == nil {
o.replyPather = DefaultReplyPather{}
}
return o
}
26 changes: 21 additions & 5 deletions pkg/snet/snet.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import (
"errors"
"net"
"net/netip"
"slices"
"syscall"

"github.com/scionproto/scion/pkg/addr"
Expand Down Expand Up @@ -66,7 +65,10 @@ type SCIONNetwork struct {
// traffic.
Topology Topology

// XXX: SCMPHandler / Reverser
// SCMPHandler is the SCMPHandler used by default for Conns opened with Dial/Listen.
SCMPHandler SCMPHandler
// ReplyPather is the ReplyPather used by default for Conns opened with Dial/Listen.
ReplyPather ReplyPather

Metrics SCIONNetworkMetrics
PacketConnMetrics SCIONPacketConnMetrics
Expand Down Expand Up @@ -146,8 +148,15 @@ func (n *SCIONNetwork) Dial(
return nil, err
}
log.FromCtx(ctx).Debug("UDP socket opened on", "addr", packetConn.LocalAddr(), "to", remote)
options = append(slices.Clone(options), WithRemote(remote))
return NewCookedConn(packetConn, n.Topology, options...)
return NewCookedConn(
packetConn,
n.Topology,
append([]ConnOption{
WithSCMPHandler(n.SCMPHandler),
WithReplyPather(n.ReplyPather),
WithRemote(remote),
}, options...)...,
)
}

// Listen opens a Conn. The returned connection's ReadFrom and WriteTo methods
Expand All @@ -173,7 +182,14 @@ func (n *SCIONNetwork) Listen(
return nil, err
}
log.FromCtx(ctx).Debug("UDP socket openned on", "addr", packetConn.LocalAddr())
return NewCookedConn(packetConn, n.Topology, options...)
return NewCookedConn(
packetConn,
n.Topology,
append([]ConnOption{
WithSCMPHandler(n.SCMPHandler),
WithReplyPather(n.ReplyPather),
}, options...)...,
)
}

func listenUDPRange(addr *net.UDPAddr, start, end uint16) (*net.UDPConn, error) {
Expand Down
9 changes: 4 additions & 5 deletions scion-pki/certs/renew.go
Original file line number Diff line number Diff line change
Expand Up @@ -738,12 +738,12 @@ func (r *renewer) requestRemote(

sn := &snet.SCIONNetwork{
Topology: r.Daemon,
SCMPHandler: snet.DefaultSCMPHandler{
RevocationHandler: daemon.RevHandler{Connector: r.Daemon},
},
}

scmpHandler := snet.DefaultSCMPHandler{
RevocationHandler: daemon.RevHandler{Connector: r.Daemon},
}
conn, err := sn.Listen(ctx, "udp", local.Host, snet.WithSCMPHandler(scmpHandler))
conn, err := sn.Listen(ctx, "udp", local.Host)
if err != nil {
return nil, serrors.WrapStr("dialing", err)
}
Expand All @@ -758,7 +758,6 @@ func (r *renewer) requestRemote(
Resolver: &svc.Resolver{
LocalIA: local.IA,
Network: sn,
// XXX scmp handler lost here
LocalIP: local.Host.IP,
},
},
Expand Down

0 comments on commit df5c391

Please sign in to comment.