From f081334e19e580ab84216f55b009ae1af3231a02 Mon Sep 17 00:00:00 2001 From: Marc Odermatt Date: Tue, 24 Sep 2024 11:46:53 +0200 Subject: [PATCH 1/5] bwtest with fabrid validation at destination --- bwtester/bwtestclient/bwtestclient.go | 20 ++++- bwtester/bwtestserver/bwtestserver.go | 32 +++++-- go.mod | 2 + go.sum | 4 +- pkg/pan/fabrid_server.go | 90 ++++++++++++++++++++ pkg/pan/path_metadata.go | 5 ++ pkg/pan/raw.go | 6 +- pkg/pan/sciond.go | 6 ++ pkg/pan/selector.go | 116 ++++++++++++++++++++++++++ pkg/pan/udp_dial.go | 7 +- pkg/pan/udp_listen.go | 103 ++++++++++++++++++++++- 11 files changed, 370 insertions(+), 21 deletions(-) create mode 100644 pkg/pan/fabrid_server.go diff --git a/bwtester/bwtestclient/bwtestclient.go b/bwtester/bwtestclient/bwtestclient.go index 6013e29b..76ec63b3 100644 --- a/bwtester/bwtestclient/bwtestclient.go +++ b/bwtester/bwtestclient/bwtestclient.go @@ -21,6 +21,8 @@ import ( "errors" "flag" "fmt" + "github.com/scionproto/scion/pkg/log" + "github.com/scionproto/scion/private/path/fabridquery" "math" "net" "net/netip" @@ -267,6 +269,7 @@ func main() { interactive bool sequence string preference string + fabridQuery string ) flag.Usage = printUsage @@ -279,6 +282,7 @@ func main() { flag.StringVar(&preference, "preference", "", "Preference sorting order for paths. "+ "Comma-separated list of available sorting options: "+ strings.Join(pan.AvailablePreferencePolicies, "|")) + flag.StringVar(&fabridQuery, "fabridquery", "", "Query for FABRID policies") flag.Parse() flagset := make(map[string]bool) @@ -320,7 +324,7 @@ func main() { fmt.Printf("server->client: %d seconds, %d bytes, %d packets\n", int(serverBwp.BwtestDuration/time.Second), serverBwp.PacketSize, serverBwp.NumPackets) - clientRes, serverRes, err := runBwtest(local.Get(), serverCCAddr, policy, clientBwp, serverBwp) + clientRes, serverRes, err := runBwtest(local.Get(), serverCCAddr, policy, clientBwp, serverBwp, fabridQuery) bwtest.Check(err) fmt.Println("\nS->C results") @@ -330,8 +334,7 @@ func main() { } // runBwtest runs the bandwidth test with the given parameters against the server at serverCCAddr. -func runBwtest(local netip.AddrPort, serverCCAddr pan.UDPAddr, policy pan.Policy, - clientBwp, serverBwp bwtest.Parameters) (clientRes, serverRes bwtest.Result, err error) { +func runBwtest(local netip.AddrPort, serverCCAddr pan.UDPAddr, policy pan.Policy, clientBwp, serverBwp bwtest.Parameters, fabridQuery string) (clientRes, serverRes bwtest.Result, err error) { // Control channel connection ccSelector := pan.NewDefaultSelector() @@ -345,7 +348,16 @@ 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) + var selector pan.Selector + if fabridQuery != "" { + query, err := fabridquery.ParseFabridQuery(fabridQuery) + if err != nil { + return bwtest.Result{}, bwtest.Result{}, err + } + selector = pan.NewFabridSelector(query, context.Background()) + } + + dcConn, err := pan.DialUDP(context.Background(), dcLocal, serverDCAddr, policy, selector) if err != nil { return } diff --git a/bwtester/bwtestserver/bwtestserver.go b/bwtester/bwtestserver/bwtestserver.go index 4656cc5f..68418302 100644 --- a/bwtester/bwtestserver/bwtestserver.go +++ b/bwtester/bwtestserver/bwtestserver.go @@ -18,9 +18,12 @@ import ( "bytes" "context" "errors" + "flag" "fmt" + "github.com/scionproto/scion/pkg/log" "net" "net/netip" + "os" "time" "gopkg.in/alecthomas/kingpin.v2" @@ -36,13 +39,21 @@ const ( func main() { var listen pan.IPPortValue kingpin.Flag("listen", "Address to listen on").Default(":40002").SetValue(&listen) + fabrid := kingpin.Flag("fabrid", "Enable FABRID").Bool() kingpin.Parse() + logCfg := log.Config{Console: log.ConsoleConfig{Level: "debug", StacktraceLevel: "none"}} + if err := log.Setup(logCfg); err != nil { + fmt.Fprintf(os.Stderr, "ERROR: %s", err) + flag.Usage() + os.Exit(1) + } + log.Info("Starting server", "fabrid", fabrid) - err := runServer(listen.Get()) + err := runServer(listen.Get(), *fabrid) bwtest.Check(err) } -func runServer(listen netip.AddrPort) error { +func runServer(listen netip.AddrPort, enableFabrid bool) error { receivePacketBuffer := make([]byte, 2500) var currentBwtest string @@ -103,7 +114,7 @@ func runServer(listen netip.AddrPort) error { } path := ccSelector.Path(clientCCAddr.(pan.UDPAddr)) finishTime, err := startBwtestBackground(serverCCAddr, clientCCAddr.(pan.UDPAddr), path, - clientBwp, serverBwp, currentResult) + clientBwp, serverBwp, currentResult, enableFabrid) if err != nil { // Ask the client to try again in 1 second writeResponseN(ccConn, clientCCAddr, 1) @@ -134,7 +145,7 @@ func runServer(listen netip.AddrPort) error { // startBwtestBackground starts a bandwidth test, in the background. // Returns the expected finish time of the test, or any error during the setup. func startBwtestBackground(serverCCAddr pan.UDPAddr, clientCCAddr pan.UDPAddr, - path *pan.Path, clientBwp, serverBwp bwtest.Parameters, res chan<- bwtest.Result) (time.Time, error) { + path *pan.Path, clientBwp, serverBwp bwtest.Parameters, res chan<- bwtest.Result, enableFabrid bool) (time.Time, error) { // Data Connection addresses: clientDCAddr := clientCCAddr @@ -143,7 +154,7 @@ func startBwtestBackground(serverCCAddr pan.UDPAddr, clientCCAddr pan.UDPAddr, // Open Data Connection dcSelector := initializedReplySelector(clientDCAddr, path) - dcConn, err := listenConnected(serverDCAddr, clientDCAddr, dcSelector) + dcConn, err := listenConnected(serverDCAddr, clientDCAddr, dcSelector, enableFabrid) if err != nil { return time.Time{}, err } @@ -286,8 +297,15 @@ 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) +func listenConnected(local netip.AddrPort, remote pan.UDPAddr, selector pan.ReplySelector, enableFabrid bool) (net.Conn, error) { + var err error + var conn pan.ListenConn + if enableFabrid { + conn, err = pan.ListenUDPWithFabrid(context.Background(), local, selector) + + } else { + conn, err = pan.ListenUDP(context.Background(), local, selector) + } return connectedPacketConn{ ListenConn: conn, remote: remote, diff --git a/go.mod b/go.mod index f4fa7b84..26551940 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,8 @@ require ( gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) +replace github.com/scionproto/scion => github.com/netsec-ethz/scion v0.6.1-0.20240920134723-b45a8ff2a753 + require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect diff --git a/go.sum b/go.sum index ac22531a..5b0f7ecc 100644 --- a/go.sum +++ b/go.sum @@ -106,6 +106,8 @@ github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdh github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/netsec-ethz/rains v0.5.1-0.20240619143424-8e9ef27f2403 h1:Ve8YXv3K9Oxlo9c4aQBYXMwe7Dx0Khv5qytdM2qTsco= github.com/netsec-ethz/rains v0.5.1-0.20240619143424-8e9ef27f2403/go.mod h1:YD8WuBUbAoxhvU/keqHboGDpFna9FSvklLLzTZSF7SE= +github.com/netsec-ethz/scion v0.6.1-0.20240920134723-b45a8ff2a753 h1:JdqS4sMU5vUjVMny4Qx/akzAqXdLrhWxTCSIgMmtUGE= +github.com/netsec-ethz/scion v0.6.1-0.20240920134723-b45a8ff2a753/go.mod h1:paxrF6VreownCN7E7Rdri6ifXMkiq3leFGoP6n/BFC4= github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= @@ -138,8 +140,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/scionproto/scion v0.11.1-0.20240610170620-50b971ca2d4b h1:n4jkPRHGsPC4xNCkVXhOy2qzqUGuMrO6A1zuY1W/2FY= -github.com/scionproto/scion v0.11.1-0.20240610170620-50b971ca2d4b/go.mod h1:paxrF6VreownCN7E7Rdri6ifXMkiq3leFGoP6n/BFC4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY= github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI= diff --git a/pkg/pan/fabrid_server.go b/pkg/pan/fabrid_server.go new file mode 100644 index 00000000..6bfb65a4 --- /dev/null +++ b/pkg/pan/fabrid_server.go @@ -0,0 +1,90 @@ +// Copyright 2021 ETH Zurich +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package pan + +import ( + "context" + "time" + + "github.com/scionproto/scion/pkg/addr" + "github.com/scionproto/scion/pkg/drkey" + "github.com/scionproto/scion/pkg/experimental/fabrid/crypto" + "github.com/scionproto/scion/pkg/log" + "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/slayers/extension" +) + +type ClientConnection struct { + Source UDPAddr + tmpBuffer []byte + pathKey drkey.Key +} + +type FabridServer struct { + Local UDPAddr + Connections map[string]*ClientConnection + ASKeyCache map[addr.IA]drkey.HostASKey +} + +func NewFabridServer(local *UDPAddr) *FabridServer { + server := &FabridServer{ + Local: *local, + Connections: make(map[string]*ClientConnection), + ASKeyCache: make(map[addr.IA]drkey.HostASKey), + } + return server +} + +func (s *FabridServer) FetchHostHostKey(dstHost UDPAddr, + validity time.Time) (drkey.Key, error) { + meta := drkey.HostHostMeta{ + Validity: validity, + SrcIA: addr.IA(s.Local.IA), + SrcHost: s.Local.IP.String(), + DstIA: addr.IA(dstHost.IA), + DstHost: dstHost.IP.String(), + ProtoId: drkey.FABRID, + } + hostHostKey, err := GetDRKeyHostHostKey(context.Background(), meta) + if err != nil { + return drkey.Key{}, serrors.WrapStr("getting host key", err) + } + return hostHostKey.Key, nil +} + +func (s *FabridServer) HandleFabridPacket(remote UDPAddr, fabridOption *extension.FabridOption, + identifierOption *extension.IdentifierOption) error { + client, found := s.Connections[remote.String()] + if !found { + pathKey, err := s.FetchHostHostKey(remote, identifierOption.Timestamp) + if err != nil { + return err + } + client = &ClientConnection{ + Source: remote, + tmpBuffer: make([]byte, 192), + pathKey: pathKey, + } + s.Connections[remote.String()] = client + log.Info("Opened new connection", "remote", remote.String()) + } + + _, err := crypto.VerifyPathValidator(fabridOption, + client.tmpBuffer, client.pathKey[:]) + if err != nil { + return err + } + return nil +} diff --git a/pkg/pan/path_metadata.go b/pkg/pan/path_metadata.go index 1b384542..dd9421e8 100644 --- a/pkg/pan/path_metadata.go +++ b/pkg/pan/path_metadata.go @@ -75,10 +75,14 @@ type PathMetadata struct { // Notes contains the notes added by ASes on the path, in the order of occurrence. // Entry i is the note of AS i on the path. Notes []string + + // FabridInfo contains information about the FABRID policies and support for each hop. + FabridInfo []FabridInfo } type GeoCoordinates = snet.GeoCoordinates type LinkType = snet.LinkType +type FabridInfo = snet.FabridInfo func (pm *PathMetadata) Copy() *PathMetadata { if pm == nil { @@ -93,6 +97,7 @@ func (pm *PathMetadata) Copy() *PathMetadata { LinkType: append(pm.LinkType[:0:0], pm.LinkType...), InternalHops: append(pm.InternalHops[:0:0], pm.InternalHops...), Notes: append(pm.Notes[:0:0], pm.Notes...), + FabridInfo: append(pm.FabridInfo[:0:0], pm.FabridInfo...), } } diff --git a/pkg/pan/raw.go b/pkg/pan/raw.go index 2a48ad99..f7bc70fc 100644 --- a/pkg/pan/raw.go +++ b/pkg/pan/raw.go @@ -110,7 +110,7 @@ func (c *baseUDPConn) writeMsg(src, dst UDPAddr, path *Path, b []byte) (int, err // readMsg is a helper for reading a single packet. // Internally invokes the configured SCMP handler. // Ignores non-UDP packets. -func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, error) { +func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, *slayers.HopByHopExtn, *slayers.EndToEndExtn, error) { c.readMutex.Lock() defer c.readMutex.Unlock() if c.readBuffer == nil { @@ -124,7 +124,7 @@ func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, error) { var lastHop net.UDPAddr err := c.raw.ReadFrom(&pkt, &lastHop) if err != nil { - return 0, UDPAddr{}, ForwardingPath{}, err + return 0, UDPAddr{}, ForwardingPath{}, nil, nil, err } udp, ok := pkt.Payload.(snet.UDPPayload) if !ok { @@ -144,7 +144,7 @@ func (c *baseUDPConn) readMsg(b []byte) (int, UDPAddr, ForwardingPath, error) { underlay: underlay, } n := copy(b, udp.Payload) - return n, remote, fw, nil + return n, remote, fw, pkt.HbhExtension, pkt.E2eExtension, nil } } diff --git a/pkg/pan/sciond.go b/pkg/pan/sciond.go index 3e3b9d1f..e4e45826 100644 --- a/pkg/pan/sciond.go +++ b/pkg/pan/sciond.go @@ -17,6 +17,7 @@ package pan import ( "context" "fmt" + "github.com/scionproto/scion/pkg/drkey" "net" "net/netip" "os" @@ -146,6 +147,7 @@ func (h *hostContext) queryPaths(ctx context.Context, dst IA) ([]*Path, error) { LinkType: snetMetadata.LinkType, InternalHops: snetMetadata.InternalHops, Notes: snetMetadata.Notes, + FabridInfo: snetMetadata.FabridInfo, } underlay := p.UnderlayNextHop().AddrPort() paths[i] = &Path{ @@ -163,6 +165,10 @@ func (h *hostContext) queryPaths(ctx context.Context, dst IA) ([]*Path, error) { return paths, nil } +func GetDRKeyHostHostKey(ctx context.Context, meta drkey.HostHostMeta) (drkey.HostHostKey, error) { + return host().sciond.DRKeyGetHostHostKey(ctx, meta) +} + func convertPathInterfaceSlice(spis []snet.PathInterface) []PathInterface { pis := make([]PathInterface, len(spis)) for i, spi := range spis { diff --git a/pkg/pan/selector.go b/pkg/pan/selector.go index 9a2fac34..821b2152 100644 --- a/pkg/pan/selector.go +++ b/pkg/pan/selector.go @@ -17,6 +17,10 @@ package pan import ( "context" "fmt" + "github.com/scionproto/scion/pkg/private/common" + "github.com/scionproto/scion/pkg/snet" + snetpath "github.com/scionproto/scion/pkg/snet/path" + "github.com/scionproto/scion/private/path/fabridquery" "net" "sync" "sync/atomic" @@ -322,3 +326,115 @@ func (s *PingingSelector) Close() error { s.pingerCancel() return s.pinger.Close() } + +// FabridSelector is a Selector for a single dialed socket. +type FabridSelector struct { + mutex sync.Mutex + paths []*Path + current int + activePaths int + fabridQuery fabridquery.Expressions + fabridConfig snetpath.FabridConfig + ctx context.Context +} + +func NewFabridSelector(query fabridquery.Expressions, ctx context.Context) *FabridSelector { + return &FabridSelector{ + fabridQuery: query, + ctx: ctx, + } +} + +func (s *FabridSelector) Path() *Path { + s.mutex.Lock() + defer s.mutex.Unlock() + + if len(s.paths) == 0 { + return nil + } + return s.paths[s.current] +} + +func convertInterfaces(interfaces []PathInterface) []snet.PathInterface { + snetInterfaces := make([]snet.PathInterface, len(interfaces)) + for i, pathInterface := range interfaces { + snetInterfaces[i] = snet.PathInterface{ + ID: common.IFIDType(pathInterface.IfID), + IA: addr.IA(pathInterface.IA), + } + } + return snetInterfaces +} + +func (s *FabridSelector) Initialize(local, remote UDPAddr, paths []*Path) { + s.mutex.Lock() + defer s.mutex.Unlock() + + fabridPaths := []*Path{} + for _, p := range paths { + scionPath, isSCIONPath := p.ForwardingPath.dataplanePath.(snetpath.SCION) + if !isSCIONPath { + continue + } + snetMetadata := snet.PathMetadata{ + Interfaces: convertInterfaces(p.Metadata.Interfaces), + FabridInfo: p.Metadata.FabridInfo} + hopIntfs := snetMetadata.Hops() + ml := fabridquery.MatchList{ + SelectedPolicies: make([]*fabridquery.Policy, len(hopIntfs)), + } + _, pols := s.fabridQuery.Evaluate(hopIntfs, &ml) + + if !pols.Accepted() { + continue + } + fabridPath, err := snetpath.NewFABRIDDataplanePath(scionPath, hopIntfs, + pols.Policies(), &s.fabridConfig) + if err != nil { + return + } + p.ForwardingPath.dataplanePath = fabridPath + + fabridPaths = append(fabridPaths, p) + } + + s.paths = fabridPaths + s.current = 0 +} + +func (s *FabridSelector) Refresh(paths []*Path) { + s.mutex.Lock() + defer s.mutex.Unlock() + + newcurrent := 0 + if len(s.paths) > 0 { + currentFingerprint := s.paths[s.current].Fingerprint + for i, p := range paths { + if p.Fingerprint == currentFingerprint { + newcurrent = i + break + } + } + } + s.paths = paths + s.current = newcurrent +} + +func (s *FabridSelector) PathDown(pf PathFingerprint, pi PathInterface) { + s.mutex.Lock() + defer s.mutex.Unlock() + + if current := s.paths[s.current]; isInterfaceOnPath(current, pi) || pf == current.Fingerprint { + fmt.Println("down:", s.current, len(s.paths)) + better := stats.FirstMoreAlive(current, s.paths) + if better >= 0 { + // Try next path. Note that this will keep cycling if we get down notifications + s.current = better + fmt.Println("failover:", s.current, len(s.paths)) + } + } +} + +func (s *FabridSelector) Close() error { + return nil +} diff --git a/pkg/pan/udp_dial.go b/pkg/pan/udp_dial.go index 2f90af8f..f87d3989 100644 --- a/pkg/pan/udp_dial.go +++ b/pkg/pan/udp_dial.go @@ -16,10 +16,9 @@ package pan import ( "context" + "github.com/scionproto/scion/pkg/snet" "net" "net/netip" - - "github.com/scionproto/scion/pkg/snet" ) // Conn represents a _dialed_ connection. @@ -137,7 +136,7 @@ func (c *dialedConn) WriteVia(path *Path, b []byte) (int, error) { func (c *dialedConn) Read(b []byte) (int, error) { for { - n, remote, _, err := c.baseUDPConn.readMsg(b) + n, remote, _, _, _, err := c.baseUDPConn.readMsg(b) if err != nil { return n, err } @@ -150,7 +149,7 @@ func (c *dialedConn) Read(b []byte) (int, error) { func (c *dialedConn) ReadVia(b []byte) (int, *Path, error) { for { - n, remote, fwPath, err := c.baseUDPConn.readMsg(b) + n, remote, fwPath, _, _, err := c.baseUDPConn.readMsg(b) if err != nil { return n, nil, err } diff --git a/pkg/pan/udp_listen.go b/pkg/pan/udp_listen.go index b7923d49..c0796268 100644 --- a/pkg/pan/udp_listen.go +++ b/pkg/pan/udp_listen.go @@ -18,6 +18,9 @@ import ( "context" "errors" "fmt" + "github.com/scionproto/scion/pkg/slayers" + "github.com/scionproto/scion/pkg/slayers/extension" + "github.com/scionproto/scion/pkg/slayers/path/scion" "net" "net/netip" "os" @@ -99,6 +102,51 @@ func ListenUDP(ctx context.Context, local netip.AddrPort, }, nil } +func ListenUDPWithFabrid(ctx context.Context, local netip.AddrPort, + selector ReplySelector) (ListenConn, error) { + + local, err := defaultLocalAddr(local) + if err != nil { + return nil, err + } + + if selector == nil { + selector = NewDefaultReplySelector() + } + stats.subscribe(selector) + sn := snet.SCIONNetwork{ + Topology: host().sciond, + SCMPHandler: scmpHandler{}, + } + conn, err := sn.OpenRaw(ctx, net.UDPAddrFromAddrPort(local)) + if err != nil { + return nil, err + } + ipport := conn.LocalAddr().(*net.UDPAddr).AddrPort() + localUDPAddr := UDPAddr{ + IA: host().ia, + IP: ipport.Addr(), + Port: ipport.Port(), + } + selector.Initialize(localUDPAddr) + + if len(os.Getenv("SCION_GO_INTEGRATION")) > 0 { + fmt.Printf("Listening addr=%s\n", localUDPAddr) + } + + server := NewFabridServer(&localUDPAddr) + return &fabridListenConn{ + listenConn: listenConn{ + baseUDPConn: baseUDPConn{ + raw: conn, + }, + local: localUDPAddr, + selector: selector, + }, + fabridServer: server, + }, nil +} + type listenConn struct { baseUDPConn @@ -106,6 +154,12 @@ type listenConn struct { selector ReplySelector } +type fabridListenConn struct { + listenConn + + fabridServer *FabridServer +} + func (c *listenConn) LocalAddr() net.Addr { return c.local } @@ -116,7 +170,7 @@ func (c *listenConn) ReadFrom(b []byte) (int, net.Addr, error) { } func (c *listenConn) ReadFromVia(b []byte) (int, UDPAddr, *Path, error) { - n, remote, fwPath, err := c.baseUDPConn.readMsg(b) + n, remote, fwPath, _, _, err := c.baseUDPConn.readMsg(b) if err != nil { return n, UDPAddr{}, nil, err } @@ -162,6 +216,53 @@ func NewDefaultReplySelector() *DefaultReplySelector { } } +func (c *fabridListenConn) ReadFrom(b []byte) (int, net.Addr, error) { + n, remote, _, err := c.ReadFromVia(b) + return n, remote, err +} + +func (c *fabridListenConn) ReadFromVia(b []byte) (int, UDPAddr, *Path, error) { + n, panRemote, fwPath, hbhExt, _, err := c.baseUDPConn.readMsg(b) + if err != nil { + return n, UDPAddr{}, nil, err + } + + path, err := reversePathFromForwardingPath(panRemote.IA, c.local.IA, fwPath) + c.selector.Record(panRemote, path) + + // Check extensions for relevant options + var identifierOption *extension.IdentifierOption + var fabridOption *extension.FabridOption + if hbhExt != nil { + for _, opt := range hbhExt.Options { + switch opt.OptType { + case slayers.OptTypeIdentifier: + decoded := scion.Decoded{} + decoded.DecodeFromBytes(fwPath.dataplanePath.(snet.RawPath).Raw) + baseTimestamp := decoded.InfoFields[0].Timestamp + identifierOption, err = extension.ParseIdentifierOption(opt, baseTimestamp) + if err != nil { + return 0, UDPAddr{}, nil, err + } + case slayers.OptTypeFabrid: + fabridOption, err = extension.ParseFabridOptionFullExtension(opt, (opt.OptDataLen-4)/4) + if err != nil { + return 0, UDPAddr{}, nil, err + } + } + } + } + if fabridOption != nil && identifierOption != nil { + + err = c.fabridServer.HandleFabridPacket(panRemote, fabridOption, identifierOption) + if err != nil { + return 0, UDPAddr{}, nil, err + } + } + + return n, panRemote, path, err +} + func (s *DefaultReplySelector) Initialize(local UDPAddr) { } From ce59a010421dab2af021e85c9b0a580eb8540b3f Mon Sep 17 00:00:00 2001 From: Marc Odermatt Date: Tue, 24 Sep 2024 14:46:08 +0200 Subject: [PATCH 2/5] lint --- bwtester/bwtestclient/bwtestclient.go | 5 +++-- bwtester/bwtestserver/bwtestserver.go | 2 +- go.mod | 1 - pkg/pan/sciond.go | 2 +- pkg/pan/selector.go | 9 ++++----- pkg/pan/udp_dial.go | 3 ++- pkg/pan/udp_listen.go | 6 +++--- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bwtester/bwtestclient/bwtestclient.go b/bwtester/bwtestclient/bwtestclient.go index 76ec63b3..99783db4 100644 --- a/bwtester/bwtestclient/bwtestclient.go +++ b/bwtester/bwtestclient/bwtestclient.go @@ -21,8 +21,6 @@ import ( "errors" "flag" "fmt" - "github.com/scionproto/scion/pkg/log" - "github.com/scionproto/scion/private/path/fabridquery" "math" "net" "net/netip" @@ -32,6 +30,9 @@ import ( "time" "unicode" + "github.com/scionproto/scion/pkg/log" + "github.com/scionproto/scion/private/path/fabridquery" + "github.com/netsec-ethz/scion-apps/bwtester/bwtest" "github.com/netsec-ethz/scion-apps/pkg/pan" ) diff --git a/bwtester/bwtestserver/bwtestserver.go b/bwtester/bwtestserver/bwtestserver.go index 68418302..c991a735 100644 --- a/bwtester/bwtestserver/bwtestserver.go +++ b/bwtester/bwtestserver/bwtestserver.go @@ -20,12 +20,12 @@ import ( "errors" "flag" "fmt" - "github.com/scionproto/scion/pkg/log" "net" "net/netip" "os" "time" + "github.com/scionproto/scion/pkg/log" "gopkg.in/alecthomas/kingpin.v2" "github.com/netsec-ethz/scion-apps/bwtester/bwtest" diff --git a/go.mod b/go.mod index 26551940..53053235 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ require ( gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) -replace github.com/scionproto/scion => github.com/netsec-ethz/scion v0.6.1-0.20240920134723-b45a8ff2a753 require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect diff --git a/pkg/pan/sciond.go b/pkg/pan/sciond.go index e4e45826..0c70a950 100644 --- a/pkg/pan/sciond.go +++ b/pkg/pan/sciond.go @@ -17,7 +17,6 @@ package pan import ( "context" "fmt" - "github.com/scionproto/scion/pkg/drkey" "net" "net/netip" "os" @@ -26,6 +25,7 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/daemon" + "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/snet" "github.com/scionproto/scion/pkg/snet/addrutil" ) diff --git a/pkg/pan/selector.go b/pkg/pan/selector.go index 821b2152..be0d8801 100644 --- a/pkg/pan/selector.go +++ b/pkg/pan/selector.go @@ -17,16 +17,16 @@ package pan import ( "context" "fmt" - "github.com/scionproto/scion/pkg/private/common" - "github.com/scionproto/scion/pkg/snet" - snetpath "github.com/scionproto/scion/pkg/snet/path" - "github.com/scionproto/scion/private/path/fabridquery" "net" "sync" "sync/atomic" "time" "github.com/scionproto/scion/pkg/addr" + "github.com/scionproto/scion/pkg/private/common" + "github.com/scionproto/scion/pkg/snet" + snetpath "github.com/scionproto/scion/pkg/snet/path" + "github.com/scionproto/scion/private/path/fabridquery" "github.com/netsec-ethz/scion-apps/pkg/pan/internal/ping" ) @@ -332,7 +332,6 @@ type FabridSelector struct { mutex sync.Mutex paths []*Path current int - activePaths int fabridQuery fabridquery.Expressions fabridConfig snetpath.FabridConfig ctx context.Context diff --git a/pkg/pan/udp_dial.go b/pkg/pan/udp_dial.go index f87d3989..b482c748 100644 --- a/pkg/pan/udp_dial.go +++ b/pkg/pan/udp_dial.go @@ -16,9 +16,10 @@ package pan import ( "context" - "github.com/scionproto/scion/pkg/snet" "net" "net/netip" + + "github.com/scionproto/scion/pkg/snet" ) // Conn represents a _dialed_ connection. diff --git a/pkg/pan/udp_listen.go b/pkg/pan/udp_listen.go index c0796268..5ba045de 100644 --- a/pkg/pan/udp_listen.go +++ b/pkg/pan/udp_listen.go @@ -18,15 +18,15 @@ import ( "context" "errors" "fmt" - "github.com/scionproto/scion/pkg/slayers" - "github.com/scionproto/scion/pkg/slayers/extension" - "github.com/scionproto/scion/pkg/slayers/path/scion" "net" "net/netip" "os" "sync" "time" + "github.com/scionproto/scion/pkg/slayers" + "github.com/scionproto/scion/pkg/slayers/extension" + "github.com/scionproto/scion/pkg/slayers/path/scion" "github.com/scionproto/scion/pkg/snet" ) From 48847db838f448be6c4176595711b66d1441c603 Mon Sep 17 00:00:00 2001 From: Marc Odermatt Date: Tue, 24 Sep 2024 15:57:31 +0200 Subject: [PATCH 3/5] simplify server, improve key fetching --- bwtester/bwtestserver/bwtestserver.go | 2 +- pkg/pan/fabrid_server.go | 77 ++++++++++++--------------- pkg/pan/sciond.go | 8 ++- pkg/pan/selector.go | 8 +++ pkg/pan/udp_listen.go | 6 +-- 5 files changed, 52 insertions(+), 49 deletions(-) diff --git a/bwtester/bwtestserver/bwtestserver.go b/bwtester/bwtestserver/bwtestserver.go index c991a735..941b146e 100644 --- a/bwtester/bwtestserver/bwtestserver.go +++ b/bwtester/bwtestserver/bwtestserver.go @@ -301,7 +301,7 @@ func listenConnected(local netip.AddrPort, remote pan.UDPAddr, selector pan.Repl var err error var conn pan.ListenConn if enableFabrid { - conn, err = pan.ListenUDPWithFabrid(context.Background(), local, selector) + conn, err = pan.ListenUDPWithFabrid(context.Background(), local, remote, selector) } else { conn, err = pan.ListenUDP(context.Background(), local, selector) diff --git a/pkg/pan/fabrid_server.go b/pkg/pan/fabrid_server.go index 6bfb65a4..4c737ffe 100644 --- a/pkg/pan/fabrid_server.go +++ b/pkg/pan/fabrid_server.go @@ -26,64 +26,55 @@ import ( "github.com/scionproto/scion/pkg/slayers/extension" ) -type ClientConnection struct { +type FabridServer struct { + Local UDPAddr Source UDPAddr tmpBuffer []byte - pathKey drkey.Key + pathKey *drkey.HostHostKey } -type FabridServer struct { - Local UDPAddr - Connections map[string]*ClientConnection - ASKeyCache map[addr.IA]drkey.HostASKey -} - -func NewFabridServer(local *UDPAddr) *FabridServer { +func NewFabridServer(local UDPAddr, remote UDPAddr) *FabridServer { server := &FabridServer{ - Local: *local, - Connections: make(map[string]*ClientConnection), - ASKeyCache: make(map[addr.IA]drkey.HostASKey), + Local: local, + Source: remote, + tmpBuffer: make([]byte, 192), } + server.refreshPathKey(time.Now()) return server } -func (s *FabridServer) FetchHostHostKey(dstHost UDPAddr, - validity time.Time) (drkey.Key, error) { - meta := drkey.HostHostMeta{ - Validity: validity, - SrcIA: addr.IA(s.Local.IA), - SrcHost: s.Local.IP.String(), - DstIA: addr.IA(dstHost.IA), - DstHost: dstHost.IP.String(), - ProtoId: drkey.FABRID, - } - hostHostKey, err := GetDRKeyHostHostKey(context.Background(), meta) - if err != nil { - return drkey.Key{}, serrors.WrapStr("getting host key", err) +func (s *FabridServer) refreshPathKey(validity time.Time) error { + if s.pathKey == nil || !s.pathKey.Epoch.Contains(validity) { + meta := drkey.HostHostMeta{ + Validity: validity, + SrcIA: addr.IA(s.Local.IA), + SrcHost: s.Local.IP.String(), + DstIA: addr.IA(s.Source.IA), + DstHost: s.Source.IP.String(), + ProtoId: drkey.FABRID, + } + log.Debug("Fetching path key", "meta", meta) + hostHostKey, err := host().drkeyGetHostHostKey(context.Background(), meta) + if err != nil { + return serrors.WrapStr("getting host key", err) + } + s.pathKey = &hostHostKey + } - return hostHostKey.Key, nil + return nil } -func (s *FabridServer) HandleFabridPacket(remote UDPAddr, fabridOption *extension.FabridOption, +func (s *FabridServer) HandleFabridPacket(fabridOption *extension.FabridOption, identifierOption *extension.IdentifierOption) error { - client, found := s.Connections[remote.String()] - if !found { - pathKey, err := s.FetchHostHostKey(remote, identifierOption.Timestamp) - if err != nil { - return err - } - client = &ClientConnection{ - Source: remote, - tmpBuffer: make([]byte, 192), - pathKey: pathKey, - } - s.Connections[remote.String()] = client - log.Info("Opened new connection", "remote", remote.String()) + err := s.refreshPathKey(identifierOption.Timestamp) + if err != nil { + log.Error("Failed to fetch path key", "err", err) + return err } - - _, err := crypto.VerifyPathValidator(fabridOption, - client.tmpBuffer, client.pathKey[:]) + _, err = crypto.VerifyPathValidator(fabridOption, + s.tmpBuffer, s.pathKey.Key[:]) if err != nil { + log.Error("Failed to verify", "err", err) return err } return nil diff --git a/pkg/pan/sciond.go b/pkg/pan/sciond.go index 0c70a950..6684405b 100644 --- a/pkg/pan/sciond.go +++ b/pkg/pan/sciond.go @@ -165,8 +165,12 @@ func (h *hostContext) queryPaths(ctx context.Context, dst IA) ([]*Path, error) { return paths, nil } -func GetDRKeyHostHostKey(ctx context.Context, meta drkey.HostHostMeta) (drkey.HostHostKey, error) { - return host().sciond.DRKeyGetHostHostKey(ctx, meta) +func (h *hostContext) drkeyGetHostHostKey(ctx context.Context, meta drkey.HostHostMeta) (drkey.HostHostKey, error) { + return h.sciond.DRKeyGetHostHostKey(ctx, meta) +} + +func (h *hostContext) fabridKeys() func(ctx context.Context, meta drkey.FabridKeysMeta) (drkey.FabridKeysResponse, error) { + return h.sciond.FabridKeys } func convertPathInterfaceSlice(spis []snet.PathInterface) []PathInterface { diff --git a/pkg/pan/selector.go b/pkg/pan/selector.go index be0d8801..c03a7514 100644 --- a/pkg/pan/selector.go +++ b/pkg/pan/selector.go @@ -369,6 +369,13 @@ func (s *FabridSelector) Initialize(local, remote UDPAddr, paths []*Path) { s.mutex.Lock() defer s.mutex.Unlock() + s.fabridConfig = snetpath.FabridConfig{ + LocalIA: addr.IA(local.IA), + LocalAddr: local.IP.String(), + DestinationIA: addr.IA(remote.IA), + DestinationAddr: remote.IP.String(), + } + fabridPaths := []*Path{} for _, p := range paths { scionPath, isSCIONPath := p.ForwardingPath.dataplanePath.(snetpath.SCION) @@ -393,6 +400,7 @@ func (s *FabridSelector) Initialize(local, remote UDPAddr, paths []*Path) { return } p.ForwardingPath.dataplanePath = fabridPath + fabridPath.RegisterDRKeyFetcher(host().fabridKeys()) fabridPaths = append(fabridPaths, p) } diff --git a/pkg/pan/udp_listen.go b/pkg/pan/udp_listen.go index 5ba045de..37aae380 100644 --- a/pkg/pan/udp_listen.go +++ b/pkg/pan/udp_listen.go @@ -102,7 +102,7 @@ func ListenUDP(ctx context.Context, local netip.AddrPort, }, nil } -func ListenUDPWithFabrid(ctx context.Context, local netip.AddrPort, +func ListenUDPWithFabrid(ctx context.Context, local netip.AddrPort, remote UDPAddr, selector ReplySelector) (ListenConn, error) { local, err := defaultLocalAddr(local) @@ -134,7 +134,7 @@ func ListenUDPWithFabrid(ctx context.Context, local netip.AddrPort, fmt.Printf("Listening addr=%s\n", localUDPAddr) } - server := NewFabridServer(&localUDPAddr) + server := NewFabridServer(localUDPAddr, remote) return &fabridListenConn{ listenConn: listenConn{ baseUDPConn: baseUDPConn{ @@ -254,7 +254,7 @@ func (c *fabridListenConn) ReadFromVia(b []byte) (int, UDPAddr, *Path, error) { } if fabridOption != nil && identifierOption != nil { - err = c.fabridServer.HandleFabridPacket(panRemote, fabridOption, identifierOption) + err = c.fabridServer.HandleFabridPacket(fabridOption, identifierOption) if err != nil { return 0, UDPAddr{}, nil, err } From 9e644295ecbf166a55a3be0c341ce6211020096d Mon Sep 17 00:00:00 2001 From: Marc Odermatt Date: Mon, 30 Sep 2024 10:56:54 +0200 Subject: [PATCH 4/5] Improved error messages, linting --- bwtester/bwtestclient/bwtestclient.go | 1 - bwtester/bwtestserver/bwtestserver.go | 11 +---------- go.mod | 1 - pkg/pan/fabrid_server.go | 19 ++++++++++++------- pkg/pan/udp_listen.go | 7 +++++-- 5 files changed, 18 insertions(+), 21 deletions(-) diff --git a/bwtester/bwtestclient/bwtestclient.go b/bwtester/bwtestclient/bwtestclient.go index 99783db4..ef84af07 100644 --- a/bwtester/bwtestclient/bwtestclient.go +++ b/bwtester/bwtestclient/bwtestclient.go @@ -30,7 +30,6 @@ import ( "time" "unicode" - "github.com/scionproto/scion/pkg/log" "github.com/scionproto/scion/private/path/fabridquery" "github.com/netsec-ethz/scion-apps/bwtester/bwtest" diff --git a/bwtester/bwtestserver/bwtestserver.go b/bwtester/bwtestserver/bwtestserver.go index 941b146e..8a66d77c 100644 --- a/bwtester/bwtestserver/bwtestserver.go +++ b/bwtester/bwtestserver/bwtestserver.go @@ -18,14 +18,11 @@ import ( "bytes" "context" "errors" - "flag" "fmt" "net" "net/netip" - "os" "time" - "github.com/scionproto/scion/pkg/log" "gopkg.in/alecthomas/kingpin.v2" "github.com/netsec-ethz/scion-apps/bwtester/bwtest" @@ -41,13 +38,6 @@ func main() { kingpin.Flag("listen", "Address to listen on").Default(":40002").SetValue(&listen) fabrid := kingpin.Flag("fabrid", "Enable FABRID").Bool() kingpin.Parse() - logCfg := log.Config{Console: log.ConsoleConfig{Level: "debug", StacktraceLevel: "none"}} - if err := log.Setup(logCfg); err != nil { - fmt.Fprintf(os.Stderr, "ERROR: %s", err) - flag.Usage() - os.Exit(1) - } - log.Info("Starting server", "fabrid", fabrid) err := runServer(listen.Get(), *fabrid) bwtest.Check(err) @@ -68,6 +58,7 @@ func runServer(listen netip.AddrPort, enableFabrid bool) error { return err } serverCCAddr := ccConn.LocalAddr().(pan.UDPAddr) + fmt.Println("Server listening on ", serverCCAddr, " fabrid:", enableFabrid) for { // Handle client requests n, clientCCAddr, err := ccConn.ReadFrom(receivePacketBuffer) diff --git a/go.mod b/go.mod index 53053235..f4fa7b84 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ require ( gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) - require ( github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect diff --git a/pkg/pan/fabrid_server.go b/pkg/pan/fabrid_server.go index 4c737ffe..c7c6dfa6 100644 --- a/pkg/pan/fabrid_server.go +++ b/pkg/pan/fabrid_server.go @@ -16,12 +16,12 @@ package pan import ( "context" + "fmt" "time" "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/experimental/fabrid/crypto" - "github.com/scionproto/scion/pkg/log" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/slayers/extension" ) @@ -31,15 +31,21 @@ type FabridServer struct { Source UDPAddr tmpBuffer []byte pathKey *drkey.HostHostKey + ctx context.Context } -func NewFabridServer(local UDPAddr, remote UDPAddr) *FabridServer { +func NewFabridServer(ctx context.Context, local UDPAddr, remote UDPAddr) *FabridServer { server := &FabridServer{ Local: local, Source: remote, tmpBuffer: make([]byte, 192), + ctx: ctx, + } + err := server.refreshPathKey(time.Now()) + if err != nil { + fmt.Println("Failed to fetch path key. Does your local IP differ from your SD?\nError:", err) + return nil } - server.refreshPathKey(time.Now()) return server } @@ -53,8 +59,7 @@ func (s *FabridServer) refreshPathKey(validity time.Time) error { DstHost: s.Source.IP.String(), ProtoId: drkey.FABRID, } - log.Debug("Fetching path key", "meta", meta) - hostHostKey, err := host().drkeyGetHostHostKey(context.Background(), meta) + hostHostKey, err := host().drkeyGetHostHostKey(s.ctx, meta) if err != nil { return serrors.WrapStr("getting host key", err) } @@ -68,13 +73,13 @@ func (s *FabridServer) HandleFabridPacket(fabridOption *extension.FabridOption, identifierOption *extension.IdentifierOption) error { err := s.refreshPathKey(identifierOption.Timestamp) if err != nil { - log.Error("Failed to fetch path key", "err", err) + fmt.Println("Failed to fetch path key. Does your local IP differ from your SD?\nError:", err) return err } _, err = crypto.VerifyPathValidator(fabridOption, s.tmpBuffer, s.pathKey.Key[:]) if err != nil { - log.Error("Failed to verify", "err", err) + fmt.Println("Failed to verify FABRID packet. Error:", err) return err } return nil diff --git a/pkg/pan/udp_listen.go b/pkg/pan/udp_listen.go index 37aae380..76939a17 100644 --- a/pkg/pan/udp_listen.go +++ b/pkg/pan/udp_listen.go @@ -134,7 +134,7 @@ func ListenUDPWithFabrid(ctx context.Context, local netip.AddrPort, remote UDPAd fmt.Printf("Listening addr=%s\n", localUDPAddr) } - server := NewFabridServer(localUDPAddr, remote) + server := NewFabridServer(ctx, localUDPAddr, remote) return &fabridListenConn{ listenConn: listenConn{ baseUDPConn: baseUDPConn{ @@ -238,7 +238,10 @@ func (c *fabridListenConn) ReadFromVia(b []byte) (int, UDPAddr, *Path, error) { switch opt.OptType { case slayers.OptTypeIdentifier: decoded := scion.Decoded{} - decoded.DecodeFromBytes(fwPath.dataplanePath.(snet.RawPath).Raw) + err = decoded.DecodeFromBytes(fwPath.dataplanePath.(snet.RawPath).Raw) + if err != nil { + return 0, UDPAddr{}, nil, err + } baseTimestamp := decoded.InfoFields[0].Timestamp identifierOption, err = extension.ParseIdentifierOption(opt, baseTimestamp) if err != nil { From ad4ad70865abb52140759853df9b43b5733fe777 Mon Sep 17 00:00:00 2001 From: Marc Odermatt Date: Mon, 30 Sep 2024 11:18:33 +0200 Subject: [PATCH 5/5] Revert go.sum changes --- go.sum | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 5b0f7ecc..ac22531a 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,6 @@ github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdh github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/netsec-ethz/rains v0.5.1-0.20240619143424-8e9ef27f2403 h1:Ve8YXv3K9Oxlo9c4aQBYXMwe7Dx0Khv5qytdM2qTsco= github.com/netsec-ethz/rains v0.5.1-0.20240619143424-8e9ef27f2403/go.mod h1:YD8WuBUbAoxhvU/keqHboGDpFna9FSvklLLzTZSF7SE= -github.com/netsec-ethz/scion v0.6.1-0.20240920134723-b45a8ff2a753 h1:JdqS4sMU5vUjVMny4Qx/akzAqXdLrhWxTCSIgMmtUGE= -github.com/netsec-ethz/scion v0.6.1-0.20240920134723-b45a8ff2a753/go.mod h1:paxrF6VreownCN7E7Rdri6ifXMkiq3leFGoP6n/BFC4= github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= github.com/onsi/gomega v1.33.0 h1:snPCflnZrpMsy94p4lXVEkHo12lmPnc3vY5XBbreexE= @@ -140,6 +138,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/scionproto/scion v0.11.1-0.20240610170620-50b971ca2d4b h1:n4jkPRHGsPC4xNCkVXhOy2qzqUGuMrO6A1zuY1W/2FY= +github.com/scionproto/scion v0.11.1-0.20240610170620-50b971ca2d4b/go.mod h1:paxrF6VreownCN7E7Rdri6ifXMkiq3leFGoP6n/BFC4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smarty/assertions v1.16.0 h1:EvHNkdRA4QHMrn75NZSoUQ/mAUXAYWfatfB01yTCzfY= github.com/smarty/assertions v1.16.0/go.mod h1:duaaFdCS0K9dnoM50iyek/eYINOZ64gbh1Xlf6LG7AI=