Skip to content

Commit

Permalink
pan: expose scmpHandler (#266)
Browse files Browse the repository at this point in the history
* expose scmpHandler

* change to functional options pattern

* ignore nil opts

* fix API calls

* pass
  • Loading branch information
JordiSubira authored Feb 11, 2025
1 parent f70181a commit 1e300df
Show file tree
Hide file tree
Showing 24 changed files with 163 additions and 63 deletions.
4 changes: 2 additions & 2 deletions _examples/helloquic/helloquic.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func runServer(listen netip.AddrPort) error {
Certificates: quicutil.MustGenerateSelfSignedCert(),
NextProtos: []string{"hello-quic"},
}
listener, err := pan.ListenQUIC(context.Background(), listen, nil, tlsCfg, nil)
listener, err := pan.ListenQUIC(context.Background(), listen, tlsCfg, nil)
if err != nil {
return err
}
Expand Down Expand Up @@ -119,7 +119,7 @@ func runClient(address string, count int) error {
Timeout: time.Second,
}
selector.SetActive(2)
session, err := pan.DialQUIC(context.Background(), netip.AddrPort{}, addr, nil, selector, "", tlsCfg, nil)
session, err := pan.DialQUIC(context.Background(), netip.AddrPort{}, addr, "", tlsCfg, nil, pan.WithSelector(selector))
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions _examples/helloworld/helloworld.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func main() {
}

func runServer(listen netip.AddrPort) error {
conn, err := pan.ListenUDP(context.Background(), listen, nil)
conn, err := pan.ListenUDP(context.Background(), listen)
if err != nil {
return err
}
Expand Down Expand Up @@ -78,7 +78,7 @@ func runClient(address string, count int) error {
if err != nil {
return err
}
conn, err := pan.DialUDP(context.Background(), netip.AddrPort{}, addr, nil, nil)
conn, err := pan.DialUDP(context.Background(), netip.AddrPort{}, addr)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion _examples/sgrpc/client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func NewPanQuicDialer(tlsCfg *tls.Config) func(context.Context, string) (net.Con
}

clientQuicConfig := &quic.Config{KeepAlivePeriod: 15 * time.Second}
session, err := pan.DialQUIC(ctx, netip.AddrPort{}, panAddr, nil, nil, "", tlsCfg, clientQuicConfig)
session, err := pan.DialQUIC(ctx, netip.AddrPort{}, panAddr, "", tlsCfg, clientQuicConfig)
if err != nil {
return nil, fmt.Errorf("did not dial: %w", err)
}
Expand Down
2 changes: 1 addition & 1 deletion _examples/sgrpc/server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func main() {
NextProtos: []string{"echo_service"},
}

quicListener, err := pan.ListenQUIC(context.Background(), addr, nil, tlsCfg, nil)
quicListener, err := pan.ListenQUIC(context.Background(), addr, tlsCfg, nil)
if err != nil {
log.Fatalf("failed to listen SCION QUIC on %s: %v", *ServerAddr, err)
}
Expand Down
4 changes: 2 additions & 2 deletions bwtester/bwtestclient/bwtestclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func runBwtest(local netip.AddrPort, serverCCAddr pan.UDPAddr, policy pan.Policy

// Control channel connection
ccSelector := pan.NewDefaultSelector()
ccConn, err := pan.DialUDP(context.Background(), local, serverCCAddr, policy, ccSelector)
ccConn, err := pan.DialUDP(context.Background(), local, serverCCAddr, pan.WithPolicy(policy), pan.WithSelector(ccSelector))
if err != nil {
return
}
Expand All @@ -345,7 +345,7 @@ func runBwtest(local netip.AddrPort, serverCCAddr pan.UDPAddr, policy pan.Policy
serverDCAddr := serverCCAddr.WithPort(serverCCAddr.Port + 1)

// Data channel connection
dcConn, err := pan.DialUDP(context.Background(), dcLocal, serverDCAddr, policy, nil)
dcConn, err := pan.DialUDP(context.Background(), dcLocal, serverDCAddr, pan.WithPolicy(policy))
if err != nil {
return
}
Expand Down
4 changes: 2 additions & 2 deletions bwtester/bwtestserver/bwtestserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func runServer(listen netip.AddrPort) error {
results := make(resultsMap)

ccSelector := pan.NewDefaultReplySelector()
ccConn, err := pan.ListenUDP(context.Background(), listen, ccSelector)
ccConn, err := pan.ListenUDP(context.Background(), listen, pan.WithReplySelector(ccSelector))
if err != nil {
return err
}
Expand Down Expand Up @@ -287,7 +287,7 @@ func (r resultsMap) purgeExpired() {
}

func listenConnected(local netip.AddrPort, remote pan.UDPAddr, selector pan.ReplySelector) (net.Conn, error) {
conn, err := pan.ListenUDP(context.Background(), local, selector)
conn, err := pan.ListenUDP(context.Background(), local, pan.WithReplySelector(selector))
return connectedPacketConn{
ListenConn: conn,
remote: remote,
Expand Down
4 changes: 1 addition & 3 deletions netcat/quic.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ func DoListenQUIC(port uint16) (chan io.ReadWriteCloser, error) {
quicListener, err := pan.ListenQUIC(
context.Background(),
netip.AddrPortFrom(netip.Addr{}, port),
nil,
&tls.Config{
Certificates: quicutil.MustGenerateSelfSignedCert(),
NextProtos: nextProtos,
Expand Down Expand Up @@ -74,14 +73,13 @@ func DoDialQUIC(remote string, policy pan.Policy) (io.ReadWriteCloser, error) {
context.Background(),
netip.AddrPort{},
remoteAddr,
policy,
nil,
pan.MangleSCIONAddr(remote),
&tls.Config{
InsecureSkipVerify: true,
NextProtos: nextProtos,
},
&quic.Config{KeepAlivePeriod: 15 * time.Second},
pan.WithPolicy(policy),
)
if err != nil {
return nil, err
Expand Down
3 changes: 1 addition & 2 deletions netcat/udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func DoDialUDP(remote string, policy pan.Policy) (io.ReadWriteCloser, error) {
if err != nil {
return nil, err
}
conn, err := pan.DialUDP(context.Background(), netip.AddrPort{}, remoteAddr, policy, nil)
conn, err := pan.DialUDP(context.Background(), netip.AddrPort{}, remoteAddr, pan.WithPolicy(policy))
if err != nil {
return nil, err
}
Expand All @@ -71,7 +71,6 @@ func DoListenUDP(port uint16) (chan io.ReadWriteCloser, error) {
conn, err := pan.ListenUDP(
context.Background(),
netip.AddrPortFrom(netip.Addr{}, port),
nil,
)
if err != nil {
return nil, err
Expand Down
32 changes: 22 additions & 10 deletions pkg/pan/quic_dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,17 @@ func (s *QUICEarlySession) CloseWithError(code quic.ApplicationErrorCode, desc s
//
// The host parameter is used for SNI.
// The tls.Config must define an application protocol (using NextProtos).
func DialQUIC(ctx context.Context,
local netip.AddrPort, remote UDPAddr, policy Policy, selector Selector,
host string, tlsConf *tls.Config, quicConf *quic.Config) (*QUICSession, error) {

conn, err := DialUDP(ctx, local, remote, policy, selector)
func DialQUIC(
ctx context.Context,
local netip.AddrPort,
remote UDPAddr,
host string,
tlsConf *tls.Config,
quicConf *quic.Config,
connOptions ...ConnOptions,
) (*QUICSession, error) {

conn, err := DialUDP(ctx, local, remote, connOptions...)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -87,11 +93,17 @@ func DialQUIC(ctx context.Context,
}

// DialQUICEarly establishes a new 0-RTT QUIC connection to a server. Analogous to DialQUIC.
func DialQUICEarly(ctx context.Context,
local netip.AddrPort, remote UDPAddr, policy Policy, selector Selector,
host string, tlsConf *tls.Config, quicConf *quic.Config) (*QUICEarlySession, error) {

conn, err := DialUDP(ctx, local, remote, policy, selector)
func DialQUICEarly(
ctx context.Context,
local netip.AddrPort,
remote UDPAddr,
host string,
tlsConf *tls.Config,
quicConf *quic.Config,
connOptions ...ConnOptions,
) (*QUICEarlySession, error) {

conn, err := DialUDP(ctx, local, remote, connOptions...)
if err != nil {
return nil, err
}
Expand Down
11 changes: 8 additions & 3 deletions pkg/pan/quic_listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,15 @@ func (l *QUICListener) Close() error {
// ListenQUIC listens for QUIC connections on a SCION/UDP port.
//
// See note on wildcard addresses in the package documentation.
func ListenQUIC(ctx context.Context, local netip.AddrPort, selector ReplySelector,
tlsConf *tls.Config, quicConfig *quic.Config) (*QUICListener, error) {
func ListenQUIC(
ctx context.Context,
local netip.AddrPort,
tlsConf *tls.Config,
quicConfig *quic.Config,
listenConnOptions ...ListenConnOptions,
) (*QUICListener, error) {

conn, err := ListenUDP(ctx, local, selector)
conn, err := ListenUDP(ctx, local, listenConnOptions...)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/pan/raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ func (c *baseUDPConn) Close() error {
return c.raw.Close()
}

type scmpHandler struct{}
type DefaultSCMPHandler struct{}

func (h scmpHandler) Handle(pkt *snet.Packet) error {
func (h DefaultSCMPHandler) Handle(pkt *snet.Packet) error {
scmp := pkt.Payload.(snet.SCMPPayload)
switch scmp.Type() {
case slayers.SCMPTypeExternalInterfaceDown:
Expand Down
71 changes: 58 additions & 13 deletions pkg/pan/udp_dial.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,20 @@ type Conn interface {
// a path among this set for each Write operation.
// If the policy is nil, all paths are allowed.
// If the selector is nil, a DefaultSelector is used.
func DialUDP(ctx context.Context, local netip.AddrPort, remote UDPAddr,
policy Policy, selector Selector) (Conn, error) {

func DialUDP(
ctx context.Context,
local netip.AddrPort,
remote UDPAddr,
opts ...ConnOptions,
) (Conn, error) {
o := applyConnOpts(opts)
local, err := defaultLocalAddr(local)
if err != nil {
return nil, err
}

sn := snet.SCIONNetwork{
Topology: host().sciond,
SCMPHandler: scmpHandler{},
SCMPHandler: o.scmpHandler,
}
conn, err := sn.OpenRaw(ctx, net.UDPAddrFromAddrPort(local))
if err != nil {
Expand All @@ -71,10 +74,7 @@ func DialUDP(ctx context.Context, local netip.AddrPort, remote UDPAddr,
}
var subscriber *pathRefreshSubscriber
if remote.IA != localUDPAddr.IA {
if selector == nil {
selector = NewDefaultSelector()
}
subscriber, err = openPathRefreshSubscriber(ctx, localUDPAddr, remote, policy, selector)
subscriber, err = openPathRefreshSubscriber(ctx, localUDPAddr, remote, o.policy, o.selector)
if err != nil {
return nil, err
}
Expand All @@ -86,10 +86,58 @@ func DialUDP(ctx context.Context, local netip.AddrPort, remote UDPAddr,
local: localUDPAddr,
remote: remote,
subscriber: subscriber,
selector: selector,
selector: o.selector,
}, nil
}

type ConnOptions func(*connOptions)

// WithDialSCMPHandler sets the SCMP handler for the connection.
func WithDialSCMPHandler(handler snet.SCMPHandler) ConnOptions {
return func(o *connOptions) {
if handler == nil {
panic("nil SCMP handler not allowed")
}
o.scmpHandler = handler
}
}

// WithSelector sets the path selector for the connection.
func WithSelector(selector Selector) ConnOptions {
return func(o *connOptions) {
if selector == nil {
panic("nil selector not allowed")
}
o.selector = selector
}
}

// WithPolicy sets the path policy for the connection.
func WithPolicy(policy Policy) ConnOptions {
return func(o *connOptions) {
o.policy = policy
}
}

type connOptions struct {
scmpHandler snet.SCMPHandler
selector Selector
policy Policy
}

func applyConnOpts(opts []ConnOptions) connOptions {
o := connOptions{
scmpHandler: DefaultSCMPHandler{},
selector: NewDefaultSelector(),
}
for _, opt := range opts {
if opt != nil {
opt(&o)
}
}
return o
}

type dialedConn struct {
baseUDPConn

Expand All @@ -110,9 +158,6 @@ func (c *dialedConn) LocalAddr() net.Addr {
}

func (c *dialedConn) GetPath() *Path {
if c.selector == nil {
return nil
}
return c.selector.Path()
}

Expand Down
Loading

0 comments on commit 1e300df

Please sign in to comment.