diff --git a/control/beaconing/writer.go b/control/beaconing/writer.go index 1c5b18cb06..70dcde0eae 100644 --- a/control/beaconing/writer.go +++ b/control/beaconing/writer.go @@ -37,7 +37,7 @@ import ( // Pather computes the remote address with a path based on the provided segment. type Pather interface { - GetPath(svc addr.HostSVC, ps *seg.PathSegment) (*snet.SVCAddr, error) + GetPath(svc addr.SVC, ps *seg.PathSegment) (*snet.SVCAddr, error) } // SegmentProvider provides segments to register for the specified type. diff --git a/control/config/BUILD.bazel b/control/config/BUILD.bazel index 97e2c636e7..82c2276559 100644 --- a/control/config/BUILD.bazel +++ b/control/config/BUILD.bazel @@ -11,7 +11,6 @@ go_library( importpath = "github.com/scionproto/scion/control/config", visibility = ["//visibility:public"], deps = [ - "//pkg/addr:go_default_library", "//pkg/drkey:go_default_library", "//pkg/log:go_default_library", "//pkg/private/serrors:go_default_library", diff --git a/control/config/drkey.go b/control/config/drkey.go index 38ad9f7768..27df174c26 100644 --- a/control/config/drkey.go +++ b/control/config/drkey.go @@ -20,7 +20,6 @@ import ( "strings" "time" - "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/private/config" @@ -118,7 +117,7 @@ func (cfg *SecretValueHostList) Validate() error { return serrors.New("GENERIC protocol is not allowed") } for _, ip := range list { - if h := addr.HostFromIPStr(ip); h == nil { + if _, err := netip.ParseAddr(ip); err != nil { return serrors.New("Syntax error: not a valid address", "ip", ip) } } diff --git a/control/drkey/grpc/drkey_service.go b/control/drkey/grpc/drkey_service.go index b0a7278c25..23434a3913 100644 --- a/control/drkey/grpc/drkey_service.go +++ b/control/drkey/grpc/drkey_service.go @@ -299,7 +299,7 @@ func validateASHostReq(meta drkey.ASHostMeta, localIA addr.IA, peerAddr net.Addr return serrors.New("invalid request, req.dstIA != localIA", "request_dst_isd_as", meta.DstIA, "local_isd_as", localIA) } - dstHost := addr.HostFromIPStr(meta.DstHost) + dstHost := net.ParseIP(meta.DstHost) if !hostAddr.Equal(dstHost) { return serrors.New("invalid request, dst_host != remote host", "dst_host", dstHost, "remote_host", hostAddr) @@ -320,7 +320,7 @@ func validateHostASReq(meta drkey.HostASMeta, localIA addr.IA, peerAddr net.Addr return serrors.New("invalid request, req.SrcIA != localIA", "request_src_isd_as", meta.SrcIA, "local_isd_as", localIA) } - srcHost := addr.HostFromIPStr(meta.SrcHost) + srcHost := net.ParseIP(meta.SrcHost) if !hostAddr.Equal(srcHost) { return serrors.New("invalid request, src_host != remote host", "src_host", srcHost, "remote_host", hostAddr) @@ -335,8 +335,8 @@ func validateHostHostReq(meta drkey.HostHostMeta, localIA addr.IA, peerAddr net. if err != nil { return err } - srcHost := addr.HostFromIPStr(meta.SrcHost) - dstHost := addr.HostFromIPStr(meta.DstHost) + srcHost := net.ParseIP(meta.SrcHost) + dstHost := net.ParseIP(meta.DstHost) if !((meta.SrcIA.Equal(localIA) && hostAddr.Equal(srcHost)) || (meta.DstIA.Equal(localIA) && hostAddr.Equal(dstHost))) { @@ -353,13 +353,13 @@ func validateHostHostReq(meta drkey.HostHostMeta, localIA addr.IA, peerAddr net. return nil } -func hostAddrFromPeer(peerAddr net.Addr) (addr.HostAddr, error) { +func hostAddrFromPeer(peerAddr net.Addr) (net.IP, error) { tcpAddr, ok := peerAddr.(*net.TCPAddr) if !ok { return nil, serrors.New("invalid peer address type, expected *net.TCPAddr", "peer", peerAddr, "type", common.TypeOf(peerAddr)) } - return addr.HostFromIP(tcpAddr.IP), nil + return tcpAddr.IP, nil } func getMeta(protoId drkeypb.Protocol, ts *timestamppb.Timestamp, srcIA, diff --git a/control/onehop/addr.go b/control/onehop/addr.go index d02fb54c78..6202443da5 100644 --- a/control/onehop/addr.go +++ b/control/onehop/addr.go @@ -35,7 +35,7 @@ type Addr struct { // Egress is the interface over which the remote AS should be reached. Egress uint16 // SVC is the service anycast address of the designated service in the remote AS. - SVC addr.HostSVC + SVC addr.SVC // NextHop is the router that owns the egress interface. NextHop *net.UDPAddr } diff --git a/control/segreq/helpers.go b/control/segreq/helpers.go index f7a517b748..391f243c77 100644 --- a/control/segreq/helpers.go +++ b/control/segreq/helpers.go @@ -30,7 +30,7 @@ import ( // Pather computes the remote address with a path based on the provided segment. type Pather interface { - GetPath(svc addr.HostSVC, ps *seg.PathSegment) (*snet.SVCAddr, error) + GetPath(svc addr.SVC, ps *seg.PathSegment) (*snet.SVCAddr, error) } // CoreChecker checks whether a given ia is core. diff --git a/daemon/cmd/daemon/main.go b/daemon/cmd/daemon/main.go index d663f9af88..a8ec8ca521 100644 --- a/daemon/cmd/daemon/main.go +++ b/daemon/cmd/daemon/main.go @@ -121,7 +121,7 @@ func realMain(ctx context.Context) error { defer rcCleaner.Stop() dialer := &libgrpc.TCPDialer{ - SvcResolver: func(dst addr.HostSVC) []resolver.Address { + SvcResolver: func(dst addr.SVC) []resolver.Address { if base := dst.Base(); base != addr.SvcCS { panic("Unsupported address type, implementation error?") } diff --git a/daemon/drkey/grpc/BUILD.bazel b/daemon/drkey/grpc/BUILD.bazel index 26801aaa00..c1fdb982c8 100644 --- a/daemon/drkey/grpc/BUILD.bazel +++ b/daemon/drkey/grpc/BUILD.bazel @@ -16,6 +16,7 @@ go_library( "//pkg/proto/control_plane:go_default_library", "//pkg/proto/drkey:go_default_library", "//pkg/scrypto/cppki:go_default_library", + "//pkg/snet:go_default_library", "@org_golang_google_protobuf//types/known/timestamppb:go_default_library", ], ) diff --git a/daemon/drkey/grpc/fetcher.go b/daemon/drkey/grpc/fetcher.go index 4916871797..a6e51ffe75 100644 --- a/daemon/drkey/grpc/fetcher.go +++ b/daemon/drkey/grpc/fetcher.go @@ -22,6 +22,7 @@ import ( sc_grpc "github.com/scionproto/scion/pkg/grpc" "github.com/scionproto/scion/pkg/private/serrors" cppb "github.com/scionproto/scion/pkg/proto/control_plane" + "github.com/scionproto/scion/pkg/snet" ) // Fetcher obtains end-host key from the local CS. @@ -34,7 +35,7 @@ func (f *Fetcher) ASHostKey( meta drkey.ASHostMeta, ) (drkey.ASHostKey, error) { - conn, err := f.Dialer.Dial(ctx, addr.SvcCS) + conn, err := f.Dialer.Dial(ctx, &snet.SVCAddr{SVC: addr.SvcCS}) if err != nil { return drkey.ASHostKey{}, serrors.WrapStr("dialing", err) } @@ -59,7 +60,7 @@ func (f *Fetcher) HostASKey( meta drkey.HostASMeta, ) (drkey.HostASKey, error) { - conn, err := f.Dialer.Dial(ctx, addr.SvcCS) + conn, err := f.Dialer.Dial(ctx, &snet.SVCAddr{SVC: addr.SvcCS}) if err != nil { return drkey.HostASKey{}, serrors.WrapStr("dialing", err) } @@ -84,7 +85,7 @@ func (f *Fetcher) HostHostKey( meta drkey.HostHostMeta, ) (drkey.HostHostKey, error) { - conn, err := f.Dialer.Dial(ctx, addr.SvcCS) + conn, err := f.Dialer.Dial(ctx, &snet.SVCAddr{SVC: addr.SvcCS}) if err != nil { return drkey.HostHostKey{}, serrors.WrapStr("dialing", err) } diff --git a/daemon/fetcher/fetcher.go b/daemon/fetcher/fetcher.go index 743fd93bb7..63206b0995 100644 --- a/daemon/fetcher/fetcher.go +++ b/daemon/fetcher/fetcher.go @@ -126,7 +126,7 @@ type dstProvider struct { } func (r *dstProvider) Dst(_ context.Context, _ segfetcher.Request) (net.Addr, error) { - return addr.SvcCS, nil + return &snet.SVCAddr{SVC: addr.SvcCS}, nil } type neverLocal struct{} diff --git a/dispatcher/cmd/dispatcher/main_test.go b/dispatcher/cmd/dispatcher/main_test.go index d3c4023d66..86e3dc710d 100644 --- a/dispatcher/cmd/dispatcher/main_test.go +++ b/dispatcher/cmd/dispatcher/main_test.go @@ -19,6 +19,7 @@ import ( "context" "fmt" "net" + "net/netip" "os" "path/filepath" "testing" @@ -65,11 +66,10 @@ func getSocketName(dir string) (string, error) { type ClientAddress struct { IA addr.IA - PublicAddress addr.HostAddr + PublicAddress netip.Addr PublicPort uint16 - ServiceAddress addr.HostSVC + ServiceAddress addr.SVC UnderlayAddress *net.UDPAddr - UnderlayPort uint16 } type TestCase struct { @@ -84,7 +84,7 @@ func genTestCases(dispatcherPort int) []*TestCase { // Addressing information var ( commonIA = xtest.MustParseIA("1-ff00:0:1") - commonPublicL3Address = addr.HostFromIP(net.IP{127, 0, 0, 1}) + commonPublicL3Address = netip.AddrFrom4([4]byte{127, 0, 0, 1}) commonUnderlayAddress = &net.UDPAddr{IP: net.IP{127, 0, 0, 1}, Port: dispatcherPort} clientXAddress = &ClientAddress{ IA: commonIA, @@ -111,11 +111,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.UDPPayload{ SrcPort: clientXAddress.PublicPort, @@ -131,11 +131,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.UDPPayload{ SrcPort: clientXAddress.PublicPort, @@ -154,11 +154,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.PublicAddress, + Host: addr.HostIP(clientYAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.ServiceAddress, + Host: addr.HostSVC(clientYAddress.ServiceAddress), }, Payload: snet.UDPPayload{ SrcPort: clientYAddress.PublicPort, @@ -174,11 +174,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.PublicAddress, + Host: addr.HostIP(clientYAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.ServiceAddress, + Host: addr.HostSVC(clientYAddress.ServiceAddress), }, Payload: snet.UDPPayload{ SrcPort: clientYAddress.PublicPort, @@ -198,22 +198,22 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPDestinationUnreachable{ Payload: MustPack(snet.Packet{ PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.UDPPayload{SrcPort: clientXAddress.PublicPort}, Path: path.Empty{}, @@ -228,22 +228,22 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPDestinationUnreachable{ Payload: MustPack(snet.Packet{ PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.UDPPayload{SrcPort: clientXAddress.PublicPort}, Path: path.Empty{}, @@ -265,11 +265,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:42"), // middle of nowhere - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.PublicAddress, + Host: addr.HostIP(clientYAddress.PublicAddress), }, Payload: snet.SCMPEchoRequest{Identifier: 0xdead}, Path: path.Empty{}, @@ -279,22 +279,22 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPDestinationUnreachable{ Payload: MustPack(snet.Packet{ PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPEchoRequest{Identifier: 0xdead}, Path: path.Empty{}, @@ -309,22 +309,22 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPDestinationUnreachable{ Payload: MustPack(snet.Packet{ PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPEchoRequest{Identifier: 0xdead}, Path: path.Empty{}, @@ -344,11 +344,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.PublicAddress, + Host: addr.HostIP(clientYAddress.PublicAddress), }, Payload: snet.SCMPEchoRequest{ Identifier: 0xdead, @@ -363,11 +363,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.PublicAddress, + Host: addr.HostIP(clientYAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPEchoReply{ Identifier: 0xdead, @@ -387,11 +387,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.PublicAddress, + Host: addr.HostIP(clientYAddress.PublicAddress), }, Payload: snet.SCMPTracerouteRequest{Identifier: 0xdeaf, Sequence: 0xcafd}, Path: path.Empty{}, @@ -402,11 +402,11 @@ func genTestCases(dispatcherPort int) []*TestCase { PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: clientYAddress.IA, - Host: clientYAddress.PublicAddress, + Host: addr.HostIP(clientYAddress.PublicAddress), }, Destination: snet.SCIONAddress{ IA: clientXAddress.IA, - Host: clientXAddress.PublicAddress, + Host: addr.HostIP(clientXAddress.PublicAddress), }, Payload: snet.SCMPTracerouteReply{Identifier: 0xdeaf, Sequence: 0xcafd}, Path: snet.RawPath{}, @@ -445,7 +445,7 @@ func RunTestCase(t *testing.T, tc *TestCase, settings *TestSettings) { ctx, tc.ClientAddress.IA, &net.UDPAddr{ - IP: tc.ClientAddress.PublicAddress.IP(), + IP: tc.ClientAddress.PublicAddress.AsSlice(), Port: int(tc.ClientAddress.PublicPort), }, tc.ClientAddress.ServiceAddress, diff --git a/dispatcher/dispatcher.go b/dispatcher/dispatcher.go index f38bf52d8e..86d15a09d8 100644 --- a/dispatcher/dispatcher.go +++ b/dispatcher/dispatcher.go @@ -94,7 +94,7 @@ func (as *Server) Serve() error { // Register creates a new connection. func (as *Server) Register(ctx context.Context, ia addr.IA, address *net.UDPAddr, - svc addr.HostSVC) (net.PacketConn, uint16, error) { + svc addr.SVC) (net.PacketConn, uint16, error) { tableEntry := newTableEntry() ref, err := as.routingTable.Register(ia, address, nil, svc, tableEntry) @@ -178,7 +178,7 @@ func (ac *Conn) LocalAddr() net.Addr { return ac.regReference.UDPAddr() } -func (ac *Conn) SVCAddr() addr.HostSVC { +func (ac *Conn) SVCAddr() addr.SVC { return ac.regReference.SVCAddr() } diff --git a/dispatcher/internal/registration/bench_test.go b/dispatcher/internal/registration/bench_test.go index 84d5e31909..177791c6a5 100644 --- a/dispatcher/internal/registration/bench_test.go +++ b/dispatcher/internal/registration/bench_test.go @@ -25,7 +25,7 @@ type registerArgs struct { ia addr.IA public *net.UDPAddr bind net.IP - svc addr.HostSVC + svc addr.SVC value interface{} } @@ -78,7 +78,7 @@ func BenchmarkLookupPublicIPv4(b *testing.B) { } type lookupServiceArgs struct { - svc addr.HostSVC + svc addr.SVC bind net.IP } diff --git a/dispatcher/internal/registration/generators_test.go b/dispatcher/internal/registration/generators_test.go index 35eeb8a6bf..ce12a84c07 100644 --- a/dispatcher/internal/registration/generators_test.go +++ b/dispatcher/internal/registration/generators_test.go @@ -49,7 +49,7 @@ func getRandomIA() addr.IA { ) } -func getRandomSVC() addr.HostSVC { +func getRandomSVC() addr.SVC { switch rand.Intn(2) { case 0: return addr.SvcNone diff --git a/dispatcher/internal/registration/iatable.go b/dispatcher/internal/registration/iatable.go index a19c2a937f..b677d09d31 100644 --- a/dispatcher/internal/registration/iatable.go +++ b/dispatcher/internal/registration/iatable.go @@ -39,7 +39,7 @@ type RegReference interface { UDPAddr() *net.UDPAddr // SVCAddr returns the SVC address associated with this reference. If no // SVC address is associated, it returns SvcNone. - SVCAddr() addr.HostSVC + SVCAddr() addr.SVC // RegisterID attaches an SCMP ID to this reference. The ID is released // when the reference is freed. Registering another ID does not overwrite // the previous; instead, multiple IDs get associated with the reference. @@ -69,7 +69,7 @@ type IATable interface { // see the documentation for SVCTable. // // To unregister from the table, free the returned reference. - Register(ia addr.IA, public *net.UDPAddr, bind net.IP, svc addr.HostSVC, + Register(ia addr.IA, public *net.UDPAddr, bind net.IP, svc addr.SVC, value interface{}) (RegReference, error) // LookupPublic returns the value associated with the selected public // address. Wildcard addresses are supported. If an entry is found, the @@ -87,7 +87,7 @@ type IATable interface { // // If SVC is a multicast address, more than one entry can be returned. The // bind address is ignored in this case. - LookupService(ia addr.IA, svc addr.HostSVC, bind net.IP) []interface{} + LookupService(ia addr.IA, svc addr.SVC, bind net.IP) []interface{} // LookupID returns the entry associated with the SCMP General class ID id. // The ID is used for SCMP Echo, TraceRoute, and RecordPath functionality. // If an entry is found, the returned boolean is set to true. Otherwise, it @@ -122,7 +122,7 @@ func newIATable(minPort, maxPort int) *iaTable { } } -func (t *iaTable) Register(ia addr.IA, public *net.UDPAddr, bind net.IP, svc addr.HostSVC, +func (t *iaTable) Register(ia addr.IA, public *net.UDPAddr, bind net.IP, svc addr.SVC, value interface{}) (RegReference, error) { t.mtx.Lock() @@ -160,7 +160,7 @@ func (t *iaTable) LookupPublic(ia addr.IA, public *net.UDPAddr) (interface{}, bo return nil, false } -func (t *iaTable) LookupService(ia addr.IA, svc addr.HostSVC, bind net.IP) []interface{} { +func (t *iaTable) LookupService(ia addr.IA, svc addr.SVC, bind net.IP) []interface{} { t.mtx.RLock() defer t.mtx.RUnlock() if table, ok := t.ia[ia]; ok { @@ -184,7 +184,7 @@ type iaTableReference struct { table *iaTable ia addr.IA entryRef *TableReference - svc addr.HostSVC + svc addr.SVC // value is the main table information associated with this reference value interface{} } @@ -202,7 +202,7 @@ func (r *iaTableReference) UDPAddr() *net.UDPAddr { return r.entryRef.UDPAddr() } -func (r *iaTableReference) SVCAddr() addr.HostSVC { +func (r *iaTableReference) SVCAddr() addr.SVC { return r.svc } diff --git a/dispatcher/internal/registration/svctable.go b/dispatcher/internal/registration/svctable.go index 6aacfe0c1e..7c93f41bd0 100644 --- a/dispatcher/internal/registration/svctable.go +++ b/dispatcher/internal/registration/svctable.go @@ -61,7 +61,7 @@ type SVCTable interface { // // To clean up resources, call Free on the returned Reference. Calling Free // more than once will cause a panic. - Register(svc addr.HostSVC, address *net.UDPAddr, value interface{}) (Reference, error) + Register(svc addr.SVC, address *net.UDPAddr, value interface{}) (Reference, error) // Lookup returns the entries associated with svc and ip. // // If SVC is an anycast address, at most one entry is returned. The ip @@ -73,7 +73,7 @@ type SVCTable interface { // // If SVC is a multicast address, more than one entry can be returned. The // ip address is ignored in this case. - Lookup(svc addr.HostSVC, ip net.IP) []interface{} + Lookup(svc addr.SVC, ip net.IP) []interface{} String() string } @@ -84,16 +84,16 @@ func NewSVCTable() SVCTable { var _ SVCTable = (*svcTable)(nil) type svcTable struct { - m map[addr.HostSVC]unicastIpTable + m map[addr.SVC]unicastIpTable } func newSvcTable() *svcTable { return &svcTable{ - m: make(map[addr.HostSVC]unicastIpTable), + m: make(map[addr.SVC]unicastIpTable), } } -func (t *svcTable) Register(svc addr.HostSVC, address *net.UDPAddr, +func (t *svcTable) Register(svc addr.SVC, address *net.UDPAddr, value interface{}) (Reference, error) { if err := validateUDPAddr(address); err != nil { @@ -126,7 +126,7 @@ func (t *svcTable) Register(svc addr.HostSVC, address *net.UDPAddr, return t.registerOne(svc, address, value) } -func (t *svcTable) registerOne(svc addr.HostSVC, address *net.UDPAddr, +func (t *svcTable) registerOne(svc addr.SVC, address *net.UDPAddr, value interface{}) (Reference, error) { if _, ok := t.m[svc]; !ok { t.m[svc] = make(unicastIpTable) @@ -141,7 +141,7 @@ func (t *svcTable) registerOne(svc addr.HostSVC, address *net.UDPAddr, }, nil } -func (t *svcTable) Lookup(svc addr.HostSVC, ip net.IP) []interface{} { +func (t *svcTable) Lookup(svc addr.SVC, ip net.IP) []interface{} { var values []interface{} if svc.IsMulticast() { values = t.multicast(svc) @@ -153,7 +153,7 @@ func (t *svcTable) Lookup(svc addr.HostSVC, ip net.IP) []interface{} { return values } -func (t *svcTable) multicast(svc addr.HostSVC) []interface{} { +func (t *svcTable) multicast(svc addr.SVC) []interface{} { var values []interface{} ipTable, ok := t.m[svc.Base()] if !ok { @@ -167,7 +167,7 @@ func (t *svcTable) multicast(svc addr.HostSVC) []interface{} { return values } -func (t *svcTable) anycast(svc addr.HostSVC, ip net.IP) (interface{}, bool) { +func (t *svcTable) anycast(svc addr.SVC, ip net.IP) (interface{}, bool) { ipTable, ok := t.m[svc] if !ok { return nil, false @@ -192,13 +192,13 @@ func (t *svcTable) String() string { return fmt.Sprintf("%v", t.m) } -func (t *svcTable) buildCleanupCallback(svc addr.HostSVC, ip net.IP, port *ring.Ring) func() { +func (t *svcTable) buildCleanupCallback(svc addr.SVC, ip net.IP, port *ring.Ring) func() { return func() { t.doCleanup(svc, ip, port) } } -func (t *svcTable) doCleanup(svc addr.HostSVC, ip net.IP, port *ring.Ring) { +func (t *svcTable) doCleanup(svc addr.SVC, ip net.IP, port *ring.Ring) { ipTable := t.m[svc] portList := ipTable[ip.String()] portList.Remove(port) diff --git a/dispatcher/internal/registration/svctable_test.go b/dispatcher/internal/registration/svctable_test.go index 240a7ebe1c..f89e0c1a26 100644 --- a/dispatcher/internal/registration/svctable_test.go +++ b/dispatcher/internal/registration/svctable_test.go @@ -32,7 +32,7 @@ func TestSVCTableLookup(t *testing.T) { value := "test value" testCases := map[string]struct { - Svc addr.HostSVC + Svc addr.SVC IP net.IP Prepare func(t *testing.T, table SVCTable) Expected []interface{} @@ -122,7 +122,7 @@ func TestSVCTableRegistration(t *testing.T) { testCases := map[string]struct { Prepare func(t *testing.T, table SVCTable) // Input Register - Svc addr.HostSVC + Svc addr.SVC Addr *net.UDPAddr Value interface{} // Assertions @@ -401,7 +401,7 @@ func TestSVCTableWildcard(t *testing.T) { defer reference.Free() testCases := map[string]struct { - Address addr.HostSVC + Address addr.SVC LookupResultCount int }{ "cs": { @@ -442,7 +442,7 @@ func TestSVCTableWildcardRollback(t *testing.T) { table := NewSVCTable() testCases := map[string]struct { - RegisteredAddress addr.HostSVC + RegisteredAddress addr.SVC LookupResultCSCount int LookupResultDSCount int }{ diff --git a/dispatcher/internal/registration/table.go b/dispatcher/internal/registration/table.go index 451d14518b..278cbc892e 100644 --- a/dispatcher/internal/registration/table.go +++ b/dispatcher/internal/registration/table.go @@ -44,7 +44,7 @@ func NewTable(minPort, maxPort int) *Table { } } -func (t *Table) Register(public *net.UDPAddr, bind net.IP, svc addr.HostSVC, +func (t *Table) Register(public *net.UDPAddr, bind net.IP, svc addr.SVC, value interface{}) (*TableReference, error) { if public == nil { @@ -69,7 +69,7 @@ func (t *Table) Register(public *net.UDPAddr, bind net.IP, svc addr.HostSVC, return &TableReference{table: t, address: address, svcRef: svcRef}, nil } -func (t *Table) insertSVCIfRequested(svc addr.HostSVC, bind net.IP, port int, +func (t *Table) insertSVCIfRequested(svc addr.SVC, bind net.IP, port int, value interface{}) (Reference, error) { if svc != addr.SvcNone { @@ -86,7 +86,7 @@ func (t *Table) LookupPublic(address *net.UDPAddr) (interface{}, bool) { return t.udpPortTable.Lookup(address) } -func (t *Table) LookupService(svc addr.HostSVC, bind net.IP) []interface{} { +func (t *Table) LookupService(svc addr.SVC, bind net.IP) []interface{} { return t.svcTable.Lookup(svc, bind) } diff --git a/dispatcher/internal/registration/table_test.go b/dispatcher/internal/registration/table_test.go index 5d717035b2..000c06848f 100644 --- a/dispatcher/internal/registration/table_test.go +++ b/dispatcher/internal/registration/table_test.go @@ -30,7 +30,7 @@ func TestRegister(t *testing.T) { tests := map[string]struct { a *net.UDPAddr b net.IP - svc addr.HostSVC + svc addr.SVC af assert.ErrorAssertionFunc }{ "no public address fails": { diff --git a/dispatcher/internal/respool/BUILD.bazel b/dispatcher/internal/respool/BUILD.bazel index ba4207764d..f66f9fa63e 100644 --- a/dispatcher/internal/respool/BUILD.bazel +++ b/dispatcher/internal/respool/BUILD.bazel @@ -22,6 +22,7 @@ go_test( srcs = ["packet_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/addr:go_default_library", "//pkg/private/xtest:go_default_library", "//pkg/slayers:go_default_library", "//pkg/slayers/path:go_default_library", diff --git a/dispatcher/internal/respool/packet_test.go b/dispatcher/internal/respool/packet_test.go index c2843d7ead..f3ad215bbd 100644 --- a/dispatcher/internal/respool/packet_test.go +++ b/dispatcher/internal/respool/packet_test.go @@ -15,13 +15,13 @@ package respool import ( - "net" "testing" "github.com/google/gopacket" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" "github.com/scionproto/scion/pkg/slayers/path" @@ -131,7 +131,7 @@ func scionLayer(t *testing.T, l4 slayers.L4ProtocolType) *slayers.SCION { }, }, } - require.NoError(t, scion.SetSrcAddr(&net.IPAddr{IP: net.IP{127, 0, 0, 1}})) - require.NoError(t, scion.SetDstAddr(&net.IPAddr{IP: net.IP{127, 0, 0, 2}})) + require.NoError(t, scion.SetSrcAddr(addr.MustParseHost("127.0.0.1"))) + require.NoError(t, scion.SetDstAddr(addr.MustParseHost("127.0.0.2"))) return scion } diff --git a/dispatcher/network/app_socket.go b/dispatcher/network/app_socket.go index 300cf7f190..2a6167de82 100644 --- a/dispatcher/network/app_socket.go +++ b/dispatcher/network/app_socket.go @@ -120,7 +120,7 @@ func (h *AppConnHandler) doRegExchange(appServer *dispatcher.Server) (net.Packet } func (h *AppConnHandler) logRegistration(ia addr.IA, public *net.UDPAddr, bind net.IP, - svc addr.HostSVC) { + svc addr.SVC) { items := []interface{}{"ia", ia, "public", public} if bind != nil { diff --git a/dispatcher/table.go b/dispatcher/table.go index e530602202..e48b40af76 100644 --- a/dispatcher/table.go +++ b/dispatcher/table.go @@ -53,7 +53,7 @@ func (t *IATable) LookupPublic(ia addr.IA, public *net.UDPAddr) (*TableEntry, bo return e.(*TableEntry), true } -func (t *IATable) LookupService(ia addr.IA, svc addr.HostSVC, bind net.IP) []*TableEntry { +func (t *IATable) LookupService(ia addr.IA, svc addr.SVC, bind net.IP) []*TableEntry { ifaces := t.IATable.LookupService(ia, svc, bind) entries := make([]*TableEntry, len(ifaces)) for i := range ifaces { diff --git a/dispatcher/underlay.go b/dispatcher/underlay.go index d42b14dc17..4a09cc22b8 100644 --- a/dispatcher/underlay.go +++ b/dispatcher/underlay.go @@ -90,19 +90,19 @@ func getDstUDP(pkt *respool.Packet) (Destination, error) { if err != nil { return nil, err } - switch d := dst.(type) { - case *net.IPAddr: + switch dst.Type() { + case addr.HostTypeIP: return UDPDestination{ IA: pkt.SCION.DstIA, Public: &net.UDPAddr{ - IP: d.IP, + IP: dst.IP().AsSlice(), Port: int(pkt.UDP.DstPort), }, }, nil - case addr.HostSVC: + case addr.HostTypeSVC: return SVCDestination{ IA: pkt.SCION.DstIA, - Svc: d, + Svc: dst.SVC(), }, nil default: return nil, serrors.WithCtx(ErrUnsupportedDestination, "type", common.TypeOf(dst)) @@ -167,14 +167,13 @@ func getDstSCMPErr(pkt *respool.Packet) (Destination, error) { if err != nil { return nil, err } - ipAddr, ok := dst.(*net.IPAddr) - if !ok { - return nil, serrors.WithCtx(ErrUnsupportedDestination, "type", common.TypeOf(dst)) + if dst.Type() != addr.HostTypeIP { + return nil, serrors.WithCtx(ErrUnsupportedDestination, "type", dst.Type()) } return UDPDestination{ IA: pkt.SCION.DstIA, Public: &net.UDPAddr{ - IP: ipAddr.IP, + IP: dst.IP().AsSlice(), Port: port, }, }, nil @@ -234,7 +233,7 @@ func (d UDPDestination) Send(dp *NetToRingDataplane, pkt *respool.Packet) { // service. type SVCDestination struct { IA addr.IA - Svc addr.HostSVC + Svc addr.SVC } func (d SVCDestination) Send(dp *NetToRingDataplane, pkt *respool.Packet) { diff --git a/dispatcher/underlay_test.go b/dispatcher/underlay_test.go index bc08c21095..e7e72a1ed5 100644 --- a/dispatcher/underlay_test.go +++ b/dispatcher/underlay_test.go @@ -61,7 +61,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCIONUDP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ExpectedDst: UDPDestination{ @@ -81,7 +81,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCIONUDP, } - require.NoError(t, pkt.SCION.SetDstAddr(addr.SvcCS)) + require.NoError(t, pkt.SCION.SetDstAddr(addr.HostSVC(addr.SvcCS))) return pkt }, ExpectedDst: SVCDestination{ @@ -252,7 +252,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ExpectedDst: UDPDestination{ @@ -308,7 +308,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ExpectedDst: SCMPDestination{ @@ -364,7 +364,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ExpectedDst: SCMPDestination{ @@ -419,7 +419,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ExpectedDst: UDPDestination{ @@ -476,7 +476,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ExpectedDst: SCMPDestination{ @@ -533,7 +533,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ExpectedDst: SCMPDestination{ @@ -588,7 +588,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ErrAssertion: assert.Error, @@ -641,7 +641,7 @@ func TestGetDst(t *testing.T) { }, L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("192.168.0.1"))) return pkt }, ErrAssertion: assert.Error, @@ -859,8 +859,8 @@ func TestSCMPHandlerReverse(t *testing.T) { SCMP: tc.L4(t), L4: slayers.LayerTypeSCMP, } - require.NoError(t, pkt.SCION.SetSrcAddr(&net.IPAddr{IP: net.IP{127, 0, 0, 1}})) - require.NoError(t, pkt.SCION.SetDstAddr(&net.IPAddr{IP: net.IP{127, 0, 0, 2}})) + require.NoError(t, pkt.SCION.SetSrcAddr(addr.MustParseHost("127.0.0.1"))) + require.NoError(t, pkt.SCION.SetDstAddr(addr.MustParseHost("127.0.0.2"))) // Reverse packet raw, err := SCMPHandler{}.reverse(pkt) @@ -902,8 +902,8 @@ func TestSCMPHandlerReverse(t *testing.T) { }, }, } - require.NoError(t, expected.SetSrcAddr(&net.IPAddr{IP: net.IP{127, 0, 0, 2}})) - require.NoError(t, expected.SetDstAddr(&net.IPAddr{IP: net.IP{127, 0, 0, 1}})) + require.NoError(t, expected.SetSrcAddr(addr.MustParseHost("127.0.0.2"))) + require.NoError(t, expected.SetDstAddr(addr.MustParseHost("127.0.0.1"))) scionL.BaseLayer = slayers.BaseLayer{} var decodedPath scion.Decoded @@ -951,7 +951,7 @@ func newSCIONHdr(t *testing.T, l4 slayers.L4ProtocolType) *slayers.SCION { }, }, } - require.NoError(t, scion.SetSrcAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 1}})) - require.NoError(t, scion.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 2}})) + require.NoError(t, scion.SetSrcAddr(addr.MustParseHost("192.168.0.1"))) + require.NoError(t, scion.SetDstAddr(addr.MustParseHost("192.168.0.2"))) return scion } diff --git a/gateway/cmd/gateway/main.go b/gateway/cmd/gateway/main.go index cf509fc36c..8796b1863f 100644 --- a/gateway/cmd/gateway/main.go +++ b/gateway/cmd/gateway/main.go @@ -20,6 +20,7 @@ import ( "net" "net/http" _ "net/http/pprof" + "net/netip" "github.com/go-chi/chi/v5" "github.com/go-chi/cors" @@ -74,6 +75,10 @@ func realMain(ctx context.Context) error { return serrors.WrapStr("determine default local IP", err) } } + controlAddressIP, ok := netip.AddrFromSlice(controlAddress.IP) + if !ok { + return serrors.New("invalid IP address", "control", controlAddress.IP) + } dataAddress, err := net.ResolveUDPAddr("udp", globalCfg.Gateway.DataAddr) if err != nil { return serrors.WrapStr("parsing data address", err) @@ -135,7 +140,7 @@ func realMain(ctx context.Context) error { ControlServerAddr: controlAddress, ControlClientIP: controlAddress.IP, ServiceDiscoveryClientIP: controlAddress.IP, - PathMonitorIP: controlAddress.IP, + PathMonitorIP: controlAddressIP, ProbeServerAddr: probeAddress, ProbeClientIP: controlAddress.IP, DataServerAddr: dataAddress, diff --git a/gateway/gateway.go b/gateway/gateway.go index 14103af340..d6fe36e583 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -111,14 +111,14 @@ func (pcf PacketConnFactory) New() (net.PacketConn, error) { type ProbeConnFactory struct { Dispatcher *reconnect.DispatcherService LocalIA addr.IA - LocalIP net.IP + LocalIP netip.Addr } func (f ProbeConnFactory) New(ctx context.Context) (net.PacketConn, error) { pathMonitorConnection, pathMonitorPort, err := f.Dispatcher.Register( context.Background(), f.LocalIA, - &net.UDPAddr{IP: f.LocalIP}, + &net.UDPAddr{IP: f.LocalIP.AsSlice()}, addr.SvcNone, ) if err != nil { @@ -186,7 +186,7 @@ type Gateway struct { ServiceDiscoveryClientIP net.IP // PathMonitorIP is the IP that should be used for path monitoring SCMP traceroute traffic. - PathMonitorIP net.IP + PathMonitorIP netip.Addr // ProbeServerAddr is the address for the probe server. The probe server replies // to probe traffic from other gateways. ProbeServerAddr *net.UDPAddr diff --git a/gateway/pathhealth/pathwatcher.go b/gateway/pathhealth/pathwatcher.go index 1116b4df3a..99f13d175d 100644 --- a/gateway/pathhealth/pathwatcher.go +++ b/gateway/pathhealth/pathwatcher.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "net" + "net/netip" "sync" "time" @@ -49,7 +50,7 @@ type DefaultPathWatcherFactory struct { // LocalIA is the ID of the local AS. LocalIA addr.IA // LocalIP is the IP address of the local host. - LocalIP net.IP + LocalIP netip.Addr // RevocationHandler is the revocation handler. RevocationHandler snet.RevocationHandler // ConnFactory is used to create probe connections. @@ -109,7 +110,7 @@ func (f *DefaultPathWatcherFactory) New( id: id, localAddr: snet.SCIONAddress{ IA: f.LocalIA, - Host: addr.HostFromIP(f.LocalIP), + Host: addr.HostIP(f.LocalIP), }, pktChan: pktChan, probesSent: createCounter(f.ProbesSent, remote), @@ -290,7 +291,7 @@ func (w *pathWatcher) prepareProbePacket() error { Destination: snet.SCIONAddress{ IA: w.remote, // The host doesn't really matter because it's terminated at the router. - Host: addr.SvcNone, + Host: addr.HostSVC(addr.SvcNone), }, Source: w.localAddr, Path: w.path.dpPath, diff --git a/pkg/addr/BUILD.bazel b/pkg/addr/BUILD.bazel index 6c003ea6f6..9ee5fd06f1 100644 --- a/pkg/addr/BUILD.bazel +++ b/pkg/addr/BUILD.bazel @@ -3,10 +3,12 @@ load("//tools/lint:go.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ + "addr.go", "doc.go", "fmt.go", "host.go", "isdas.go", + "svc.go", ], importpath = "github.com/scionproto/scion/pkg/addr", visibility = ["//visibility:public"], @@ -16,9 +18,14 @@ go_library( go_test( name = "go_default_test", srcs = [ + "addr_test.go", "host_test.go", "isdas_test.go", + "svc_test.go", ], embed = [":go_default_library"], - deps = ["@com_github_stretchr_testify//assert:go_default_library"], + deps = [ + "@com_github_stretchr_testify//assert:go_default_library", + "@com_github_stretchr_testify//require:go_default_library", + ], ) diff --git a/pkg/addr/addr.go b/pkg/addr/addr.go new file mode 100644 index 0000000000..4467f54a42 --- /dev/null +++ b/pkg/addr/addr.go @@ -0,0 +1,117 @@ +// Copyright 2023 SCION Association +// +// 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 addr + +import ( + "fmt" + "net" + "strconv" + "strings" + + "github.com/scionproto/scion/pkg/private/serrors" +) + +// Addr is a full SCION address, composed of ISD, AS and Host part. +type Addr struct { + IA IA + Host Host +} + +// ParseAddr parses s as an address in the format -,, +// returning the result as an Addr. +func ParseAddr(s string) (Addr, error) { + comma := strings.IndexByte(s, ',') + if comma < 0 { + return Addr{}, serrors.New("invalid address: expected comma", "value", s) + } + ia, err := ParseIA(s[0:comma]) + if err != nil { + return Addr{}, err + } + h, err := ParseHost(s[comma+1:]) + if err != nil { + return Addr{}, err + } + return Addr{IA: ia, Host: h}, nil +} + +// MustParseAddr calls ParseAddr(s) and panics on error. +// It is intended for use in tests with hard-coded strings. +func MustParseAddr(s string) Addr { + a, err := ParseAddr(s) + if err != nil { + panic(err) + } + return a +} + +func (a Addr) String() string { + return fmt.Sprintf("%s,%s", a.IA, a.Host) +} + +// Set implements flag.Value interface +func (a *Addr) Set(s string) error { + pA, err := ParseAddr(s) + if err != nil { + return err + } + *a = pA + return nil +} + +func (a Addr) MarshalText() ([]byte, error) { + return []byte(a.String()), nil +} + +func (a *Addr) UnmarshalText(b []byte) error { + return a.Set(string(b)) +} + +// ParseAddrPort parses s as a SCION address with a port, in the format +// +// [-,]:. +// +// Examples: +// - [isd-as,svc]:port (e.g., [1-ff00:0:110,CS]:80) +// - [isd-as,ipv4]:port (e.g., [1-ff00:0:110,192.0.2.1]:80) +// - [isd-as,ipv6%zone]:port (e.g., [1-ff00:0:110,2001:DB8::1%zone]:80) +// +// EXPERIMENTAL: This API is experimental. It may be changed to return a +// combined AddrPort type instead. +func ParseAddrPort(s string) (Addr, uint16, error) { + host, port, err := net.SplitHostPort(s) + if err != nil { + return Addr{}, 0, serrors.WrapStr("invalid address: split host:port", err, "addr", s) + } + a, err := ParseAddr(host) + if err != nil { + return Addr{}, 0, serrors.WrapStr("invalid address: host invalid", err, "host", host) + } + p, err := strconv.ParseUint(port, 10, 16) + if err != nil { + return Addr{}, 0, serrors.WrapStr("invalid address: port invalid", err, "port", port) + } + return a, uint16(p), nil +} + +// FormatAddrPort formats an Addr with a port to the format +// +// [-,]:. +// +// EXPERIMENTAL: This API is experimental. It may be changed to a String() +// function an a combined AddrPort type instead. +func FormatAddrPort(a Addr, port uint16) string { + return fmt.Sprintf("[%s]:%d", a, port) +} diff --git a/pkg/addr/addr_test.go b/pkg/addr/addr_test.go new file mode 100644 index 0000000000..b3056c3e8d --- /dev/null +++ b/pkg/addr/addr_test.go @@ -0,0 +1,221 @@ +// Copyright 2023 SCION Association +// +// 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 addr_test + +import ( + "encoding" + "flag" + "fmt" + "net/netip" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/scionproto/scion/pkg/addr" +) + +func ExampleParseAddr() { + a, err := addr.ParseAddr("6-ffaa:0:123,198.51.100.1") + fmt.Printf("ia: %v, host type: %v, host: %v, err: %v\n", a.IA, a.Host.Type(), a.Host, err) + // Output: ia: 6-ffaa:0:123, host type: IP, host: 198.51.100.1, err: +} + +func ExampleParseAddr_svc() { + a, err := addr.ParseAddr("6-ffaa:0:123,CS") + fmt.Printf("ia: %v, host type: %v, host: %v, err: %v\n", a.IA, a.Host.Type(), a.Host, err) + // Output: ia: 6-ffaa:0:123, host type: SVC, host: CS, err: +} + +func TestParseAddr(t *testing.T) { + invalid := []string{ + "", + ",", + "a", + "0-0::", + "0-0,::,", + "1,ffaa:0:1101::", + "65536-1,ff00::1", + "[1-ffaa:0:1101,127.0.0.1]", + } + for _, s := range invalid { + t.Run(s, func(t *testing.T) { + _, err := addr.ParseAddr(s) + assert.Error(t, err) + }) + t.Run("unmarshal "+s, func(t *testing.T) { + var a addr.Addr + var u encoding.TextUnmarshaler = &a + err := u.UnmarshalText([]byte(s)) + assert.Error(t, err) + assert.Equal(t, addr.Addr{}, a) + }) + t.Run("set "+s, func(t *testing.T) { + var a addr.Addr + var v flag.Value = &a + err := v.Set(s) + assert.Error(t, err) + assert.Equal(t, addr.Addr{}, a) + }) + } + + valid := map[string]addr.Addr{ + "0-0,::": { + IA: addr.MustIAFrom(0, 0), + Host: addr.HostIP(netip.AddrFrom16([16]byte{})), + }, + "0-0,0.0.0.0": { + IA: addr.MustIAFrom(0, 0), + Host: addr.HostIP(netip.AddrFrom4([4]byte{})), + }, + "1-ffaa:0:1101,::1": { + IA: addr.MustIAFrom(1, 0xffaa_0000_1101), + Host: addr.HostIP(netip.AddrFrom16( + [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + )), + }, + "1-ffaa:0:1101,127.0.0.1": { + IA: addr.MustIAFrom(1, 0xffaa_0000_1101), + Host: addr.HostIP(netip.AddrFrom4([4]byte{127, 0, 0, 1})), + }, + "1-ffaa:0:1101,CS": { + IA: addr.MustIAFrom(1, 0xffaa_0000_1101), + Host: addr.HostSVC(addr.SvcCS), + }, + "65535-1,ff00::1": { + IA: addr.MustIAFrom(65535, 1), + Host: addr.HostIP(netip.AddrFrom16( + [16]byte{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, + )), + }, + "1-1:fcd1:1,::ffff:192.0.2.128": { + IA: addr.MustIAFrom(1, 0x0001_fcd1_0001), + Host: addr.HostIP(netip.AddrFrom16( + [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 0, 2, 128}, + )), + }, + } + for s, expected := range valid { + t.Run(s, func(t *testing.T) { + a, err := addr.ParseAddr(s) + require.NoError(t, err) + assert.Equal(t, expected, a) + }) + t.Run("unmarshal "+s, func(t *testing.T) { + var a addr.Addr + var u encoding.TextUnmarshaler = &a + err := u.UnmarshalText([]byte(s)) + require.NoError(t, err) + assert.Equal(t, expected, a) + }) + t.Run("set "+s, func(t *testing.T) { + var a addr.Addr + var v flag.Value = &a + err := v.Set(s) + require.NoError(t, err) + assert.Equal(t, expected, a) + }) + } +} + +func TestParseAddrPort(t *testing.T) { + invalid := []string{ + "", + "[]", + "[]:", + "[0-0,::]:65536", + "[0-0,::]:http", + "[0-0,::]:a", + "[1-ffaa:0:1101,127.0.0.1]", + "[1-ffaa:0:1101,127.0.0.1]:0xff", + "[1-ffaa:0:1101,127.0.0.1]:ff", + "[1-ffaa:0:1101,127.0.0.1]:-1", + "[1-ffaa:0:1101,127.0.0.1]:666666", + } + for _, s := range invalid { + t.Run(s, func(t *testing.T) { + _, _, err := addr.ParseAddrPort(s) + assert.Error(t, err) + }) + } + + valid := map[string]struct { + IA addr.IA + Host addr.Host + Port uint16 + }{ + "[0-0,::]:0": { + IA: addr.MustIAFrom(0, 0), + Host: addr.HostIP(netip.AddrFrom16([16]byte{})), + Port: 0, + }, + "[0-0,::]:65535": { + IA: addr.MustIAFrom(0, 0), + Host: addr.HostIP(netip.AddrFrom16([16]byte{})), + Port: 65535, + }, + "[0-0,0.0.0.0]:1234": { + IA: addr.MustIAFrom(0, 0), + Host: addr.HostIP(netip.AddrFrom4([4]byte{})), + Port: 1234, + }, + "[1-ffaa:0:1101,::1]:54321": { + IA: addr.MustIAFrom(1, 0xffaa_0000_1101), + Host: addr.HostIP(netip.AddrFrom16( + [16]byte{15: 1}, + )), + Port: 54321, + }, + "[1-ffaa:0:1101,127.0.0.1]:010": { + IA: addr.MustIAFrom(1, 0xffaa_0000_1101), + Host: addr.HostIP(netip.AddrFrom4([4]byte{127, 0, 0, 1})), + Port: 10, + }, + "[1-ffaa:0:1101,CS]:42": { + IA: addr.MustIAFrom(1, 0xffaa_0000_1101), + Host: addr.HostSVC(addr.SvcCS), + Port: 42, + }, + "[65535-1,ff00::1]:8888": { + IA: addr.MustIAFrom(65535, 1), + Host: addr.HostIP(netip.AddrFrom16( + [16]byte{0: 0xff, 15: 1}, + )), + Port: 8888, + }, + "[1-1:fcd1:1,::ffff:192.0.2.128]:0000000000000000000080": { + IA: addr.MustIAFrom(1, 0x0001_fcd1_0001), + Host: addr.HostIP(netip.AddrFrom16( + [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 0, 2, 128}, + )), + Port: 80, + }, + } + + for s, expected := range valid { + t.Run(s, func(t *testing.T) { + a, port, err := addr.ParseAddrPort(s) + require.NoError(t, err) + assert.Equal(t, addr.Addr{IA: expected.IA, Host: expected.Host}, a) + assert.Equal(t, expected.Port, port) + + fmted := addr.FormatAddrPort(a, port) + if !strings.Contains(s, "]:0") { // skip cases where port has leading 0s + assert.Equal(t, s, fmted) + } + }) + } +} diff --git a/pkg/addr/doc.go b/pkg/addr/doc.go index 26382813a2..ae493bfa02 100644 --- a/pkg/addr/doc.go +++ b/pkg/addr/doc.go @@ -18,6 +18,9 @@ Package addr contains types for SCION addressing. A SCION address is composed of the following parts: ISD (ISolation Domain identifier), AS (Autonomous System idenifier), and Host (the host address). +The ISD-AS parts are often considered together. Conventionally, this is +abbreviated to "IA". + The allocations and formatting of ISDs and ASes are documented here: https://github.com/scionproto/scion/wiki/ISD-and-AS-numbering. Note that the ':' separator for AS formatting is not used in paths/filenames for diff --git a/pkg/addr/host.go b/pkg/addr/host.go index 69ffba2f53..d6f157e54c 100644 --- a/pkg/addr/host.go +++ b/pkg/addr/host.go @@ -1,5 +1,6 @@ // Copyright 2016 ETH Zurich // Copyright 2018 ETH Zurich, Anapaya Systems +// Copyright 2022 ETH Zurich, Anapaya Systems, SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,20 +17,16 @@ package addr import ( - "encoding/binary" "fmt" - "net" - "strings" - - "github.com/scionproto/scion/pkg/private/serrors" + "net/netip" ) +// HostAddrType discriminates between different types of Host addresses. type HostAddrType uint8 const ( HostTypeNone HostAddrType = iota - HostTypeIPv4 - HostTypeIPv6 + HostTypeIP HostTypeSVC ) @@ -37,313 +34,103 @@ func (t HostAddrType) String() string { switch t { case HostTypeNone: return "None" - case HostTypeIPv4: - return "IPv4" - case HostTypeIPv6: - return "IPv6" + case HostTypeIP: + return "IP" case HostTypeSVC: return "SVC" } return fmt.Sprintf("UNKNOWN (%d)", t) } -const ( - HostLenNone = 0 - HostLenIPv4 = net.IPv4len - HostLenIPv6 = net.IPv6len - HostLenSVC = 2 -) - -var ( - // ErrBadHostAddrType indicates an invalid host address type. - ErrBadHostAddrType = serrors.New("unsupported host address type") - // ErrMalformedHostAddrType indicates a malformed host address type. - ErrMalformedHostAddrType = serrors.New("malformed host address type") - // ErrUnsupportedSVCAddress indicates an unsupported SVC address. - ErrUnsupportedSVCAddress = serrors.New("unsupported SVC address") -) - -const ( - SvcDS HostSVC = 0x0001 - SvcCS HostSVC = 0x0002 - SvcWildcard HostSVC = 0x0010 - SvcNone HostSVC = 0xffff - - SVCMcast HostSVC = 0x8000 -) - -type HostAddr interface { - Size() int - Type() HostAddrType - Pack() []byte - IP() net.IP - Copy() HostAddr - Equal(HostAddr) bool - fmt.Stringer -} - -var _ HostAddr = (HostNone)(nil) - -type HostNone net.IP - -func (h HostNone) Size() int { - return HostLenNone -} - -func (h HostNone) Type() HostAddrType { - return HostTypeNone -} - -func (h HostNone) Pack() []byte { - return []byte{} -} - -func (h HostNone) IP() net.IP { - return nil -} - -func (h HostNone) Copy() HostAddr { - return HostNone{} -} - -func (h HostNone) Equal(o HostAddr) bool { - _, ok := o.(HostNone) - return ok -} - -func (h HostNone) String() string { - return "" -} - -var _ HostAddr = (HostIPv4)(nil) - -type HostIPv4 net.IP - -func (h HostIPv4) Size() int { - return HostLenIPv4 -} - -func (h HostIPv4) Type() HostAddrType { - return HostTypeIPv4 -} - -func (h HostIPv4) Pack() []byte { - return []byte(h.IP()) -} - -func (h HostIPv4) IP() net.IP { - // XXX(kormat): ensure the reply is the 4-byte representation. - return net.IP(h).To4() -} - -func (h HostIPv4) Copy() HostAddr { - return HostIPv4(append(net.IP(nil), h...)) -} - -func (h HostIPv4) Equal(o HostAddr) bool { - ha, ok := o.(HostIPv4) - return ok && net.IP(h).Equal(net.IP(ha)) -} - -func (h HostIPv4) String() string { - return h.IP().String() -} - -var _ HostAddr = (HostIPv6)(nil) - -type HostIPv6 net.IP - -func (h HostIPv6) Size() int { - return HostLenIPv6 -} - -func (h HostIPv6) Type() HostAddrType { - return HostTypeIPv6 -} - -func (h HostIPv6) Pack() []byte { - return []byte(h)[:HostLenIPv6] -} - -func (h HostIPv6) IP() net.IP { - return net.IP(h) -} - -func (h HostIPv6) Copy() HostAddr { - return HostIPv6(append(net.IP(nil), h...)) -} - -func (h HostIPv6) Equal(o HostAddr) bool { - ha, ok := o.(HostIPv6) - return ok && net.IP(h).Equal(net.IP(ha)) -} - -func (h HostIPv6) String() string { - return h.IP().String() -} - -var _ HostAddr = (*HostSVC)(nil) - -type HostSVC uint16 - -// HostSVCFromString returns the SVC address corresponding to str. For anycast -// SVC addresses, use BS_A, PS_A, CS_A, and SB_A; shorthand versions without -// the _A suffix (e.g., PS) also return anycast SVC addresses. For multicast, -// use BS_M, PS_M, CS_M, and SB_M. -func HostSVCFromString(str string) HostSVC { - var m HostSVC - switch { - case strings.HasSuffix(str, "_A"): - str = strings.TrimSuffix(str, "_A") - case strings.HasSuffix(str, "_M"): - str = strings.TrimSuffix(str, "_M") - m = SVCMcast +// Host represents the AS-local host identifier of a SCION address. +// +// Different address types (IPv4, IPv6, SVC) are all represented with +// this Host struct, discriminated with a Type() field. +// +// The zero value is a valid object with Host{}.Type() == HostTypeNone. +type Host struct { + ip netip.Addr + svc SVC + t HostAddrType +} + +// ParseHost parses s as either a service address or an IP address, +// returning the result as a Host address. +// s can either be a SVC address, in the format supported by ParseSVC(s), +// or an IP address in dotted decimal or IPv6 format. +func ParseHost(s string) (Host, error) { + svc, err := ParseSVC(s) + if err == nil { + return HostSVC(svc), nil } - switch str { - case "DS": - return SvcDS | m - case "CS": - return SvcCS | m - case "Wildcard": - return SvcWildcard | m - default: - return SvcNone + ip, err := netip.ParseAddr(s) + if err != nil { + return Host{}, err } + return HostIP(ip), nil } -func (h HostSVC) Size() int { - return HostLenSVC -} - -func (h HostSVC) Type() HostAddrType { - return HostTypeSVC -} - -func (h HostSVC) Pack() []byte { - out := make([]byte, HostLenSVC) - binary.BigEndian.PutUint16(out, uint16(h)) - return out -} - -func (h HostSVC) PackWithPad(pad int) []byte { - out := make([]byte, HostLenSVC+pad) - binary.BigEndian.PutUint16(out, uint16(h)) - return out -} - -func (h HostSVC) IP() net.IP { - return nil -} - -func (h HostSVC) IsMulticast() bool { - return (h & SVCMcast) != 0 -} - -func (h HostSVC) Base() HostSVC { - return h & ^SVCMcast -} - -func (h HostSVC) Multicast() HostSVC { - return h | SVCMcast -} - -func (h HostSVC) Copy() HostAddr { - return h -} - -func (h HostSVC) Equal(o HostAddr) bool { - ha, ok := o.(HostSVC) - return ok && h == ha -} - -func (h HostSVC) String() string { - name := h.BaseString() - cast := 'A' - if h.IsMulticast() { - cast = 'M' +// MustParseHost calls ParseHost(s) and panics on error. +// It is intended for use in tests with hard-coded strings. +func MustParseHost(s string) Host { + host, err := ParseHost(s) + if err != nil { + panic(err) } - return fmt.Sprintf("%v %c (0x%04x)", name, cast, uint16(h)) + return host } -// BaseString returns the upper case name of the service. For hosts or unrecognized services, it -// returns UNKNOWN. -func (h HostSVC) BaseString() string { - switch h.Base() { - case SvcDS: - return "DS" - case SvcCS: - return "CS" - case SvcWildcard: - return "Wildcard" - default: - return "UNKNOWN" - } +// HostIP returns a Host address representing ip, with type HostTypeIP. +func HostIP(ip netip.Addr) Host { + return Host{t: HostTypeIP, ip: ip} } -func (h HostSVC) Network() string { - return "" +// HostSvc returns a Host address representing svc, with type HostTypeSVC. +func HostSVC(svc SVC) Host { + return Host{t: HostTypeSVC, svc: svc} } -func HostFromRaw(b []byte, htype HostAddrType) (HostAddr, error) { - switch htype { - case HostTypeNone: - return HostNone{}, nil - case HostTypeIPv4: - if len(b) < HostLenIPv4 { - return nil, serrors.WithCtx(ErrMalformedHostAddrType, "type", htype) - } - return HostIPv4(b[:HostLenIPv4]), nil - case HostTypeIPv6: - if len(b) < HostLenIPv6 { - return nil, serrors.WithCtx(ErrMalformedHostAddrType, "type", htype) - } - return HostIPv6(b[:HostLenIPv6]), nil - case HostTypeSVC: - if len(b) < HostLenSVC { - return nil, serrors.WithCtx(ErrMalformedHostAddrType, "type", htype) - } - return HostSVC(binary.BigEndian.Uint16(b)), nil - default: - return nil, serrors.WithCtx(ErrBadHostAddrType, "type", htype) - } +// Type returns the type of the address represented by h. +func (h Host) Type() HostAddrType { + return h.t } -func HostFromIP(ip net.IP) HostAddr { - if ip4 := ip.To4(); ip4 != nil { - return HostIPv4(ip4) +// IP returns the IP address represented by h. +// Panics if h.Type() is not HostTypeIP. +func (h Host) IP() netip.Addr { + if h.t != HostTypeIP { + panic("IP called on non-IP address") } - return HostIPv6(ip) + return h.ip } -func HostFromIPStr(s string) HostAddr { - ip := net.ParseIP(s) - if ip == nil { - return nil +// SVC returns the SVC address represented by h. +// Panics if h.Type() is not HostTypeSVC. +func (h Host) SVC() SVC { + if h.t != HostTypeSVC { + panic("SVC called on non-SVC address") } - return HostFromIP(ip) + return h.svc } -func HostLen(htype HostAddrType) (uint8, error) { - var length uint8 - switch htype { +func (h Host) String() string { + switch h.Type() { case HostTypeNone: - length = HostLenNone - case HostTypeIPv4: - length = HostLenIPv4 - case HostTypeIPv6: - length = HostLenIPv6 + return "" + case HostTypeIP: + return h.ip.String() case HostTypeSVC: - length = HostLenSVC - default: - return 0, serrors.WithCtx(ErrBadHostAddrType, "type", htype) + return h.svc.String() } - return length, nil + panic("unsupported host type") } -func HostTypeCheck(t HostAddrType) bool { - switch t { - case HostTypeIPv6, HostTypeIPv4, HostTypeSVC: - return true +// Set implements flag.Value interface +func (h *Host) Set(s string) error { + pH, err := ParseHost(s) + if err != nil { + return err } - return false + *h = pH + return nil } diff --git a/pkg/addr/host_test.go b/pkg/addr/host_test.go index 7f0272ede3..d8da6eada0 100644 --- a/pkg/addr/host_test.go +++ b/pkg/addr/host_test.go @@ -1,4 +1,4 @@ -// Copyright 2021 ETH Zurich, Anapaya Systems +// Copyright 2023 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -15,72 +15,146 @@ package addr_test import ( - "net" + "fmt" + "net/netip" + "reflect" + "runtime" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/scionproto/scion/pkg/addr" ) -func TestHostFromRaw(t *testing.T) { - testCases := map[string]struct { - input []byte - addrType addr.HostAddrType - expected addr.HostAddr - errAssertion assert.ErrorAssertionFunc - }{ - "nil IPv4": { - addrType: addr.HostTypeIPv4, - errAssertion: assert.Error, - }, - "short IPv4": { - input: make([]byte, 3), - addrType: addr.HostTypeIPv4, - errAssertion: assert.Error, - }, - "valid IPv4": { - input: []byte{127, 0, 0, 1}, - addrType: addr.HostTypeIPv4, - expected: addr.HostFromIP(net.IPv4(127, 0, 0, 1)), - errAssertion: assert.NoError, - }, - "nil IPv6": { - addrType: addr.HostTypeIPv6, - errAssertion: assert.Error, - }, - "short IPv6": { - input: make([]byte, 14), - addrType: addr.HostTypeIPv6, - errAssertion: assert.Error, - }, - "valid IPv6": { - input: net.ParseIP("dead::beef"), - addrType: addr.HostTypeIPv6, - expected: addr.HostFromIP(net.ParseIP("dead::beef")), - errAssertion: assert.NoError, - }, - "nil SVC": { - addrType: addr.HostTypeSVC, - errAssertion: assert.Error, - }, - "short SVC": { - input: make([]byte, 1), - addrType: addr.HostTypeSVC, - errAssertion: assert.Error, - }, - "valid SVC": { - input: addr.SvcDS.Pack(), - addrType: addr.HostTypeSVC, - expected: addr.SvcDS, - errAssertion: assert.NoError, - }, +func ExampleHost() { + hs := []addr.Host{ + {}, + addr.HostIP(netip.MustParseAddr("::1")), + addr.HostIP(netip.AddrFrom4([4]byte{198, 51, 100, 1})), + addr.HostSVC(addr.SvcCS), } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - got, err := addr.HostFromRaw(tc.input, tc.addrType) - tc.errAssertion(t, err) - assert.Equal(t, tc.expected, got) + for _, h := range hs { + fmt.Printf("h: %q, h.Type(): %q", h, h.Type()) + switch h.Type() { + case addr.HostTypeIP: + fmt.Printf(", h.IP().Is4(): %v", h.IP().Is4()) + case addr.HostTypeSVC: + fmt.Printf(", h.SVC().IsMulticast(): %v", h.SVC().IsMulticast()) + default: + fmt.Printf(", h == addr.Host{}: %v", h == addr.Host{}) + } + fmt.Println() + } + + // Use Host as map key: + stuff := make(map[addr.Host]struct{}) + for _, h := range hs { + stuff[h] = struct{}{} + } + _, hasSvcCS := stuff[addr.HostSVC(addr.SvcCS)] + _, hasSvcDS := stuff[addr.HostSVC(addr.SvcDS)] + fmt.Printf("has SvcCS: %v, has SvcDS: %v", hasSvcCS, hasSvcDS) + + // Output: + // h: "", h.Type(): "None", h == addr.Host{}: true + // h: "::1", h.Type(): "IP", h.IP().Is4(): false + // h: "198.51.100.1", h.Type(): "IP", h.IP().Is4(): true + // h: "CS", h.Type(): "SVC", h.SVC().IsMulticast(): false + // has SvcCS: true, has SvcDS: false +} + +func TestHostStructSize(t *testing.T) { + if runtime.GOARCH != `amd64` { + t.SkipNow() + } + ipv6 := 16 + zonePtr := 8 + svc := 2 + typ := 1 + padding := 5 + expected := ipv6 + zonePtr + svc + typ + padding + + sizeofHost := int(reflect.TypeOf(addr.Host{}).Size()) + assert.Equal(t, expected, sizeofHost) +} + +func TestParseHost(t *testing.T) { + invalid := []string{ + "", + "x", + "512.0.0.1", + "10.1234567", + "::ffff1", + "2001:0db8:85a3:0000:0000:8a2e:0370:7334:1", // too long + " ::1", + "::1 ", + "localhost", + "CS_X", // almost a service addr + } + for _, s := range invalid { + t.Run(s, func(t *testing.T) { + _, err := addr.ParseHost(s) + assert.Error(t, err) + }) + } + + ipv6 := []string{ + "::", + "::1", + "::ff02:1", + "2001:0db8:85a3:0000:0000:8a2e:0370:7334", + "fe80::1ff:fe23:4567:890a%eth2", + "::ffff:192.0.2.128", + "ff00::", + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", + } + for _, s := range ipv6 { + t.Run(s, func(t *testing.T) { + h, err := addr.ParseHost(s) + require.NoError(t, err) + require.Equal(t, addr.HostTypeIP, h.Type()) + assert.True(t, h.IP().Is6()) + assert.Equal(t, netip.MustParseAddr(s), h.IP()) + }) + } + + ipv4 := []string{ + "0.0.0.0", + "127.0.0.1", + "198.51.100.0", + "198.51.100.1", + "198.51.100.254", + "198.51.100.255", + "255.255.255.255", + } + for _, s := range ipv4 { + t.Run(s, func(t *testing.T) { + h, err := addr.ParseHost(s) + require.NoError(t, err) + require.Equal(t, addr.HostTypeIP, h.Type()) + assert.True(t, h.IP().Is4()) + assert.Equal(t, netip.MustParseAddr(s), h.IP()) + }) + } + + svcs := map[string]addr.SVC{ + "CS": addr.SvcCS, + "DS": addr.SvcDS, + "Wildcard": addr.SvcWildcard, + "CS_A": addr.SvcCS, + "DS_A": addr.SvcDS, + "Wildcard_A": addr.SvcWildcard, + "CS_M": addr.SvcCS.Multicast(), + "DS_M": addr.SvcDS.Multicast(), + "Wildcard_M": addr.SvcWildcard.Multicast(), + } + for src, svc := range svcs { + t.Run(src, func(t *testing.T) { + h, err := addr.ParseHost(src) + require.NoError(t, err) + require.Equal(t, addr.HostTypeSVC, h.Type()) + assert.Equal(t, svc, h.SVC()) }) } } diff --git a/pkg/addr/svc.go b/pkg/addr/svc.go new file mode 100644 index 0000000000..d69ab926bc --- /dev/null +++ b/pkg/addr/svc.go @@ -0,0 +1,106 @@ +// Copyright 2022 SCION Association +// +// 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 addr + +import ( + "fmt" + "strings" + + "github.com/scionproto/scion/pkg/private/serrors" +) + +const ( + SvcDS SVC = 0x0001 + SvcCS SVC = 0x0002 + SvcWildcard SVC = 0x0010 + SvcNone SVC = 0xffff + + SVCMcast SVC = 0x8000 +) + +var ( + // ErrUnsupportedSVCAddress indicates an unsupported SVC address. + ErrUnsupportedSVCAddress = serrors.New("unsupported SVC address") +) + +// SVC is a SCION service address. +// A service address is a short identifier for the service type, and a +// flag-bit for multicast. +// The package's SVC constant values are defined without multicast. +// The Multicast and Base methods set/unset the multicast flag. +type SVC uint16 + +// ParseSVC returns the SVC address corresponding to str. For anycast +// SVC addresses, use CS_A and DS_A; shorthand versions without +// the _A suffix (e.g., CS) also return anycast SVC addresses. For multicast, +// use CS_M, and DS_M. +func ParseSVC(str string) (SVC, error) { + var m SVC + switch { + case strings.HasSuffix(str, "_A"): + str = strings.TrimSuffix(str, "_A") + case strings.HasSuffix(str, "_M"): + str = strings.TrimSuffix(str, "_M") + m = SVCMcast + } + switch str { + case "DS": + return SvcDS | m, nil + case "CS": + return SvcCS | m, nil + case "Wildcard": + return SvcWildcard | m, nil + default: + return SvcNone, serrors.New("invalid service address", "value", str) + } +} + +// IsMulticast returns the value of the multicast flag. +func (h SVC) IsMulticast() bool { + return (h & SVCMcast) != 0 +} + +// Base returns the SVC identifier with the multicast flag unset. +func (h SVC) Base() SVC { + return h & ^SVCMcast +} + +// Multicast returns the SVC identifier with the multicast flag set. +func (h SVC) Multicast() SVC { + return h | SVCMcast +} + +func (h SVC) String() string { + s := h.BaseString() + if h.IsMulticast() { + s += "_M" + } + return s +} + +// BaseString returns the upper case name of the service. For unrecognized services, it +// returns "". +func (h SVC) BaseString() string { + switch h.Base() { + case SvcDS: + return "DS" + case SvcCS: + return "CS" + case SvcWildcard: + return "Wildcard" + default: + return fmt.Sprintf("", uint16(h)) + } +} diff --git a/pkg/addr/svc_test.go b/pkg/addr/svc_test.go new file mode 100644 index 0000000000..2af253df2a --- /dev/null +++ b/pkg/addr/svc_test.go @@ -0,0 +1,78 @@ +// Copyright 2023 SCION Association +// +// 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 addr_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/scionproto/scion/pkg/addr" +) + +func TestParseSVC(t *testing.T) { + invalid := []string{ + "", + "garbage", + "CS_Y", + "cs_a", + "cs_m", + "CS ", + " CS", + } + for _, src := range invalid { + t.Run(src, func(t *testing.T) { + _, err := addr.ParseSVC(src) + assert.Error(t, err) + }) + } + + valid := map[string]addr.SVC{ + "CS": addr.SvcCS, + "DS": addr.SvcDS, + "Wildcard": addr.SvcWildcard, + "CS_A": addr.SvcCS, + "DS_A": addr.SvcDS, + "Wildcard_A": addr.SvcWildcard, + "CS_M": addr.SvcCS.Multicast(), + "DS_M": addr.SvcDS.Multicast(), + "Wildcard_M": addr.SvcWildcard.Multicast(), + } + for src, svc := range valid { + t.Run(src, func(t *testing.T) { + v, err := addr.ParseSVC(src) + assert.NoError(t, err) + assert.Equal(t, svc, v) + }) + } +} + +func TestSVCString(t *testing.T) { + cases := map[addr.SVC]string{ + addr.SVC(0xABC): "", + addr.SvcCS: "CS", + addr.SvcCS.Multicast(): "CS_M", + addr.SvcDS: "DS", + addr.SvcDS.Multicast(): "DS_M", + addr.SvcWildcard: "Wildcard", + addr.SvcWildcard.Multicast(): "Wildcard_M", + } + for svc, expected := range cases { + t.Run(expected, func(t *testing.T) { + actual := svc.String() + assert.Equal(t, expected, actual) + }) + } +} diff --git a/pkg/daemon/apitypes.go b/pkg/daemon/apitypes.go index bdbdabe752..4b4564bef8 100644 --- a/pkg/daemon/apitypes.go +++ b/pkg/daemon/apitypes.go @@ -65,11 +65,11 @@ type TopoQuerier struct { } // UnderlayAnycast provides any address for the given svc type. -func (h TopoQuerier) UnderlayAnycast(ctx context.Context, svc addr.HostSVC) (*net.UDPAddr, error) { +func (h TopoQuerier) UnderlayAnycast(ctx context.Context, svc addr.SVC) (*net.UDPAddr, error) { if err := checkSVC(svc); err != nil { return nil, err } - r, err := h.Connector.SVCInfo(ctx, []addr.HostSVC{svc}) + r, err := h.Connector.SVCInfo(ctx, []addr.SVC{svc}) if err != nil { return nil, err } @@ -84,7 +84,7 @@ func (h TopoQuerier) UnderlayAnycast(ctx context.Context, svc addr.HostSVC) (*ne return &net.UDPAddr{IP: a.IP, Port: topology.EndhostPort, Zone: a.Zone}, nil } -func checkSVC(svc addr.HostSVC) error { +func checkSVC(svc addr.SVC) error { switch svc { case addr.SvcCS: return nil diff --git a/pkg/daemon/daemon.go b/pkg/daemon/daemon.go index 3fd60619ce..24d0b6b9f8 100644 --- a/pkg/daemon/daemon.go +++ b/pkg/daemon/daemon.go @@ -78,7 +78,7 @@ type Connector interface { // service types. If unset, a fresh (i.e., uncached) answer containing all // service types is returned. The reply is a map from service type to a list // of URIs of the service in the local AS. - SVCInfo(ctx context.Context, svcTypes []addr.HostSVC) (map[addr.HostSVC][]string, error) + SVCInfo(ctx context.Context, svcTypes []addr.SVC) (map[addr.SVC][]string, error) // RevNotification sends a RevocationInfo message to the daemon. RevNotification(ctx context.Context, revInfo *path_mgmt.RevInfo) error // DRKeyGetASHostKey requests a AS-Host Key from the daemon. diff --git a/pkg/daemon/grpc.go b/pkg/daemon/grpc.go index 2903a276c0..26ae049d7b 100644 --- a/pkg/daemon/grpc.go +++ b/pkg/daemon/grpc.go @@ -131,8 +131,8 @@ func (c grpcConn) IFInfo(ctx context.Context, func (c grpcConn) SVCInfo( ctx context.Context, - _ []addr.HostSVC, -) (map[addr.HostSVC][]string, error) { + _ []addr.SVC, +) (map[addr.SVC][]string, error) { client := sdpb.NewDaemonServiceClient(c.conn) response, err := client.Services(ctx, &sdpb.ServicesRequest{}) @@ -140,7 +140,7 @@ func (c grpcConn) SVCInfo( c.metrics.incServcies(err) return nil, err } - result := make(map[addr.HostSVC][]string) + result := make(map[addr.SVC][]string) for st, si := range response.Services { svc := topoServiceTypeToSVCAddr(topology.ServiceTypeFromString(st)) if svc == addr.SvcNone || len(si.Services) == 0 { @@ -315,7 +315,7 @@ func linkTypeFromPB(lt sdpb.LinkType) snet.LinkType { } } -func topoServiceTypeToSVCAddr(st topology.ServiceType) addr.HostSVC { +func topoServiceTypeToSVCAddr(st topology.ServiceType) addr.SVC { switch st { case topology.Control: return addr.SvcCS diff --git a/pkg/daemon/mock_daemon/mock.go b/pkg/daemon/mock_daemon/mock.go index 0bc1388f44..61c85508c3 100644 --- a/pkg/daemon/mock_daemon/mock.go +++ b/pkg/daemon/mock_daemon/mock.go @@ -175,10 +175,10 @@ func (mr *MockConnectorMockRecorder) RevNotification(arg0, arg1 interface{}) *go } // SVCInfo mocks base method. -func (m *MockConnector) SVCInfo(arg0 context.Context, arg1 []addr.HostSVC) (map[addr.HostSVC][]string, error) { +func (m *MockConnector) SVCInfo(arg0 context.Context, arg1 []addr.SVC) (map[addr.SVC][]string, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SVCInfo", arg0, arg1) - ret0, _ := ret[0].(map[addr.HostSVC][]string) + ret0, _ := ret[0].(map[addr.SVC][]string) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/pkg/drkey/generic/BUILD.bazel b/pkg/drkey/generic/BUILD.bazel index 1655a57ff9..afd06f2b2a 100644 --- a/pkg/drkey/generic/BUILD.bazel +++ b/pkg/drkey/generic/BUILD.bazel @@ -6,8 +6,10 @@ go_library( importpath = "github.com/scionproto/scion/pkg/drkey/generic", visibility = ["//visibility:public"], deps = [ + "//pkg/addr:go_default_library", "//pkg/drkey:go_default_library", "//pkg/private/serrors:go_default_library", + "//pkg/slayers:go_default_library", ], ) diff --git a/pkg/drkey/generic/generic.go b/pkg/drkey/generic/generic.go index d6e20cb524..d690180971 100644 --- a/pkg/drkey/generic/generic.go +++ b/pkg/drkey/generic/generic.go @@ -17,8 +17,10 @@ package generic import ( "encoding/binary" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/slayers" ) // Deriver implements the level 2/3 generic drkey derivation. @@ -32,13 +34,16 @@ func (d Deriver) DeriveASHost( key drkey.Key, ) (drkey.Key, error) { - host, err := drkey.HostAddrFromString(dstHost) + host, err := addr.ParseHost(dstHost) if err != nil { return drkey.Key{}, serrors.WrapStr("parsing dst host", err) } buf := make([]byte, 32) - len := d.serializeLevel2Input(buf, drkey.AsHost, d.Proto, host) - outKey, err := drkey.DeriveKey(buf[:len], key) + l, err := d.serializeLevel2Input(buf, drkey.AsHost, d.Proto, host) + if err != nil { + return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + } + outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err } @@ -48,13 +53,16 @@ func (d Deriver) DeriveHostAS( key drkey.Key, ) (drkey.Key, error) { - host, err := drkey.HostAddrFromString(srcHost) + host, err := addr.ParseHost(srcHost) if err != nil { return drkey.Key{}, serrors.WrapStr("parsing src host", err) } buf := make([]byte, 32) - len := d.serializeLevel2Input(buf, drkey.HostAS, d.Proto, host) - outKey, err := drkey.DeriveKey(buf[:len], key) + l, err := d.serializeLevel2Input(buf, drkey.HostAS, d.Proto, host) + if err != nil { + return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + } + outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err } @@ -64,13 +72,16 @@ func (d Deriver) DeriveHostHost( key drkey.Key, ) (drkey.Key, error) { - host, err := drkey.HostAddrFromString(dstHost) + host, err := addr.ParseHost(dstHost) if err != nil { return drkey.Key{}, serrors.WrapStr("deriving input H2H", err) } buf := make([]byte, 32) - len := drkey.SerializeHostHostInput(buf[:], host) - outKey, err := drkey.DeriveKey(buf[:len], key) + l, err := drkey.SerializeHostHostInput(buf[:], host) + if err != nil { + return drkey.Key{}, serrors.WrapStr("serializing drkey host-host input", err) + } + outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err } @@ -81,11 +92,14 @@ func (d Deriver) serializeLevel2Input( input []byte, derType drkey.KeyType, proto drkey.Protocol, - host drkey.HostAddr, -) int { + host addr.Host, +) (int, error) { - hostAddr := host.RawAddr - l := len(hostAddr) + typ, raw, err := slayers.PackAddr(host) + if err != nil { + return 0, serrors.WrapStr("packing host address", err) + } + l := len(raw) // Calculate a multiple of 16 such that the input fits in nrBlocks := (4+l-1)/16 + 1 @@ -94,9 +108,9 @@ func (d Deriver) serializeLevel2Input( _ = input[inputLength-1] input[0] = uint8(derType) binary.BigEndian.PutUint16(input[1:], uint16(proto)) - input[3] = uint8(host.AddrType & 0xF) - copy(input[4:], hostAddr) + input[3] = uint8(typ & 0xF) + copy(input[4:], raw) copy(input[4+l:inputLength], drkey.ZeroBlock[:]) - return inputLength + return inputLength, nil } diff --git a/pkg/drkey/protocol.go b/pkg/drkey/protocol.go index ee3fa596c8..b9469c0c8b 100644 --- a/pkg/drkey/protocol.go +++ b/pkg/drkey/protocol.go @@ -17,8 +17,6 @@ package drkey import ( "crypto/aes" "crypto/cipher" - "encoding/binary" - "net" "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/serrors" @@ -40,60 +38,16 @@ var ( ZeroBlock [aes.BlockSize]byte ) -// HostAddr is the address representation of a host as defined in the SCION header. -type HostAddr struct { - AddrType slayers.AddrType - RawAddr []byte -} - -// AddrToString returns the string representation of the HostAddr. -func (h *HostAddr) String() string { - switch h.AddrType { - case slayers.T4Ip: - return net.IP(h.RawAddr).String() - case slayers.T4Svc: - addr := addr.HostSVC(binary.BigEndian.Uint16(h.RawAddr[:addr.HostLenSVC])) - return addr.String() - case slayers.T16Ip: - return net.IP(h.RawAddr).String() - } - return "" -} - -// packtoHostAddr returns a HostAddr parsing a given address in string format. -func HostAddrFromString(host string) (HostAddr, error) { - // trying IP - ipAddr := addr.HostFromIPStr(host) - if ipAddr != nil { - if ip := ipAddr.IP().To4(); ip != nil { - return HostAddr{ - AddrType: slayers.T4Ip, - RawAddr: ip, - }, nil - } - return HostAddr{ - AddrType: slayers.T16Ip, - RawAddr: ipAddr.IP(), - }, nil - } - // trying SVC - svcAddr := addr.HostSVCFromString(host) - if svcAddr != addr.SvcNone { - return HostAddr{ - AddrType: slayers.T4Svc, - RawAddr: svcAddr.PackWithPad(2), - }, nil - } - return HostAddr{}, serrors.New("unsupported address", "addr", host) -} - // SerializeHostHostInput serializes the input for deriving a HostHost key, // as explained in // https://docs.scion.org/en/latest/cryptography/drkey.html#level-derivation. // This derivation is common for Generic and Specific derivations. -func SerializeHostHostInput(input []byte, host HostAddr) int { - hostAddr := host.RawAddr - l := len(hostAddr) +func SerializeHostHostInput(input []byte, host addr.Host) (int, error) { + typ, raw, err := slayers.PackAddr(host) + if err != nil { + return 0, serrors.WrapStr("packing host address", err) + } + l := len(raw) // Calculate a multiple of 16 such that the input fits in nrBlocks := (2+l-1)/16 + 1 @@ -102,11 +56,11 @@ func SerializeHostHostInput(input []byte, host HostAddr) int { _ = input[inputLength-1] input[0] = uint8(HostHost) - input[1] = uint8(host.AddrType & 0xF) - copy(input[2:], hostAddr) + input[1] = uint8(typ & 0xF) + copy(input[2:], raw) copy(input[2+l:inputLength], ZeroBlock[:]) - return inputLength + return inputLength, nil } // DeriveKey derives the following key given an input and a higher-level key, diff --git a/pkg/drkey/specific/BUILD.bazel b/pkg/drkey/specific/BUILD.bazel index c3316a6a9e..baad2183ac 100644 --- a/pkg/drkey/specific/BUILD.bazel +++ b/pkg/drkey/specific/BUILD.bazel @@ -9,6 +9,7 @@ go_library( "//pkg/addr:go_default_library", "//pkg/drkey:go_default_library", "//pkg/private/serrors:go_default_library", + "//pkg/slayers:go_default_library", ], ) diff --git a/pkg/drkey/specific/specific.go b/pkg/drkey/specific/specific.go index b156b2f6cb..88a585a28b 100644 --- a/pkg/drkey/specific/specific.go +++ b/pkg/drkey/specific/specific.go @@ -21,6 +21,7 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/slayers" ) // SpecificDeriver implements the specific drkey derivation. @@ -44,37 +45,46 @@ func (d Deriver) DeriveASHost( key drkey.Key, ) (drkey.Key, error) { - host, err := drkey.HostAddrFromString(dstHost) + host, err := addr.ParseHost(dstHost) if err != nil { return drkey.Key{}, serrors.WrapStr("parsing dst host", err) } buf := make([]byte, 32) - len := d.serializeLevel2Input(buf, drkey.AsHost, host) - outKey, err := drkey.DeriveKey(buf[:len], key) + l, err := d.serializeLevel2Input(buf, drkey.AsHost, host) + if err != nil { + return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + } + outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err } // DeriveHostAS returns the HostAS derived key. func (p Deriver) DeriveHostAS(srcHost string, key drkey.Key) (drkey.Key, error) { - host, err := drkey.HostAddrFromString(srcHost) + host, err := addr.ParseHost(srcHost) if err != nil { return drkey.Key{}, serrors.WrapStr("parsing src host", err) } buf := make([]byte, 32) - len := p.serializeLevel2Input(buf, drkey.HostAS, host) - outKey, err := drkey.DeriveKey(buf[:len], key) + l, err := p.serializeLevel2Input(buf, drkey.HostAS, host) + if err != nil { + return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + } + outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err } // DeriveHostHost returns the HostHost derived key. func (d Deriver) DeriveHostHost(dstHost string, key drkey.Key) (drkey.Key, error) { - host, err := drkey.HostAddrFromString(dstHost) + host, err := addr.ParseHost(dstHost) if err != nil { return drkey.Key{}, serrors.WrapStr("deriving input H2H", err) } buf := make([]byte, 32) - len := drkey.SerializeHostHostInput(buf, host) - outKey, err := drkey.DeriveKey(buf[:len], key) + l, err := drkey.SerializeHostHostInput(buf, host) + if err != nil { + return drkey.Key{}, serrors.WrapStr("serializing drkey host-host input", err) + } + outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err } @@ -84,11 +94,14 @@ func (d Deriver) DeriveHostHost(dstHost string, key drkey.Key) (drkey.Key, error func (d Deriver) serializeLevel2Input( input []byte, derType drkey.KeyType, - host drkey.HostAddr, -) int { + host addr.Host, +) (int, error) { - hostAddr := host.RawAddr - l := len(hostAddr) + typ, raw, err := slayers.PackAddr(host) + if err != nil { + return 0, serrors.WrapStr("packing host address", err) + } + l := len(raw) // Calculate a multiple of 16 such that the input fits in nrBlocks := (2+l-1)/16 + 1 @@ -96,11 +109,11 @@ func (d Deriver) serializeLevel2Input( _ = input[inputLength-1] input[0] = uint8(derType) - input[1] = uint8(host.AddrType & 0xF) - copy(input[2:], hostAddr) + input[1] = uint8(typ & 0xF) + copy(input[2:], raw) copy(input[2+l:inputLength], drkey.ZeroBlock[:]) - return inputLength + return inputLength, nil } // serializeLevel1Input serializes the input for a Level1 key, diff --git a/pkg/experimental/epic/BUILD.bazel b/pkg/experimental/epic/BUILD.bazel index 753ce3b34e..15dc154e93 100644 --- a/pkg/experimental/epic/BUILD.bazel +++ b/pkg/experimental/epic/BUILD.bazel @@ -24,6 +24,7 @@ go_test( ], embed = [":go_default_library"], deps = [ + "//pkg/addr:go_default_library", "//pkg/private/xtest:go_default_library", "//pkg/slayers:go_default_library", "//pkg/slayers/path/epic:go_default_library", diff --git a/pkg/experimental/epic/epic_test.go b/pkg/experimental/epic/epic_test.go index 6de95ac237..6d7bb32843 100644 --- a/pkg/experimental/epic/epic_test.go +++ b/pkg/experimental/epic/epic_test.go @@ -15,13 +15,13 @@ package epic_test import ( - "net" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/scionproto/scion/pkg/addr" libepic "github.com/scionproto/scion/pkg/experimental/epic" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -384,8 +384,7 @@ func createScionCmnAddrHdr(t *testing.T) *slayers.SCION { SrcIA: xtest.MustParseIA("2-ff00:0:222"), PayloadLen: 120, } - ip4Addr := &net.IPAddr{IP: net.ParseIP("10.0.0.100")} - require.NoError(t, spkt.SetSrcAddr(ip4Addr)) + _ = spkt.SetSrcAddr(addr.MustParseHost("10.0.0.100")) return spkt } diff --git a/pkg/experimental/hiddenpath/beaconwriter_test.go b/pkg/experimental/hiddenpath/beaconwriter_test.go index 95c0891077..3cd383fa2c 100644 --- a/pkg/experimental/hiddenpath/beaconwriter_test.go +++ b/pkg/experimental/hiddenpath/beaconwriter_test.go @@ -308,7 +308,7 @@ func (m addrMatcher) Matches(other interface{}) bool { if !m.svc.IA.Equal(svc.IA) { return false } - if !m.svc.SVC.Equal(svc.SVC) { + if m.svc.SVC != svc.SVC { return false } return true diff --git a/pkg/grpc/BUILD.bazel b/pkg/grpc/BUILD.bazel index fc6a2b1c46..e82853d5ff 100644 --- a/pkg/grpc/BUILD.bazel +++ b/pkg/grpc/BUILD.bazel @@ -33,6 +33,7 @@ go_test( deps = [ ":go_default_library", "//pkg/addr:go_default_library", + "//pkg/snet:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", "@com_github_stretchr_testify//require:go_default_library", "@org_golang_google_grpc//:go_default_library", diff --git a/pkg/grpc/dialer.go b/pkg/grpc/dialer.go index 952870036e..03edee33ad 100644 --- a/pkg/grpc/dialer.go +++ b/pkg/grpc/dialer.go @@ -90,20 +90,21 @@ func (SimpleDialer) Dial(ctx context.Context, address net.Addr) (*grpc.ClientCon // TCPDialer dials a gRPC connection over TCP. This dialer is meant to be used // for AS internal communication, and is capable of resolving svc addresses. type TCPDialer struct { - SvcResolver func(addr.HostSVC) []resolver.Address + SvcResolver func(addr.SVC) []resolver.Address } // Dial dials a gRPC connection over TCP. It resolves svc addresses. func (t *TCPDialer) Dial(ctx context.Context, dst net.Addr) (*grpc.ClientConn, error) { - if v, ok := dst.(addr.HostSVC); ok { - targets := t.SvcResolver(v) + if v, ok := dst.(*snet.SVCAddr); ok { + // XXX(matzf) is this really needed!? + targets := t.SvcResolver(v.SVC) if len(targets) == 0 { return nil, serrors.New("could not resolve") } r := manual.NewBuilderWithScheme("svc") r.InitialState(resolver.State{Addresses: targets}) - return grpc.DialContext(ctx, r.Scheme()+":///"+v.BaseString(), + return grpc.DialContext(ctx, r.Scheme()+":///"+v.SVC.BaseString(), grpc.WithDefaultServiceConfig(`{"loadBalancingConfig": [{"round_robin":{}}]}`), grpc.WithInsecure(), grpc.WithResolvers(r), diff --git a/pkg/grpc/dialer_test.go b/pkg/grpc/dialer_test.go index 533f92ebdb..0c62605255 100644 --- a/pkg/grpc/dialer_test.go +++ b/pkg/grpc/dialer_test.go @@ -31,6 +31,7 @@ import ( "github.com/scionproto/scion/pkg/addr" libgrpc "github.com/scionproto/scion/pkg/grpc" + "github.com/scionproto/scion/pkg/snet" ) func TestTCPDial(t *testing.T) { @@ -62,22 +63,22 @@ func TestTCPDial(t *testing.T) { t.Run("cases", func(t *testing.T) { testCases := map[string]struct { - svcResolve func(*testing.T, addr.HostSVC) []resolver.Address + svcResolve func(*testing.T, addr.SVC) []resolver.Address dst net.Addr assertDialError assert.ErrorAssertionFunc assertCallError assert.ErrorAssertionFunc }{ "valid tcp address": { dst: lis.Addr(), - svcResolve: func(*testing.T, addr.HostSVC) []resolver.Address { + svcResolve: func(*testing.T, addr.SVC) []resolver.Address { return nil }, assertDialError: assert.NoError, assertCallError: assert.NoError, }, "valid cs svc address": { - dst: addr.SvcCS, - svcResolve: func(*testing.T, addr.HostSVC) []resolver.Address { + dst: &snet.SVCAddr{SVC: addr.SvcCS}, + svcResolve: func(*testing.T, addr.SVC) []resolver.Address { return []resolver.Address{ {Addr: lis.Addr().String()}, {Addr: getUnusedAddr(t)}, @@ -87,8 +88,8 @@ func TestTCPDial(t *testing.T) { assertCallError: assert.NoError, }, "valid cs svc address second": { - dst: addr.SvcCS, - svcResolve: func(*testing.T, addr.HostSVC) []resolver.Address { + dst: &snet.SVCAddr{SVC: addr.SvcCS}, + svcResolve: func(*testing.T, addr.SVC) []resolver.Address { return []resolver.Address{ {Addr: getUnusedAddr(t)}, {Addr: lis.Addr().String()}, @@ -98,8 +99,8 @@ func TestTCPDial(t *testing.T) { assertCallError: assert.NoError, }, "valid, one server with no gRPC": { - dst: addr.SvcCS, - svcResolve: func(*testing.T, addr.HostSVC) []resolver.Address { + dst: &snet.SVCAddr{SVC: addr.SvcCS}, + svcResolve: func(*testing.T, addr.SVC) []resolver.Address { return []resolver.Address{ {Addr: noGRPCLis.Addr().String()}, {Addr: lis.Addr().String()}, @@ -109,8 +110,8 @@ func TestTCPDial(t *testing.T) { assertCallError: assert.NoError, }, "invalid": { - dst: addr.SvcCS, - svcResolve: func(*testing.T, addr.HostSVC) []resolver.Address { + dst: &snet.SVCAddr{SVC: addr.SvcCS}, + svcResolve: func(*testing.T, addr.SVC) []resolver.Address { return nil }, assertDialError: assert.Error, @@ -131,7 +132,7 @@ func TestTCPDial(t *testing.T) { defer cancel() dialer := libgrpc.TCPDialer{ - SvcResolver: func(svc addr.HostSVC) []resolver.Address { + SvcResolver: func(svc addr.SVC) []resolver.Address { return tc.svcResolve(t, svc) }, } diff --git a/pkg/slayers/export_test.go b/pkg/slayers/export_test.go index dcdec7a7d1..8897b970f0 100644 --- a/pkg/slayers/export_test.go +++ b/pkg/slayers/export_test.go @@ -19,8 +19,6 @@ package slayers type TLVOption = tlvOption var ( - PackAddr = packAddr - ParseAddr = parseAddr SerializeTLVOptions = serializeTLVOptions ) diff --git a/pkg/slayers/scion.go b/pkg/slayers/scion.go index 86343d758e..7e24772f14 100644 --- a/pkg/slayers/scion.go +++ b/pkg/slayers/scion.go @@ -16,7 +16,7 @@ package slayers import ( "encoding/binary" - "net" + "net/netip" "github.com/google/gopacket" @@ -349,64 +349,66 @@ func scionNextLayerTypeL4(t L4ProtocolType) gopacket.LayerType { } } -// DstAddr parses the destination address into a net.Addr. The returned net.Addr references data -// from the underlaying layer data. Changing the net.Addr object might lead to inconsistent layer -// information and thus should be treated read-only. Instead, SetDstAddr should be used to update -// the destination address. -func (s *SCION) DstAddr() (net.Addr, error) { - return parseAddr(s.DstAddrType, s.RawDstAddr) +// DstAddr parses the destination address into a addr.Host. +func (s *SCION) DstAddr() (addr.Host, error) { + return ParseAddr(s.DstAddrType, s.RawDstAddr) } -// SrcAddr parses the source address into a net.Addr. The returned net.Addr references data from the -// underlaying layer data. Changing the net.Addr object might lead to inconsistent layer information -// and thus should be treated read-only. Instead, SetDstAddr should be used to update the source -// address. -func (s *SCION) SrcAddr() (net.Addr, error) { - return parseAddr(s.SrcAddrType, s.RawSrcAddr) +// SrcAddr parses the source address into a addr.Host. +func (s *SCION) SrcAddr() (addr.Host, error) { + return ParseAddr(s.SrcAddrType, s.RawSrcAddr) } // SetDstAddr sets the destination address and updates the DstAddrType field accordingly. -// SetDstAddr takes ownership of dst and callers should not write to it after calling SetDstAddr. -// Changes to dst might leave the layer in an inconsistent state. -func (s *SCION) SetDstAddr(dst net.Addr) error { +func (s *SCION) SetDstAddr(dst addr.Host) error { var err error - s.DstAddrType, s.RawDstAddr, err = packAddr(dst) + s.DstAddrType, s.RawDstAddr, err = PackAddr(dst) return err } // SetSrcAddr sets the source address and updates the DstAddrType field accordingly. -// SetSrcAddr takes ownership of src and callers should not write to it after calling SetSrcAddr. -// Changes to src might leave the layer in an inconsistent state. -func (s *SCION) SetSrcAddr(src net.Addr) error { +func (s *SCION) SetSrcAddr(src addr.Host) error { var err error - s.SrcAddrType, s.RawSrcAddr, err = packAddr(src) + s.SrcAddrType, s.RawSrcAddr, err = PackAddr(src) return err } -func parseAddr(addrType AddrType, raw []byte) (net.Addr, error) { +func ParseAddr(addrType AddrType, raw []byte) (addr.Host, error) { switch addrType { case T4Ip: - return &net.IPAddr{IP: net.IP(raw)}, nil + var raw4 [4]byte + copy(raw4[:], raw) + return addr.HostIP(netip.AddrFrom4(raw4)), nil case T4Svc: - return addr.HostSVC(binary.BigEndian.Uint16(raw[:addr.HostLenSVC])), nil + svc := addr.SVC(binary.BigEndian.Uint16(raw[:2])) + return addr.HostSVC(svc), nil case T16Ip: - return &net.IPAddr{IP: net.IP(raw)}, nil + var raw16 [16]byte + copy(raw16[:], raw) + return addr.HostIP(netip.AddrFrom16(raw16)), nil } - return nil, serrors.New("unsupported address type/length combination", + return addr.Host{}, serrors.New("unsupported address type/length combination", "type", addrType, "len", addrType.Length()) } -func packAddr(hostAddr net.Addr) (AddrType, []byte, error) { - switch a := hostAddr.(type) { - case *net.IPAddr: - if ip := a.IP.To4(); ip != nil { - return T4Ip, ip, nil +func PackAddr(host addr.Host) (AddrType, []byte, error) { + switch host.Type() { + case addr.HostTypeIP: + ip := host.IP() + if !ip.IsValid() { + break } - return T16Ip, a.IP, nil - case addr.HostSVC: - return T4Svc, a.PackWithPad(2), nil + t := T4Ip + if ip.Is6() { + t = T16Ip + } + return t, ip.AsSlice(), nil + case addr.HostTypeSVC: + raw := make([]byte, 4) + binary.BigEndian.PutUint16(raw, uint16(host.SVC())) + return T4Svc, raw, nil } - return 0, nil, serrors.New("unsupported address", "addr", hostAddr) + return 0, nil, serrors.New("unsupported address", "addr", host) } // AddrHdrLen returns the length of the address header (destination and source ISD-AS-Host triples) diff --git a/pkg/slayers/scion_test.go b/pkg/slayers/scion_test.go index 4ee6046686..06d4967551 100644 --- a/pkg/slayers/scion_test.go +++ b/pkg/slayers/scion_test.go @@ -17,7 +17,6 @@ package slayers_test import ( "encoding/binary" "fmt" - "net" "testing" "github.com/google/gopacket" @@ -34,9 +33,9 @@ import ( ) var ( - ip6Addr = &net.IPAddr{IP: net.ParseIP("2001:db8::68")} - ip4Addr = &net.IPAddr{IP: net.ParseIP("10.0.0.100").To4()} - svcAddr = addr.HostSVCFromString("Wildcard") + ip6Addr = addr.MustParseHost("2001:db8::68") + ip4Addr = addr.MustParseHost("10.0.0.100") + svcAddr = addr.MustParseHost("Wildcard") rawPath = func() []byte { return []byte("\x00\x00\x20\x80\x00\x00\x01\x11\x00\x00\x01\x00\x01\x00\x02\x22\x00" + "\x00\x01\x00\x00\x3f\x00\x01\x00\x00\x01\x02\x03\x04\x05\x06\x00\x3f\x00\x03\x00" + @@ -57,10 +56,10 @@ func TestSCIONLayerString(t *testing.T) { DstIA: ia1, SrcIA: ia2, } - if err := sc.SetDstAddr(&net.IPAddr{IP: net.ParseIP("1.2.3.4").To4()}); err != nil { + if err := sc.SetDstAddr(addr.MustParseHost("1.2.3.4")); err != nil { assert.NoError(t, err) } - if err := sc.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("5.6.7.8").To4()}); err != nil { + if err := sc.SetSrcAddr(addr.MustParseHost("5.6.7.8")); err != nil { assert.NoError(t, err) } @@ -256,8 +255,8 @@ func TestSCIONSerializeLengthCheck(t *testing.T) { func TestSetAndGetAddr(t *testing.T) { testCases := map[string]struct { - srcAddr net.Addr - dstAddr net.Addr + srcAddr addr.Host + dstAddr addr.Host }{ "set/get IPv4/IPv4": { srcAddr: ip4Addr, @@ -293,22 +292,15 @@ func TestSetAndGetAddr(t *testing.T) { gotDst, err := s.DstAddr() assert.NoError(t, err) - equalAddr := func(t *testing.T, expected, actual net.Addr) { - if _, ok := expected.(*net.IPAddr); !ok { - assert.Equal(t, expected, actual) - return - } - assert.True(t, expected.(*net.IPAddr).IP.Equal(actual.(*net.IPAddr).IP)) - } - equalAddr(t, tc.srcAddr, gotSrc) - equalAddr(t, tc.dstAddr, gotDst) + assert.Equal(t, tc.srcAddr, gotSrc) + assert.Equal(t, tc.dstAddr, gotDst) }) } } func TestPackAddr(t *testing.T) { testCases := map[string]struct { - addr net.Addr + addr addr.Host addrType slayers.AddrType rawAddr []byte errorFunc assert.ErrorAssertionFunc @@ -316,19 +308,19 @@ func TestPackAddr(t *testing.T) { "pack IPv4": { addr: ip4Addr, addrType: slayers.T4Ip, - rawAddr: []byte(ip4Addr.IP), + rawAddr: ip4Addr.IP().AsSlice(), errorFunc: assert.NoError, }, "pack IPv6": { addr: ip6Addr, addrType: slayers.T16Ip, - rawAddr: []byte(ip6Addr.IP), + rawAddr: ip6Addr.IP().AsSlice(), errorFunc: assert.NoError, }, "pack SVC": { - addr: svcAddr, + addr: addr.HostSVC(addr.SvcWildcard), addrType: slayers.T4Svc, - rawAddr: svcAddr.PackWithPad(2), + rawAddr: []byte{0, 0x10, 0, 0}, errorFunc: assert.NoError, }, } @@ -350,31 +342,31 @@ func TestParseAddr(t *testing.T) { testCases := map[string]struct { addrType slayers.AddrType rawAddr []byte - want net.Addr + want addr.Host errorFunc assert.ErrorAssertionFunc }{ "parse IPv4": { addrType: slayers.T4Ip, - rawAddr: []byte(ip4Addr.IP.To4()), + rawAddr: ip4Addr.IP().AsSlice(), want: ip4Addr, errorFunc: assert.NoError, }, "parse IPv6": { addrType: slayers.T16Ip, - rawAddr: []byte(ip6Addr.IP), + rawAddr: ip6Addr.IP().AsSlice(), want: ip6Addr, errorFunc: assert.NoError, }, "parse SVC": { addrType: slayers.T4Svc, - rawAddr: svcAddr.PackWithPad(2), - want: svcAddr, + rawAddr: []byte{0, 0x10, 0, 0}, + want: addr.HostSVC(addr.SvcWildcard), errorFunc: assert.NoError, }, "parse unknown type": { addrType: 0b0001, // T=0,Len=8 rawAddr: []byte{0, 0, 0, 0, 0, 0, 0, 0}, - want: nil, + want: addr.Host{}, errorFunc: assert.Error, }, } @@ -547,9 +539,9 @@ func TestSCIONComputeChecksum(t *testing.T) { SrcIA: xtest.MustParseIA("1-ff00:0:110"), DstIA: xtest.MustParseIA("1-ff00:0:112"), } - err := s.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}) + err := s.SetSrcAddr(addr.MustParseHost("174.16.4.1")) require.NoError(t, err) - err = s.SetDstAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.2").To4()}) + err = s.SetDstAddr(addr.MustParseHost("172.16.4.2")) require.NoError(t, err) return s }, @@ -563,9 +555,9 @@ func TestSCIONComputeChecksum(t *testing.T) { SrcIA: xtest.MustParseIA("1-ff00:0:110"), DstIA: xtest.MustParseIA("1-ff00:0:112"), } - err := s.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}) + err := s.SetSrcAddr(addr.MustParseHost("174.16.4.1")) require.NoError(t, err) - err = s.SetDstAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.2").To4()}) + err = s.SetDstAddr(addr.MustParseHost("172.16.4.2")) require.NoError(t, err) return s }, @@ -579,9 +571,9 @@ func TestSCIONComputeChecksum(t *testing.T) { SrcIA: xtest.MustParseIA("1-ff00:0:110"), DstIA: xtest.MustParseIA("1-ff00:0:112"), } - err := s.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}) + err := s.SetSrcAddr(addr.MustParseHost("174.16.4.1")) require.NoError(t, err) - err = s.SetDstAddr(&net.IPAddr{IP: net.ParseIP("dead::beef")}) + err = s.SetDstAddr(addr.MustParseHost("dead::beef")) require.NoError(t, err) return s }, @@ -595,9 +587,9 @@ func TestSCIONComputeChecksum(t *testing.T) { SrcIA: xtest.MustParseIA("1-ff00:0:110"), DstIA: xtest.MustParseIA("1-ff00:0:112"), } - err := s.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}) + err := s.SetSrcAddr(addr.MustParseHost("174.16.4.1")) require.NoError(t, err) - err = s.SetDstAddr(addr.SvcCS) + err = s.SetDstAddr(addr.HostSVC(addr.SvcCS)) require.NoError(t, err) return s }, diff --git a/pkg/slayers/scmp_test.go b/pkg/slayers/scmp_test.go index c8881e8d94..dfeceb54ff 100644 --- a/pkg/slayers/scmp_test.go +++ b/pkg/slayers/scmp_test.go @@ -17,13 +17,13 @@ package slayers_test import ( "bytes" "fmt" - "net" "testing" "github.com/google/gopacket" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" ) @@ -82,9 +82,9 @@ func TestSCMPSerializeTo(t *testing.T) { SrcIA: xtest.MustParseIA("1-ff00:0:1"), DstIA: xtest.MustParseIA("1-ff00:0:4"), } - err := scnL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}) + err := scnL.SetDstAddr(addr.MustParseHost("174.16.4.1")) require.NoError(t, err) - err = scnL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.3")}) + err = scnL.SetSrcAddr(addr.MustParseHost("172.16.4.3")) require.NoError(t, err) testCases := map[string]struct { @@ -513,9 +513,9 @@ func TestSCMP(t *testing.T) { SrcIA: xtest.MustParseIA("1-ff00:0:1"), DstIA: xtest.MustParseIA("1-ff00:0:4"), } - err := scnL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}) + err := scnL.SetDstAddr(addr.MustParseHost("174.16.4.1")) assert.NoError(t, err) - err = scnL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.3").To4()}) + err = scnL.SetSrcAddr(addr.MustParseHost("172.16.4.3")) require.NoError(t, err) opts := gopacket.SerializeOptions{ComputeChecksums: true} diff --git a/pkg/snet/addrutil/addrutil.go b/pkg/snet/addrutil/addrutil.go index 60595f91ba..aa6e65c270 100644 --- a/pkg/snet/addrutil/addrutil.go +++ b/pkg/snet/addrutil/addrutil.go @@ -40,7 +40,7 @@ type Pather struct { } // GetPath computes the remote address with a path based on the provided segment. -func (p Pather) GetPath(svc addr.HostSVC, ps *seg.PathSegment) (*snet.SVCAddr, error) { +func (p Pather) GetPath(svc addr.SVC, ps *seg.PathSegment) (*snet.SVCAddr, error) { if len(ps.ASEntries) == 0 { return nil, serrors.New("empty path") } diff --git a/pkg/snet/base.go b/pkg/snet/base.go index 2d7c84fc7e..a06f956f0c 100644 --- a/pkg/snet/base.go +++ b/pkg/snet/base.go @@ -27,7 +27,7 @@ type scionConnBase struct { remote *UDPAddr // svc address - svc addr.HostSVC + svc addr.SVC // Reference to SCION networking context scionNet *SCIONNetwork @@ -41,6 +41,6 @@ func (c *scionConnBase) RemoteAddr() net.Addr { return c.remote } -func (c *scionConnBase) SVC() addr.HostSVC { +func (c *scionConnBase) SVC() addr.SVC { return c.svc } diff --git a/pkg/snet/dispatcher.go b/pkg/snet/dispatcher.go index 8e1e6c87de..bfc1180a09 100644 --- a/pkg/snet/dispatcher.go +++ b/pkg/snet/dispatcher.go @@ -34,7 +34,7 @@ import ( // fine-grained control over header fields. type PacketDispatcherService interface { Register(ctx context.Context, ia addr.IA, registration *net.UDPAddr, - svc addr.HostSVC) (PacketConn, uint16, error) + svc addr.SVC) (PacketConn, uint16, error) } var _ PacketDispatcherService = (*DefaultPacketDispatcherService)(nil) @@ -53,7 +53,7 @@ type DefaultPacketDispatcherService struct { } func (s *DefaultPacketDispatcherService) Register(ctx context.Context, ia addr.IA, - registration *net.UDPAddr, svc addr.HostSVC) (PacketConn, uint16, error) { + registration *net.UDPAddr, svc addr.SVC) (PacketConn, uint16, error) { rconn, port, err := s.Dispatcher.Register(ctx, ia, registration, svc) if err != nil { diff --git a/pkg/snet/interface.go b/pkg/snet/interface.go index 37f704608d..343ec1a442 100644 --- a/pkg/snet/interface.go +++ b/pkg/snet/interface.go @@ -24,7 +24,7 @@ import ( type Network interface { Listen(ctx context.Context, network string, listen *net.UDPAddr, - svc addr.HostSVC) (*Conn, error) + svc addr.SVC) (*Conn, error) Dial(ctx context.Context, network string, listen *net.UDPAddr, remote *UDPAddr, - svc addr.HostSVC) (*Conn, error) + svc addr.SVC) (*Conn, error) } diff --git a/pkg/snet/mock_snet/mock.go b/pkg/snet/mock_snet/mock.go index fd52a212cd..181ac9a929 100644 --- a/pkg/snet/mock_snet/mock.go +++ b/pkg/snet/mock_snet/mock.go @@ -40,7 +40,7 @@ func (m *MockPacketDispatcherService) EXPECT() *MockPacketDispatcherServiceMockR } // Register mocks base method. -func (m *MockPacketDispatcherService) Register(arg0 context.Context, arg1 addr.IA, arg2 *net.UDPAddr, arg3 addr.HostSVC) (snet.PacketConn, uint16, error) { +func (m *MockPacketDispatcherService) Register(arg0 context.Context, arg1 addr.IA, arg2 *net.UDPAddr, arg3 addr.SVC) (snet.PacketConn, uint16, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Register", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(snet.PacketConn) @@ -79,7 +79,7 @@ func (m *MockNetwork) EXPECT() *MockNetworkMockRecorder { } // Dial mocks base method. -func (m *MockNetwork) Dial(arg0 context.Context, arg1 string, arg2 *net.UDPAddr, arg3 *snet.UDPAddr, arg4 addr.HostSVC) (*snet.Conn, error) { +func (m *MockNetwork) Dial(arg0 context.Context, arg1 string, arg2 *net.UDPAddr, arg3 *snet.UDPAddr, arg4 addr.SVC) (*snet.Conn, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Dial", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(*snet.Conn) @@ -94,7 +94,7 @@ func (mr *MockNetworkMockRecorder) Dial(arg0, arg1, arg2, arg3, arg4 interface{} } // Listen mocks base method. -func (m *MockNetwork) Listen(arg0 context.Context, arg1 string, arg2 *net.UDPAddr, arg3 addr.HostSVC) (*snet.Conn, error) { +func (m *MockNetwork) Listen(arg0 context.Context, arg1 string, arg2 *net.UDPAddr, arg3 addr.SVC) (*snet.Conn, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Listen", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(*snet.Conn) diff --git a/pkg/snet/packet.go b/pkg/snet/packet.go index 7289cc5d91..6444d34d03 100644 --- a/pkg/snet/packet.go +++ b/pkg/snet/packet.go @@ -15,8 +15,6 @@ package snet import ( - "net" - "github.com/google/gopacket" "github.com/scionproto/scion/pkg/addr" @@ -370,20 +368,12 @@ func (p *Packet) Decode() error { if err != nil { return serrors.WrapStr("extracting destination address", err) } - dstHost, err := netAddrToHostAddr(dstAddr) - if err != nil { - return serrors.WrapStr("converting dst address to HostAddr", err) - } srcAddr, err := scionLayer.SrcAddr() if err != nil { return serrors.WrapStr("extracting source address", err) } - srcHost, err := netAddrToHostAddr(srcAddr) - if err != nil { - return serrors.WrapStr("converting src address to HostAddr", err) - } - p.Destination = SCIONAddress{IA: scionLayer.DstIA, Host: dstHost} - p.Source = SCIONAddress{IA: scionLayer.SrcIA, Host: srcHost} + p.Destination = SCIONAddress{IA: scionLayer.DstIA, Host: dstAddr} + p.Source = SCIONAddress{IA: scionLayer.SrcIA, Host: srcAddr} rpath := RawPath{ PathType: scionLayer.Path.Type(), @@ -549,20 +539,10 @@ func (p *Packet) Serialize() error { scionLayer.FlowID = 1 scionLayer.DstIA = p.Destination.IA scionLayer.SrcIA = p.Source.IA - netDstAddr, err := hostAddrToNetAddr(p.Destination.Host) - if err != nil { - return serrors.WrapStr("converting destination addr.HostAddr to net.Addr", err, - "address", p.Destination.Host) - } - if err := scionLayer.SetDstAddr(netDstAddr); err != nil { + if err := scionLayer.SetDstAddr(p.Destination.Host); err != nil { return serrors.WrapStr("setting destination address", err) } - netSrcAddr, err := hostAddrToNetAddr(p.Source.Host) - if err != nil { - return serrors.WrapStr("converting source addr.HostAddr to net.Addr", err, - "address", p.Source.Host) - } - if err := scionLayer.SetSrcAddr(netSrcAddr); err != nil { + if err := scionLayer.SetSrcAddr(p.Source.Host); err != nil { return serrors.WrapStr("setting source address", err) } @@ -612,25 +592,3 @@ type PacketInfo struct { // Payload is the Payload of the message. Payload Payload } - -func netAddrToHostAddr(a net.Addr) (addr.HostAddr, error) { - switch aImpl := a.(type) { - case *net.IPAddr: - return addr.HostFromIP(aImpl.IP), nil - case addr.HostSVC: - return aImpl, nil - default: - return nil, serrors.New("address not supported", "a", a) - } -} - -func hostAddrToNetAddr(a addr.HostAddr) (net.Addr, error) { - switch aImpl := a.(type) { - case addr.HostSVC: - return aImpl, nil - case addr.HostIPv4, addr.HostIPv6: - return &net.IPAddr{IP: aImpl.IP()}, nil - default: - return nil, serrors.New("address not supported", "a", a) - } -} diff --git a/pkg/snet/packet_conn.go b/pkg/snet/packet_conn.go index 7dfd027487..6e257f3095 100644 --- a/pkg/snet/packet_conn.go +++ b/pkg/snet/packet_conn.go @@ -15,7 +15,6 @@ package snet import ( - "fmt" "net" "time" @@ -82,14 +81,7 @@ type SCMPExternalInterfaceDownL4 struct { func (SCMPExternalInterfaceDownL4) closed() {} // SCIONAddress is the fully-specified address of a host. -type SCIONAddress struct { - IA addr.IA - Host addr.HostAddr -} - -func (a SCIONAddress) String() string { - return fmt.Sprintf("%v,%s", a.IA, a.Host.String()) -} +type SCIONAddress = addr.Addr type SCIONPacketConnMetrics struct { // Closes records the total number of Close calls on the connection. diff --git a/pkg/snet/packet_test.go b/pkg/snet/packet_test.go index f0d32ef55a..ebaf1f55f9 100644 --- a/pkg/snet/packet_test.go +++ b/pkg/snet/packet_test.go @@ -15,7 +15,6 @@ package snet_test import ( - "net" "testing" "github.com/stretchr/testify/assert" @@ -55,11 +54,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.OneHop{}, Payload: snet.UDPPayload{ @@ -73,11 +72,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.SCION{ Raw: rawSP(), @@ -93,11 +92,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.SCION{ Raw: rawSP(), @@ -113,11 +112,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.SCION{ Raw: rawSP(), @@ -133,11 +132,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.SCION{ Raw: rawSP(), @@ -153,11 +152,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.SCION{ Raw: rawSP(), @@ -174,11 +173,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.SCION{ Raw: rawSP(), @@ -196,11 +195,11 @@ func TestPacketSerializeDecodeLoop(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1").To4()), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.SCION{ Raw: rawSP(), @@ -268,11 +267,11 @@ func TestPacketSerialize(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1")), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.OneHop{}, Payload: snet.UDPPayload{ @@ -289,11 +288,11 @@ func TestPacketSerialize(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1")), + Host: addr.MustParseHost("127.0.0.1"), }, Payload: snet.UDPPayload{ SrcPort: 25, @@ -313,11 +312,11 @@ func TestPacketSerialize(t *testing.T) { PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:110"), - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), }, Source: snet.SCIONAddress{ IA: xtest.MustParseIA("1-ff00:0:112"), - Host: addr.HostIPv4(net.ParseIP("127.0.0.1")), + Host: addr.MustParseHost("127.0.0.1"), }, Path: snetpath.OneHop{}, }, diff --git a/pkg/snet/reader.go b/pkg/snet/reader.go index ca4b87dde5..d09ff6926f 100644 --- a/pkg/snet/reader.go +++ b/pkg/snet/reader.go @@ -97,10 +97,10 @@ func (c *scionConnReader) read(b []byte) (int, *UDPAddr, error) { // https://github.com/scionproto/scion/issues/1659. remote := &UDPAddr{ IA: pkt.Source.IA, - Host: CopyUDPAddr(&net.UDPAddr{ - IP: pkt.Source.Host.IP(), + Host: &net.UDPAddr{ + IP: pkt.Source.Host.IP().AsSlice(), Port: int(udp.SrcPort), - }), + }, Path: replyPath, NextHop: CopyUDPAddr(&lastHop), } diff --git a/pkg/snet/snet.go b/pkg/snet/snet.go index e85d2cd4b5..c41c269e8c 100644 --- a/pkg/snet/snet.go +++ b/pkg/snet/snet.go @@ -82,7 +82,7 @@ type SCIONNetwork struct { // The context is used for connection setup, it doesn't affect the returned // connection. func (n *SCIONNetwork) Dial(ctx context.Context, network string, listen *net.UDPAddr, - remote *UDPAddr, svc addr.HostSVC) (*Conn, error) { + remote *UDPAddr, svc addr.SVC) (*Conn, error) { metrics.CounterInc(n.Metrics.Dials) if remote == nil { @@ -104,7 +104,7 @@ func (n *SCIONNetwork) Dial(ctx context.Context, network string, listen *net.UDP // The context is used for connection setup, it doesn't affect the returned // connection. func (n *SCIONNetwork) Listen(ctx context.Context, network string, listen *net.UDPAddr, - svc addr.HostSVC) (*Conn, error) { + svc addr.SVC) (*Conn, error) { metrics.CounterInc(n.Metrics.Listens) diff --git a/pkg/snet/svcaddr.go b/pkg/snet/svcaddr.go index c65190315e..b072cd4c4b 100644 --- a/pkg/snet/svcaddr.go +++ b/pkg/snet/svcaddr.go @@ -26,7 +26,7 @@ type SVCAddr struct { IA addr.IA Path DataplanePath NextHop *net.UDPAddr - SVC addr.HostSVC + SVC addr.SVC } // Network implements net.Addr interface. diff --git a/pkg/snet/svcaddr_test.go b/pkg/snet/svcaddr_test.go index 138ec02040..1738fe5fe9 100644 --- a/pkg/snet/svcaddr_test.go +++ b/pkg/snet/svcaddr_test.go @@ -36,7 +36,7 @@ func TestSVCAddrString(t *testing.T) { }{ "nil": { input: &snet.SVCAddr{}, - want: "0-0,UNKNOWN A (0x0000)", + want: "0-0,", }, } for n, tc := range tests { diff --git a/pkg/snet/udpaddr.go b/pkg/snet/udpaddr.go index 6d741fea76..50a13cb8ce 100644 --- a/pkg/snet/udpaddr.go +++ b/pkg/snet/udpaddr.go @@ -19,7 +19,6 @@ import ( "net" "net/netip" "regexp" - "strconv" "strings" "github.com/scionproto/scion/pkg/addr" @@ -52,34 +51,17 @@ func ParseUDPAddr(s string) (*UDPAddr, error) { // - [isd-as,ipv4]:port (e.g., [1-ff00:0:110,192.0.2.1]:80) // - [isd-as,ipv6%zone]:port (e.g., [1-ff00:0:110,2001:DB8::1%zone]:80) func parseUDPAddr(s string) (*UDPAddr, error) { - host, port, err := net.SplitHostPort(s) + a, p, err := addr.ParseAddrPort(s) if err != nil { - return nil, serrors.WrapStr("invalid address: split host:port", err, "addr", s) - } - parts := strings.Split(host, ",") - if len(parts) != 2 { - return nil, serrors.New("invalid address: host parts invalid", - "expected", 2, "actual", len(parts)) - } - ia, err := addr.ParseIA(parts[0]) - if err != nil { - return nil, serrors.WrapStr("invalid address: IA not parsable", err, "ia", ia) - } - ip, err := netip.ParseAddr(parts[1]) - if err != nil { - return nil, serrors.WrapStr("invalid address: ip not parsable", err, "ip", parts[1]) - } - p, err := strconv.Atoi(port) - if err != nil { - return nil, serrors.WrapStr("invalid address: port invalid", err, "port", port) + return nil, err } udp := &net.UDPAddr{ - IP: ip.AsSlice(), - Zone: ip.Zone(), - Port: p, + IP: a.Host.IP().AsSlice(), + Zone: a.Host.IP().Zone(), + Port: int(p), } - return &UDPAddr{IA: ia, Host: udp}, nil + return &UDPAddr{IA: a.IA, Host: udp}, nil } // The legacy format of the SCION address URI encoding allows multiple different encodings. diff --git a/pkg/snet/writer.go b/pkg/snet/writer.go index f185542e29..70609f1023 100644 --- a/pkg/snet/writer.go +++ b/pkg/snet/writer.go @@ -18,6 +18,7 @@ package snet import ( "fmt" "net" + "net/netip" "sync" "time" @@ -47,7 +48,11 @@ func (c *scionConnWriter) WriteTo(b []byte, raddr net.Addr) (int, error) { case nil: return 0, serrors.New("Missing remote address") case *UDPAddr: - dst = SCIONAddress{IA: a.IA, Host: addr.HostFromIP(a.Host.IP)} + hostIP, ok := netip.AddrFromSlice(a.Host.IP) + if !ok { + return 0, serrors.New("invalid destination host IP", "ip", a.Host.IP) + } + dst = SCIONAddress{IA: a.IA, Host: addr.HostIP(hostIP)} port, path = a.Host.Port, a.Path nextHop = a.NextHop if nextHop == nil && c.base.scionNet.LocalIA.Equal(a.IA) { @@ -59,20 +64,25 @@ func (c *scionConnWriter) WriteTo(b []byte, raddr net.Addr) (int, error) { } case *SVCAddr: - dst, port, path = SCIONAddress{IA: a.IA, Host: a.SVC}, 0, a.Path + dst, port, path = SCIONAddress{IA: a.IA, Host: addr.HostSVC(a.SVC)}, 0, a.Path nextHop = a.NextHop default: return 0, serrors.New("Unable to write to non-SCION address", "addr", fmt.Sprintf("%v(%T)", a, a)) } + listenHostIP, ok := netip.AddrFromSlice(c.base.listen.Host.IP) + if !ok { + return 0, serrors.New("invalid listen host IP", "ip", c.base.listen.Host.IP) + } + pkt := &Packet{ Bytes: Bytes(c.buffer), PacketInfo: PacketInfo{ Destination: dst, Source: SCIONAddress{ IA: c.base.scionNet.LocalIA, - Host: addr.HostFromIP(c.base.listen.Host.IP), + Host: addr.HostIP(listenHostIP), }, Path: path, Payload: UDPPayload{ diff --git a/pkg/sock/reliable/frame.go b/pkg/sock/reliable/frame.go index f0b64f8659..31b8b938af 100644 --- a/pkg/sock/reliable/frame.go +++ b/pkg/sock/reliable/frame.go @@ -18,7 +18,6 @@ import ( "encoding/binary" "net" - "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/serrors" ) @@ -88,7 +87,7 @@ func (f *frame) DecodeFromBytes(data []byte) error { f.AddressType = data[8] f.Length = binary.BigEndian.Uint32(data[9:]) offset := 13 - addressType := addr.HostAddrType(f.AddressType) + addressType := hostAddrType(f.AddressType) if !isValidReliableSockDestination(addressType) { return serrors.WithCtx(ErrBadAddressType, "type", addressType) } @@ -136,8 +135,8 @@ func (f *frame) insertAddress(address *net.UDPAddr) error { } func (f *frame) extractAddress() *net.UDPAddr { - t := addr.HostAddrType(f.AddressType) - if t == addr.HostTypeIPv4 || t == addr.HostTypeIPv6 { + t := hostAddrType(f.AddressType) + if t == hostTypeIPv4 || t == hostTypeIPv6 { return &net.UDPAddr{ IP: net.IP(f.Address), Port: int(binary.BigEndian.Uint16(f.Port)), diff --git a/pkg/sock/reliable/mock_reliable/mock.go b/pkg/sock/reliable/mock_reliable/mock.go index 20893aa72c..6dd9215859 100644 --- a/pkg/sock/reliable/mock_reliable/mock.go +++ b/pkg/sock/reliable/mock_reliable/mock.go @@ -37,7 +37,7 @@ func (m *MockDispatcher) EXPECT() *MockDispatcherMockRecorder { } // Register mocks base method. -func (m *MockDispatcher) Register(arg0 context.Context, arg1 addr.IA, arg2 *net.UDPAddr, arg3 addr.HostSVC) (net.PacketConn, uint16, error) { +func (m *MockDispatcher) Register(arg0 context.Context, arg1 addr.IA, arg2 *net.UDPAddr, arg3 addr.SVC) (net.PacketConn, uint16, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Register", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(net.PacketConn) diff --git a/pkg/sock/reliable/packetizer.go b/pkg/sock/reliable/packetizer.go index 90e2c1c65c..38485bf395 100644 --- a/pkg/sock/reliable/packetizer.go +++ b/pkg/sock/reliable/packetizer.go @@ -18,7 +18,6 @@ import ( "encoding/binary" "net" - "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" ) @@ -85,8 +84,8 @@ func (reader *ReadPacketizer) haveNextPacket(b []byte) []byte { } rcvdAddrType := b[8] payloadLength := binary.BigEndian.Uint32(b[9:13]) - addressLength := getAddressLength(addr.HostAddrType(rcvdAddrType)) - portLength := getPortLength(addr.HostAddrType(rcvdAddrType)) + addressLength := getAddressLength(hostAddrType(rcvdAddrType)) + portLength := getPortLength(hostAddrType(rcvdAddrType)) totalLength := 13 + addressLength + portLength + int(payloadLength) if len(b) < totalLength { return nil diff --git a/pkg/sock/reliable/reconnect/network.go b/pkg/sock/reliable/reconnect/network.go index 91f0df5110..84358f2837 100644 --- a/pkg/sock/reliable/reconnect/network.go +++ b/pkg/sock/reliable/reconnect/network.go @@ -45,7 +45,7 @@ func NewDispatcherService(dispatcher reliable.Dispatcher) *DispatcherService { } func (pn *DispatcherService) Register(ctx context.Context, ia addr.IA, public *net.UDPAddr, - svc addr.HostSVC) (net.PacketConn, uint16, error) { + svc addr.SVC) (net.PacketConn, uint16, error) { // Perform initial connection to allocate port. We use a reconnecter here // to set up the initial connection using the same retry logic we use when @@ -71,7 +71,7 @@ func (pn *DispatcherService) Register(ctx context.Context, ia addr.IA, public *n } func (pn *DispatcherService) newReconnecterFromListenArgs(ctx context.Context, ia addr.IA, - public *net.UDPAddr, svc addr.HostSVC) *TickingReconnecter { + public *net.UDPAddr, svc addr.SVC) *TickingReconnecter { // f represents individual connection attempts f := func(timeout time.Duration) (net.PacketConn, uint16, error) { diff --git a/pkg/sock/reliable/registration.go b/pkg/sock/reliable/registration.go index e7475825a6..e4e7c87c99 100644 --- a/pkg/sock/reliable/registration.go +++ b/pkg/sock/reliable/registration.go @@ -35,7 +35,7 @@ type Registration struct { IA addr.IA PublicAddress *net.UDPAddr BindAddress *net.UDPAddr - SVCAddress addr.HostSVC + SVCAddress addr.SVC } func (r *Registration) SerializeTo(b []byte) (int, error) { @@ -78,7 +78,7 @@ func (r *Registration) DecodeFromBytes(b []byte) error { if len(msg.SVC) == 0 { r.SVCAddress = addr.SvcNone } else { - r.SVCAddress = addr.HostSVC(binary.BigEndian.Uint16(msg.SVC)) + r.SVCAddress = addr.SVC(binary.BigEndian.Uint16(msg.SVC)) } if (msg.Command & CmdBindAddress) != 0 { r.BindAddress = &net.UDPAddr{ @@ -175,10 +175,10 @@ func (l *registrationAddressField) DecodeFromBytes(b []byte) error { } l.Port = binary.BigEndian.Uint16(b[:2]) l.AddressType = b[2] - if !isValidReliableSockDestination(addr.HostAddrType(l.AddressType)) { + if !isValidReliableSockDestination(hostAddrType(l.AddressType)) { return ErrBadAddressType } - addressLength := getAddressLength(addr.HostAddrType(l.AddressType)) + addressLength := getAddressLength(hostAddrType(l.AddressType)) if len(b[3:]) < addressLength { return ErrIncompleteAddress } diff --git a/pkg/sock/reliable/reliable.go b/pkg/sock/reliable/reliable.go index c70afac0b5..b3b3ed1484 100644 --- a/pkg/sock/reliable/reliable.go +++ b/pkg/sock/reliable/reliable.go @@ -95,7 +95,7 @@ type Dispatcher interface { // Register connects to a SCION Dispatcher's UNIX socket. Future messages for the address in AS // ia which arrive at the dispatcher can be read by calling Read on the returned connection. Register(ctx context.Context, ia addr.IA, address *net.UDPAddr, - svc addr.HostSVC) (net.PacketConn, uint16, error) + svc addr.SVC) (net.PacketConn, uint16, error) } // NewDispatcher creates a new dispatcher API endpoint on top of a UNIX @@ -113,7 +113,7 @@ type dispatcherService struct { } func (d *dispatcherService) Register(ctx context.Context, ia addr.IA, public *net.UDPAddr, - svc addr.HostSVC) (net.PacketConn, uint16, error) { + svc addr.SVC) (net.PacketConn, uint16, error) { return registerMetricsWrapper(ctx, d.Address, ia, public, svc) } @@ -161,7 +161,7 @@ func Dial(ctx context.Context, address string) (*Conn, error) { } func registerMetricsWrapper(ctx context.Context, dispatcher string, ia addr.IA, - public *net.UDPAddr, svc addr.HostSVC) (*Conn, uint16, error) { + public *net.UDPAddr, svc addr.SVC) (*Conn, uint16, error) { conn, port, err := register(ctx, dispatcher, ia, public, svc) labels := metrics.RegisterLabels{Result: labelResult(err), SVC: svc.BaseString()} @@ -170,7 +170,7 @@ func registerMetricsWrapper(ctx context.Context, dispatcher string, ia addr.IA, } func register(ctx context.Context, dispatcher string, ia addr.IA, public *net.UDPAddr, - svc addr.HostSVC) (*Conn, uint16, error) { + svc addr.SVC) (*Conn, uint16, error) { reg := &Registration{ IA: ia, diff --git a/pkg/sock/reliable/util.go b/pkg/sock/reliable/util.go index f79dc256cd..f0e49b0f5c 100644 --- a/pkg/sock/reliable/util.go +++ b/pkg/sock/reliable/util.go @@ -16,22 +16,29 @@ package reliable import ( "net" +) + +type hostAddrType uint8 - "github.com/scionproto/scion/pkg/addr" +const ( + hostTypeNone = iota + hostTypeIPv4 + hostTypeIPv6 + hostTypeSVC ) -func getAddressType(address *net.UDPAddr) addr.HostAddrType { +func getAddressType(address *net.UDPAddr) hostAddrType { if address == nil || address.IP == nil { - return addr.HostTypeNone + return hostTypeNone } return getIPAddressType(address.IP) } -func getIPAddressType(ip net.IP) addr.HostAddrType { +func getIPAddressType(ip net.IP) hostAddrType { if ip.To4() != nil { - return addr.HostTypeIPv4 + return hostTypeIPv4 } - return addr.HostTypeIPv6 + return hostTypeIPv6 } // normalizeIP returns a 4-byte slice for an IPv4 address, and 16-byte slice @@ -43,17 +50,26 @@ func normalizeIP(ip net.IP) net.IP { return ip } -func isValidReliableSockDestination(t addr.HostAddrType) bool { - return t == addr.HostTypeNone || t == addr.HostTypeIPv4 || t == addr.HostTypeIPv6 +func isValidReliableSockDestination(t hostAddrType) bool { + return t == hostTypeNone || t == hostTypeIPv4 || t == hostTypeIPv6 } -func getAddressLength(t addr.HostAddrType) int { - n, _ := addr.HostLen(t) - return int(n) +func getAddressLength(t hostAddrType) int { + switch t { + case hostTypeNone: + return 0 + case hostTypeIPv4: + return 4 + case hostTypeIPv6: + return 16 + case hostTypeSVC: + return 2 + } + return 0 } -func getPortLength(t addr.HostAddrType) int { - if t == addr.HostTypeIPv4 || t == addr.HostTypeIPv6 { +func getPortLength(t hostAddrType) int { + if t == hostTypeIPv4 || t == hostTypeIPv6 { return 2 } return 0 diff --git a/pkg/spao/BUILD.bazel b/pkg/spao/BUILD.bazel index f047fd0e49..390c3f26c2 100644 --- a/pkg/spao/BUILD.bazel +++ b/pkg/spao/BUILD.bazel @@ -30,7 +30,6 @@ go_test( ], embed = [":go_default_library"], deps = [ - "//pkg/addr:go_default_library", "//pkg/drkey:go_default_library", "//pkg/private/xtest:go_default_library", "//pkg/slayers:go_default_library", diff --git a/pkg/spao/mac_test.go b/pkg/spao/mac_test.go index d9ad62fc21..08e6e8c167 100644 --- a/pkg/spao/mac_test.go +++ b/pkg/spao/mac_test.go @@ -24,7 +24,6 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -159,7 +158,7 @@ func TestComputeAuthMac(t *testing.T) { SrcAddrType: slayers.T16Ip, RawSrcAddr: net.ParseIP("2001:cafe::1").To16(), DstAddrType: slayers.T4Svc, - RawDstAddr: addr.HostSVCFromString("CS").Pack(), + RawDstAddr: nil, Path: decodedPath, PathType: decodedPath.Type(), }, diff --git a/private/app/appnet/addr.go b/private/app/appnet/addr.go index 19387e2f50..4bbd733037 100644 --- a/private/app/appnet/addr.go +++ b/private/app/appnet/addr.go @@ -33,7 +33,7 @@ import ( // SVC address to a unicast IP/UDP one. type Resolver interface { // LookupSVC resolves the SVC address for the AS terminating the path. - LookupSVC(ctx context.Context, path snet.Path, svc addr.HostSVC) (*svc.Reply, error) + LookupSVC(ctx context.Context, path snet.Path, svc addr.SVC) (*svc.Reply, error) } // AddressRewriter is used to compute paths and replace SVC destinations with @@ -174,7 +174,7 @@ func (r AddressRewriter) buildFullAddress(ctx context.Context, // The returned path is the path contained in the reply; the path can be used // to talk to the remote AS after One-Hop Path construction. func (r AddressRewriter) resolveSVC(ctx context.Context, p snet.Path, - s addr.HostSVC) (snet.Path, *net.UDPAddr, bool, error) { + s addr.SVC) (snet.Path, *net.UDPAddr, bool, error) { logger := log.FromCtx(ctx) if r.SVCResolutionFraction < 1.0 { var cancelF context.CancelFunc @@ -232,5 +232,5 @@ type SVCResolver interface { // GetUnderlay returns the underlay address of a SVC server of the specified // type. When multiple servers are available, the choice is random. If no // servers are available an error should be returned. - GetUnderlay(svc addr.HostSVC) (*net.UDPAddr, error) + GetUnderlay(svc addr.SVC) (*net.UDPAddr, error) } diff --git a/private/app/appnet/addr_test.go b/private/app/appnet/addr_test.go index 89b0e527db..27bba692cc 100644 --- a/private/app/appnet/addr_test.go +++ b/private/app/appnet/addr_test.go @@ -318,7 +318,7 @@ func TestBuildFullAddress(t *testing.T) { func TestResolve(t *testing.T) { testCases := map[string]struct { - input addr.HostSVC + input addr.SVC ResolverSetup func(*mock_infraenv.MockResolver) SVCResolutionFraction float64 wantPath snet.Path diff --git a/private/app/appnet/export_test.go b/private/app/appnet/export_test.go index a6c3c57ca9..47e689ebff 100644 --- a/private/app/appnet/export_test.go +++ b/private/app/appnet/export_test.go @@ -29,7 +29,7 @@ func (r AddressRewriter) BuildFullAddress(ctx context.Context, } func (r AddressRewriter) ResolveSVC(ctx context.Context, p snet.Path, - s addr.HostSVC) (snet.Path, *net.UDPAddr, bool, error) { + s addr.SVC) (snet.Path, *net.UDPAddr, bool, error) { return r.resolveSVC(ctx, p, s) } diff --git a/private/app/appnet/mock_infraenv/mock.go b/private/app/appnet/mock_infraenv/mock.go index 1a35fd832d..920dda8a82 100644 --- a/private/app/appnet/mock_infraenv/mock.go +++ b/private/app/appnet/mock_infraenv/mock.go @@ -39,7 +39,7 @@ func (m *MockSVCResolver) EXPECT() *MockSVCResolverMockRecorder { } // GetUnderlay mocks base method. -func (m *MockSVCResolver) GetUnderlay(arg0 addr.HostSVC) (*net.UDPAddr, error) { +func (m *MockSVCResolver) GetUnderlay(arg0 addr.SVC) (*net.UDPAddr, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetUnderlay", arg0) ret0, _ := ret[0].(*net.UDPAddr) @@ -77,7 +77,7 @@ func (m *MockResolver) EXPECT() *MockResolverMockRecorder { } // LookupSVC mocks base method. -func (m *MockResolver) LookupSVC(arg0 context.Context, arg1 snet.Path, arg2 addr.HostSVC) (*svc.Reply, error) { +func (m *MockResolver) LookupSVC(arg0 context.Context, arg1 snet.Path, arg2 addr.SVC) (*svc.Reply, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "LookupSVC", arg0, arg1, arg2) ret0, _ := ret[0].(*svc.Reply) diff --git a/private/app/path/pathprobe/paths.go b/private/app/path/pathprobe/paths.go index 5a64f601c8..951d27d59d 100644 --- a/private/app/path/pathprobe/paths.go +++ b/private/app/path/pathprobe/paths.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "net" + "net/netip" "os" "sync" "sync/atomic" @@ -55,7 +56,7 @@ const ( // Status indicates the state a path is in. type Status struct { Status StatusName - LocalIP net.IP + LocalIP netip.Addr AdditionalInfo string } @@ -172,10 +173,11 @@ func (p Prober) GetStatuses(ctx context.Context, paths []snet.Path, // Resolve all the local IPs per path. We will open one connection // per local IP address. - pathsPerIP := map[string][]snet.Path{} + pathsPerIP := map[netip.Addr][]snet.Path{} for _, path := range paths { - localIP, err := p.resolveLocalIP(path.UnderlayNextHop()) - if err != nil { + localIPSlice, err := p.resolveLocalIP(path.UnderlayNextHop()) + localIP, ok := netip.AddrFromSlice(localIPSlice) + if err != nil || !ok { addStatus( PathKey(path), Status{ @@ -185,20 +187,20 @@ func (p Prober) GetStatuses(ctx context.Context, paths []snet.Path, ) continue } - pathsPerIP[localIP.String()] = append(pathsPerIP[localIP.String()], path) + pathsPerIP[localIP] = append(pathsPerIP[localIP], path) addStatus(PathKey(path), Status{Status: StatusTimeout, LocalIP: localIP}) } // Sequence number for the sent traceroute packets. var seq int32 g, _ := errgroup.WithContext(ctx) - for ip, paths := range pathsPerIP { - ip, paths := ip, paths + for localIP, paths := range pathsPerIP { + localIP, paths := localIP, paths g.Go(func() error { defer log.HandlePanic() - localIP := net.ParseIP(ip) - conn, _, err := disp.Register(ctx, p.LocalIA, &net.UDPAddr{IP: localIP}, addr.SvcNone) + conn, _, err := disp.Register(ctx, p.LocalIA, + &net.UDPAddr{IP: localIP.AsSlice()}, addr.SvcNone) if err != nil { return serrors.WrapStr("creating packet conn", err, "local", localIP) } @@ -236,11 +238,11 @@ func (p Prober) GetStatuses(ctx context.Context, paths []snet.Path, PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: p.DstIA, - Host: addr.SvcNone, + Host: addr.HostSVC(addr.SvcNone), }, Source: snet.SCIONAddress{ IA: p.LocalIA, - Host: addr.HostFromIP(localIP), + Host: addr.HostIP(localIP), }, Path: alertPath, Payload: snet.SCMPTracerouteRequest{ diff --git a/private/svc/resolver.go b/private/svc/resolver.go index ad0c2190c9..fb01fb173f 100644 --- a/private/svc/resolver.go +++ b/private/svc/resolver.go @@ -17,6 +17,7 @@ package svc import ( "context" "net" + "net/netip" "github.com/opentracing/opentracing-go" "github.com/opentracing/opentracing-go/ext" @@ -68,7 +69,7 @@ type Resolver struct { } // LookupSVC resolves the SVC address for the AS terminating the path. -func (r *Resolver) LookupSVC(ctx context.Context, p snet.Path, svc addr.HostSVC) (*Reply, error) { +func (r *Resolver) LookupSVC(ctx context.Context, p snet.Path, svc addr.SVC) (*Reply, error) { var span opentracing.Span span, ctx = opentracing.StartSpanFromContext(ctx, "svc.resolution") span.SetTag("svc", svc.String()) @@ -78,6 +79,10 @@ func (r *Resolver) LookupSVC(ctx context.Context, p snet.Path, svc addr.HostSVC) u := &net.UDPAddr{ IP: r.LocalIP, } + localIP, ok := netip.AddrFromSlice(r.LocalIP) + if !ok { + return nil, serrors.New("invalid local IP", "ip", r.LocalIP) + } conn, port, err := r.ConnFactory.Register(ctx, r.LocalIA, u, addr.SvcNone) if err != nil { @@ -95,11 +100,11 @@ func (r *Resolver) LookupSVC(ctx context.Context, p snet.Path, svc addr.HostSVC) PacketInfo: snet.PacketInfo{ Source: snet.SCIONAddress{ IA: r.LocalIA, - Host: addr.HostFromIP(r.LocalIP), + Host: addr.HostIP(localIP), }, Destination: snet.SCIONAddress{ IA: p.Destination(), - Host: svc, + Host: addr.HostSVC(svc), }, Path: p.Dataplane(), Payload: snet.UDPPayload{ diff --git a/private/svc/resolver_test.go b/private/svc/resolver_test.go index 72325863e5..86a47bf579 100644 --- a/private/svc/resolver_test.go +++ b/private/svc/resolver_test.go @@ -55,6 +55,7 @@ func TestResolver(t *testing.T) { resolver := &svc.Resolver{ LocalIA: srcIA, ConnFactory: mockPacketDispatcherService, + LocalIP: net.IP{0, 0, 0, 0}, } reply, err := resolver.LookupSVC(context.Background(), mockPath, addr.SvcCS) diff --git a/private/svc/svc.go b/private/svc/svc.go index c9e0666f8d..e7451f25c1 100644 --- a/private/svc/svc.go +++ b/private/svc/svc.go @@ -18,6 +18,7 @@ package svc import ( "context" "net" + "net/netip" "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/common" @@ -72,8 +73,12 @@ type ResolverPacketDispatcher struct { } func (d *ResolverPacketDispatcher) Register(ctx context.Context, ia addr.IA, - registration *net.UDPAddr, svc addr.HostSVC) (snet.PacketConn, uint16, error) { + registration *net.UDPAddr, svc addr.SVC) (snet.PacketConn, uint16, error) { + registrationIP, ok := netip.AddrFromSlice(registration.IP) + if !ok { + return nil, 0, serrors.New("invalid registration IP", "ip", registration.IP) + } c, port, err := d.dispService.Register(ctx, ia, registration, svc) if err != nil { return nil, 0, err @@ -82,7 +87,7 @@ func (d *ResolverPacketDispatcher) Register(ctx context.Context, ia addr.IA, PacketConn: c, source: snet.SCIONAddress{ IA: ia, - Host: addr.HostFromIP(registration.IP), + Host: addr.HostIP(registrationIP), }, handler: d.handler, } @@ -107,11 +112,11 @@ func (c *resolverPacketConn) ReadFrom(pkt *snet.Packet, ov *net.UDPAddr) error { } // XXX(scrye): destination address is guaranteed to not be nil - svc, ok := pkt.Destination.Host.(addr.HostSVC) - if !ok { + if pkt.Destination.Host.Type() != addr.HostTypeSVC { // Normal packet, return to caller because data is already parsed and ready return nil } + svc := pkt.Destination.Host.SVC() // Multicasts do not trigger SVC resolution logic if svc.IsMulticast() { diff --git a/private/svc/svc_test.go b/private/svc/svc_test.go index 2abade4a42..f6aed72334 100644 --- a/private/svc/svc_test.go +++ b/private/svc/svc_test.go @@ -59,7 +59,7 @@ func TestSVCResolutionServer(t *testing.T) { mockPacketConn.EXPECT().ReadFrom(gomock.Any(), gomock.Any()).DoAndReturn( func(pkt *snet.Packet, ov *net.UDPAddr) error { pkt.Destination = snet.SCIONAddress{ - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), } return nil }, @@ -85,7 +85,7 @@ func TestSVCResolutionServer(t *testing.T) { mockPacketConn.EXPECT().ReadFrom(gomock.Any(), gomock.Any()).DoAndReturn( func(pkt *snet.Packet, ov *net.UDPAddr) error { pkt.Destination = snet.SCIONAddress{ - Host: addr.SvcCS, + Host: addr.HostSVC(addr.SvcCS), } return nil }, @@ -111,7 +111,7 @@ func TestSVCResolutionServer(t *testing.T) { mockPacketConn.EXPECT().ReadFrom(gomock.Any(), gomock.Any()).DoAndReturn( func(pkt *snet.Packet, ov *net.UDPAddr) error { pkt.Destination = snet.SCIONAddress{ - Host: addr.HostIPv4(net.IP{192, 168, 0, 1}), + Host: addr.MustParseHost("192.168.0.1"), } return nil }, @@ -160,7 +160,7 @@ func TestSVCResolutionServer(t *testing.T) { mockPacketConn.EXPECT().ReadFrom(gomock.Any(), gomock.Any()).DoAndReturn( func(pkt *snet.Packet, ov *net.UDPAddr) error { pkt.Destination = snet.SCIONAddress{ - Host: addr.SvcCS.Multicast(), + Host: addr.HostSVC(addr.SvcCS.Multicast()), } return nil }, @@ -190,7 +190,8 @@ func TestSVCResolutionServer(t *testing.T) { defer ctrl.Finish() disp := svc.NewResolverPacketDispatcher(tc.DispService(ctrl), tc.ReqHandler(ctrl)) - conn, port, err := disp.Register(context.Background(), 0, &net.UDPAddr{}, + conn, port, err := disp.Register(context.Background(), 0, + &net.UDPAddr{IP: net.ParseIP("198.51.100.1")}, addr.SvcCS) tc.ErrRegister(t, err) @@ -280,7 +281,7 @@ func TestDefaultHandler(t *testing.T) { }, }, "Source address override": { - ReplySource: snet.SCIONAddress{Host: addr.HostIPv4(net.IP{192, 168, 0, 1})}, + ReplySource: snet.SCIONAddress{Host: addr.MustParseHost("192.168.0.1")}, InputPacket: &snet.Packet{ PacketInfo: snet.PacketInfo{ Payload: snet.UDPPayload{}, @@ -289,7 +290,7 @@ func TestDefaultHandler(t *testing.T) { }, ExpectedPacket: &snet.Packet{ PacketInfo: snet.PacketInfo{ - Source: snet.SCIONAddress{Host: addr.HostIPv4(net.IP{192, 168, 0, 1})}, + Source: snet.SCIONAddress{Host: addr.MustParseHost("192.168.0.1")}, Payload: snet.UDPPayload{}, Path: snet.RawReplyPath{ Path: empty.Path{}, diff --git a/private/topology/interface.go b/private/topology/interface.go index 868414d238..f6440c1770 100644 --- a/private/topology/interface.go +++ b/private/topology/interface.go @@ -43,17 +43,17 @@ type Topology interface { // PublicAddress gets the public address of a server with the requested type and name, and nil // if no such server exists. - PublicAddress(svc addr.HostSVC, name string) *net.UDPAddr + PublicAddress(svc addr.SVC, name string) *net.UDPAddr // Anycast returns the address for an arbitrary server of the requested type. - Anycast(svc addr.HostSVC) (*net.UDPAddr, error) + Anycast(svc addr.SVC) (*net.UDPAddr, error) // Multicast returns all addresses for the requested type. - Multicast(svc addr.HostSVC) ([]*net.UDPAddr, error) + Multicast(svc addr.SVC) ([]*net.UDPAddr, error) // UnderlayAnycast returns the underlay address for an arbitrary server of the requested type. - UnderlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error) + UnderlayAnycast(svc addr.SVC) (*net.UDPAddr, error) // UnderlayMulticast returns all underlay addresses for the requested type. - UnderlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error) + UnderlayMulticast(svc addr.SVC) ([]*net.UDPAddr, error) // UnderlayNextHop returns the internal underlay address of the router // containing the interface ID. UnderlayNextHop(ifID common.IFIDType) (*net.UDPAddr, bool) @@ -89,7 +89,7 @@ type Topology interface { // FIXME(scrye): Remove this, callers shouldn't care about names. // // XXX(scrye): Return value is a shallow copy. - SVCNames(svc addr.HostSVC) ServiceNames + SVCNames(svc addr.SVC) ServiceNames // Writable returns a pointer to the underlying topology object. This is included for legacy // reasons and should never be used. @@ -203,7 +203,7 @@ func (t *topologyS) BR(name string) (BRInfo, bool) { return br, ok } -func (t *topologyS) PublicAddress(svc addr.HostSVC, name string) *net.UDPAddr { +func (t *topologyS) PublicAddress(svc addr.SVC, name string) *net.UDPAddr { topoAddr := t.topoAddress(svc, name) if topoAddr == nil { return nil @@ -211,7 +211,7 @@ func (t *topologyS) PublicAddress(svc addr.HostSVC, name string) *net.UDPAddr { return topoAddr.SCIONAddress } -func (t *topologyS) topoAddress(svc addr.HostSVC, name string) *TopoAddr { +func (t *topologyS) topoAddress(svc addr.SVC, name string) *TopoAddr { var addresses IDAddrMap switch svc.Base() { case addr.SvcDS: @@ -225,7 +225,7 @@ func (t *topologyS) topoAddress(svc addr.HostSVC, name string) *TopoAddr { return addresses.GetByID(name) } -func (t *topologyS) Anycast(svc addr.HostSVC) (*net.UDPAddr, error) { +func (t *topologyS) Anycast(svc addr.SVC) (*net.UDPAddr, error) { addrs, err := t.Multicast(svc) if err != nil { return nil, err @@ -233,7 +233,7 @@ func (t *topologyS) Anycast(svc addr.HostSVC) (*net.UDPAddr, error) { return addrs[rand.Intn(len(addrs))], nil } -func (t *topologyS) Multicast(svc addr.HostSVC) ([]*net.UDPAddr, error) { +func (t *topologyS) Multicast(svc addr.SVC) ([]*net.UDPAddr, error) { st, err := toServiceType(svc) if err != nil { return nil, err @@ -257,7 +257,7 @@ func (t *topologyS) Multicast(svc addr.HostSVC) ([]*net.UDPAddr, error) { return addrs, nil } -func (t *topologyS) UnderlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error) { +func (t *topologyS) UnderlayAnycast(svc addr.SVC) (*net.UDPAddr, error) { names := t.SVCNames(svc) name, err := names.GetRandom() if err != nil { @@ -275,12 +275,12 @@ func (t *topologyS) UnderlayAnycast(svc addr.HostSVC) (*net.UDPAddr, error) { return underlay, nil } -func supportedSVC(svc addr.HostSVC) bool { +func supportedSVC(svc addr.SVC) bool { b := svc.Base() return b == addr.SvcDS || b == addr.SvcCS } -func (t *topologyS) UnderlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error) { +func (t *topologyS) UnderlayMulticast(svc addr.SVC) ([]*net.UDPAddr, error) { st, err := toServiceType(svc) if err != nil { return nil, err @@ -312,7 +312,7 @@ func (t *topologyS) UnderlayMulticast(svc addr.HostSVC) ([]*net.UDPAddr, error) return underlayAddrs, nil } -func (t *topologyS) underlayByName(svc addr.HostSVC, name string) (*net.UDPAddr, error) { +func (t *topologyS) underlayByName(svc addr.SVC, name string) (*net.UDPAddr, error) { st, err := toServiceType(svc) if err != nil { return nil, err @@ -328,7 +328,7 @@ func (t *topologyS) underlayByName(svc addr.HostSVC, name string) (*net.UDPAddr, return copyUDPAddr(underlayAddr), nil } -func toServiceType(svc addr.HostSVC) (ServiceType, error) { +func toServiceType(svc addr.SVC) (ServiceType, error) { switch svc.Base() { case addr.SvcDS: return Discovery, nil @@ -347,7 +347,7 @@ func (t *topologyS) BRNames() []string { return t.Topology.BRNames } -func (t *topologyS) SVCNames(svc addr.HostSVC) ServiceNames { +func (t *topologyS) SVCNames(svc addr.SVC) ServiceNames { var m IDAddrMap switch svc.Base() { case addr.SvcDS: diff --git a/private/topology/mock_topology/mock.go b/private/topology/mock_topology/mock.go index 62832c8b4a..2c33bb48b2 100644 --- a/private/topology/mock_topology/mock.go +++ b/private/topology/mock_topology/mock.go @@ -38,7 +38,7 @@ func (m *MockTopology) EXPECT() *MockTopologyMockRecorder { } // Anycast mocks base method. -func (m *MockTopology) Anycast(arg0 addr.HostSVC) (*net.UDPAddr, error) { +func (m *MockTopology) Anycast(arg0 addr.SVC) (*net.UDPAddr, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Anycast", arg0) ret0, _ := ret[0].(*net.UDPAddr) @@ -182,7 +182,7 @@ func (mr *MockTopologyMockRecorder) MakeHostInfos(arg0 interface{}) *gomock.Call } // Multicast mocks base method. -func (m *MockTopology) Multicast(arg0 addr.HostSVC) ([]*net.UDPAddr, error) { +func (m *MockTopology) Multicast(arg0 addr.SVC) ([]*net.UDPAddr, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Multicast", arg0) ret0, _ := ret[0].([]*net.UDPAddr) @@ -197,7 +197,7 @@ func (mr *MockTopologyMockRecorder) Multicast(arg0 interface{}) *gomock.Call { } // PublicAddress mocks base method. -func (m *MockTopology) PublicAddress(arg0 addr.HostSVC, arg1 string) *net.UDPAddr { +func (m *MockTopology) PublicAddress(arg0 addr.SVC, arg1 string) *net.UDPAddr { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "PublicAddress", arg0, arg1) ret0, _ := ret[0].(*net.UDPAddr) @@ -211,7 +211,7 @@ func (mr *MockTopologyMockRecorder) PublicAddress(arg0, arg1 interface{}) *gomoc } // SVCNames mocks base method. -func (m *MockTopology) SVCNames(arg0 addr.HostSVC) topology.ServiceNames { +func (m *MockTopology) SVCNames(arg0 addr.SVC) topology.ServiceNames { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SVCNames", arg0) ret0, _ := ret[0].(topology.ServiceNames) @@ -225,7 +225,7 @@ func (mr *MockTopologyMockRecorder) SVCNames(arg0 interface{}) *gomock.Call { } // UnderlayAnycast mocks base method. -func (m *MockTopology) UnderlayAnycast(arg0 addr.HostSVC) (*net.UDPAddr, error) { +func (m *MockTopology) UnderlayAnycast(arg0 addr.SVC) (*net.UDPAddr, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UnderlayAnycast", arg0) ret0, _ := ret[0].(*net.UDPAddr) @@ -240,7 +240,7 @@ func (mr *MockTopologyMockRecorder) UnderlayAnycast(arg0 interface{}) *gomock.Ca } // UnderlayMulticast mocks base method. -func (m *MockTopology) UnderlayMulticast(arg0 addr.HostSVC) ([]*net.UDPAddr, error) { +func (m *MockTopology) UnderlayMulticast(arg0 addr.SVC) ([]*net.UDPAddr, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UnderlayMulticast", arg0) ret0, _ := ret[0].([]*net.UDPAddr) diff --git a/private/topology/reload.go b/private/topology/reload.go index 196174b18e..74f974681f 100644 --- a/private/topology/reload.go +++ b/private/topology/reload.go @@ -207,7 +207,7 @@ func (l *Loader) HiddenSegmentRegistrationAddresses() ([]*net.UDPAddr, error) { } // TODO(lukedirtwalker): remove error / cleanup. -func (l *Loader) GetUnderlay(svc addr.HostSVC) (*net.UDPAddr, error) { +func (l *Loader) GetUnderlay(svc addr.SVC) (*net.UDPAddr, error) { l.mtx.Lock() defer l.mtx.Unlock() diff --git a/router/connector.go b/router/connector.go index f2bd767213..6944e75b2b 100644 --- a/router/connector.go +++ b/router/connector.go @@ -145,7 +145,7 @@ func (c *Connector) AddExternalInterface(localIfID common.IFIDType, link control } // AddSvc adds the service address for the given ISD-AS. -func (c *Connector) AddSvc(ia addr.IA, svc addr.HostSVC, ip net.IP) error { +func (c *Connector) AddSvc(ia addr.IA, svc addr.SVC, ip net.IP) error { c.mtx.Lock() defer c.mtx.Unlock() log.Debug("Adding service", "isd_as", ia, "svc", svc, "ip", ip) @@ -156,7 +156,7 @@ func (c *Connector) AddSvc(ia addr.IA, svc addr.HostSVC, ip net.IP) error { } // DelSvc deletes the service entry for the given ISD-AS and IP pair. -func (c *Connector) DelSvc(ia addr.IA, svc addr.HostSVC, ip net.IP) error { +func (c *Connector) DelSvc(ia addr.IA, svc addr.SVC, ip net.IP) error { c.mtx.Lock() defer c.mtx.Unlock() log.Debug("Deleting service", "isd_as", ia, "svc", svc, "ip", ip) diff --git a/router/control/conf.go b/router/control/conf.go index b11e4c27d4..1e68e892cb 100644 --- a/router/control/conf.go +++ b/router/control/conf.go @@ -34,8 +34,8 @@ type Dataplane interface { CreateIACtx(ia addr.IA) error AddInternalInterface(ia addr.IA, local net.UDPAddr) error AddExternalInterface(localIfID common.IFIDType, info LinkInfo, owned bool) error - AddSvc(ia addr.IA, svc addr.HostSVC, ip net.IP) error - DelSvc(ia addr.IA, svc addr.HostSVC, ip net.IP) error + AddSvc(ia addr.IA, svc addr.SVC, ip net.IP) error + DelSvc(ia addr.IA, svc addr.SVC, ip net.IP) error SetKey(ia addr.IA, index int, key []byte) error } @@ -206,7 +206,7 @@ func confExternalInterfaces(dp Dataplane, cfg *Config) error { return nil } -var svcTypes = []addr.HostSVC{ +var svcTypes = []addr.SVC{ addr.SvcDS, addr.SvcCS, } diff --git a/router/dataplane.go b/router/dataplane.go index 3410979683..81592f3cd3 100644 --- a/router/dataplane.go +++ b/router/dataplane.go @@ -24,6 +24,7 @@ import ( "hash" "math/big" "net" + "net/netip" "strconv" "sync" "syscall" @@ -99,7 +100,7 @@ type DataPlane struct { linkTypes map[uint16]topology.LinkType neighborIAs map[uint16]addr.IA internal BatchConn - internalIP *net.IPAddr + internalIP netip.Addr internalNextHops map[uint16]*net.UDPAddr svc *services macFactory func() hash.Hash @@ -132,7 +133,7 @@ var ( ) type drkeyProvider interface { - GetAuthKey(validTime time.Time, dstIA addr.IA, dstAddr net.Addr) (drkey.Key, error) + GetAuthKey(validTime time.Time, dstIA addr.IA, dstAddr addr.Host) (drkey.Key, error) } type scmpError struct { @@ -203,7 +204,11 @@ func (d *DataPlane) AddInternalInterface(conn BatchConn, ip net.IP) error { return alreadySet } d.internal = conn - d.internalIP = &net.IPAddr{IP: ip} + var ok bool + d.internalIP, ok = netip.AddrFromSlice(ip) + if !ok { + return serrors.New("invalid ip", "ip", ip) + } return nil } @@ -291,7 +296,10 @@ func (d *DataPlane) AddExternalInterfaceBFD(ifID uint16, conn BatchConn, PacketsReceived: d.Metrics.BFDPacketsReceived.With(labels), } } - s := newBFDSend(conn, src.IA, dst.IA, src.Addr, dst.Addr, ifID, d.macFactory()) + s, err := newBFDSend(conn, src.IA, dst.IA, src.Addr, dst.Addr, ifID, d.macFactory()) + if err != nil { + return err + } return d.addBFDController(ifID, s, cfg, m) } @@ -337,7 +345,7 @@ func (d *DataPlane) addBFDController(ifID uint16, s *bfdSend, cfg control.BFD, // AddSvc adds the address for the given service. This can be called multiple // times for the same service, with the address added to the list of addresses // that provide the service. -func (d *DataPlane) AddSvc(svc addr.HostSVC, a *net.UDPAddr) error { +func (d *DataPlane) AddSvc(svc addr.SVC, a *net.UDPAddr) error { d.mtx.Lock() defer d.mtx.Unlock() if a == nil { @@ -356,7 +364,7 @@ func (d *DataPlane) AddSvc(svc addr.HostSVC, a *net.UDPAddr) error { } // DelSvc deletes the address for the given service. -func (d *DataPlane) DelSvc(svc addr.HostSVC, a *net.UDPAddr) error { +func (d *DataPlane) DelSvc(svc addr.SVC, a *net.UDPAddr) error { d.mtx.Lock() defer d.mtx.Unlock() if a == nil { @@ -431,7 +439,10 @@ func (d *DataPlane) AddNextHopBFD(ifID uint16, src, dst *net.UDPAddr, cfg contro } } - s := newBFDSend(d.internal, d.localIA, d.localIA, src, dst, 0, d.macFactory()) + s, err := newBFDSend(d.internal, d.localIA, d.localIA, src, dst, 0, d.macFactory()) + if err != nil { + return err + } return d.addBFDController(ifID, s, cfg, m) } @@ -1426,24 +1437,24 @@ func (d *DataPlane) resolveLocalDst(s slayers.SCION) (*net.UDPAddr, error) { // TODO parameter problem. return nil, err } - switch v := dst.(type) { - case addr.HostSVC: + switch dst.Type() { + case addr.HostTypeSVC: // For map lookup use the Base address, i.e. strip the multi cast // information, because we only register base addresses in the map. - a, ok := d.svc.Any(v.Base()) + a, ok := d.svc.Any(dst.SVC().Base()) if !ok { return nil, noSVCBackend } return a, nil - case *net.IPAddr: - return addEndhostPort(v), nil + case addr.HostTypeIP: + return addEndhostPort(dst.IP().AsSlice()), nil default: panic("unexpected address type returned from DstAddr") } } -func addEndhostPort(dst *net.IPAddr) *net.UDPAddr { - return &net.UDPAddr{IP: dst.IP, Port: topology.EndhostPort} +func addEndhostPort(dst net.IP) *net.UDPAddr { + return &net.UDPAddr{IP: dst, Port: topology.EndhostPort} } // TODO(matzf) this function is now only used to update the OneHop-path. @@ -1476,7 +1487,7 @@ type bfdSend struct { // newBFDSend creates and initializes a BFD Sender func newBFDSend(conn BatchConn, srcIA, dstIA addr.IA, srcAddr, dstAddr *net.UDPAddr, - ifID uint16, mac hash.Hash) *bfdSend { + ifID uint16, mac hash.Hash) (*bfdSend, error) { scn := &slayers.SCION{ Version: 0, @@ -1487,11 +1498,19 @@ func newBFDSend(conn BatchConn, srcIA, dstIA addr.IA, srcAddr, dstAddr *net.UDPA DstIA: dstIA, } - if err := scn.SetSrcAddr(&net.IPAddr{IP: srcAddr.IP}); err != nil { - panic(err) // Must work unless IPAddr is not supported + srcAddrIP, ok := netip.AddrFromSlice(srcAddr.IP) + if !ok { + return nil, serrors.New("invalid source IP", "ip", srcAddr.IP) } - if err := scn.SetDstAddr(&net.IPAddr{IP: dstAddr.IP}); err != nil { - panic(err) // Must work unless IPAddr is not supported + dstAddrIP, ok := netip.AddrFromSlice(dstAddr.IP) + if !ok { + return nil, serrors.New("invalid destination IP", "ip", dstAddr.IP) + } + if err := scn.SetSrcAddr(addr.HostIP(srcAddrIP)); err != nil { + panic(err) // Must work + } + if err := scn.SetDstAddr(addr.HostIP(dstAddrIP)); err != nil { + panic(err) // Must work } var ohp *onehop.Path @@ -1522,7 +1541,7 @@ func newBFDSend(conn BatchConn, srcIA, dstIA addr.IA, srcAddr, dstAddr *net.UDPA mac: mac, macBuffer: make([]byte, path.MACBufferSize), buffer: gopacket.NewSerializeBuffer(), - } + }, nil } func (b *bfdSend) String() string { @@ -1624,7 +1643,7 @@ func (p *scionPacketProcessor) prepareSCMP( if err := scionL.SetDstAddr(srcA); err != nil { return nil, serrors.Wrap(cannotRoute, err, "details", "setting dest addr") } - if err := scionL.SetSrcAddr(p.d.internalIP); err != nil { + if err := scionL.SetSrcAddr(addr.HostIP(p.d.internalIP)); err != nil { return nil, serrors.Wrap(cannotRoute, err, "details", "setting src addr") } scionL.NextHdr = slayers.L4SCMP @@ -1894,7 +1913,7 @@ func interfaceToMetricLabels(id uint16, localIA addr.IA, } } -func serviceMetricLabels(localIA addr.IA, svc addr.HostSVC) prometheus.Labels { +func serviceMetricLabels(localIA addr.IA, svc addr.SVC) prometheus.Labels { return prometheus.Labels{ "isd_as": localIA.String(), "service": svc.BaseString(), @@ -1906,7 +1925,7 @@ type fakeProvider struct{} func (p *fakeProvider) GetAuthKey( _ time.Time, _ addr.IA, - _ net.Addr, + _ addr.Host, ) (drkey.Key, error) { return drkey.Key{}, nil } diff --git a/router/dataplane_test.go b/router/dataplane_test.go index d68d95336c..effd7199ca 100644 --- a/router/dataplane_test.go +++ b/router/dataplane_test.go @@ -19,6 +19,7 @@ import ( "context" "fmt" "net" + "net/netip" "sync" "syscall" "testing" @@ -50,13 +51,14 @@ import ( ) func TestDataPlaneAddInternalInterface(t *testing.T) { + internalIP := net.ParseIP("198.51.100.1") t.Run("fails after serve", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() d := &router.DataPlane{} d.FakeStart() - assert.Error(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), net.IP{})) + assert.Error(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), internalIP)) }) t.Run("setting nil value is not allowed", func(t *testing.T) { ctrl := gomock.NewController(t) @@ -70,15 +72,15 @@ func TestDataPlaneAddInternalInterface(t *testing.T) { defer ctrl.Finish() d := &router.DataPlane{} - assert.NoError(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), net.IP{})) + assert.NoError(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), internalIP)) }) t.Run("double set fails", func(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() d := &router.DataPlane{} - assert.NoError(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), net.IP{})) - assert.Error(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), net.IP{})) + assert.NoError(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), internalIP)) + assert.Error(t, d.AddInternalInterface(mock_router.NewMockBatchConn(ctrl), internalIP)) }) } @@ -278,7 +280,8 @@ func TestDataPlaneRun(t *testing.T) { YourDiscriminator: 0, } - _ = scn.SetSrcAddr(&net.IPAddr{IP: src.IP}) + srcIP, _ := netip.AddrFromSlice(src.IP) + _ = scn.SetSrcAddr(addr.HostIP(srcIP)) buffer := gopacket.NewSerializeBuffer() _ = gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{FixLengths: true}, scn, bfdL) @@ -363,7 +366,7 @@ func TestDataPlaneRun(t *testing.T) { if err != nil { return 1, nil } - if !bytes.Equal(a.(*net.IPAddr).IP, localAddr.IP) { + if !bytes.Equal(a.IP().AsSlice(), localAddr.IP) { return 1, nil } @@ -371,7 +374,7 @@ func TestDataPlaneRun(t *testing.T) { if err != nil { return 1, nil } - if !bytes.Equal(b.(*net.IPAddr).IP, remoteAddr.IP) { + if !bytes.Equal(b.IP().AsSlice(), remoteAddr.IP) { return 1, nil } @@ -581,7 +584,7 @@ func TestProcessPkt(t *testing.T) { mockMsg: func(afterProcessing bool) *ipv4.Message { spkt, dpath := prepBaseMsg(now) spkt.DstIA = xtest.MustParseIA("1-ff00:0:110") - dst := &net.IPAddr{IP: net.ParseIP("10.0.100.100").To4()} + dst := addr.MustParseHost("10.0.100.100") _ = spkt.SetDstAddr(dst) dpath.HopFields = []path.HopField{ {ConsIngress: 41, ConsEgress: 40}, @@ -592,7 +595,7 @@ func TestProcessPkt(t *testing.T) { dpath.HopFields[2].Mac = computeMAC(t, key, dpath.InfoFields[0], dpath.HopFields[2]) ret := toMsg(t, spkt, dpath) if afterProcessing { - ret.Addr = &net.UDPAddr{IP: dst.IP, Port: topology.EndhostPort} + ret.Addr = &net.UDPAddr{IP: dst.IP().AsSlice(), Port: topology.EndhostPort} ret.Flags, ret.NN, ret.N, ret.OOB = 0, 0, 0, nil } return ret @@ -787,8 +790,8 @@ func TestProcessPkt(t *testing.T) { "svc": { prepareDP: func(ctrl *gomock.Controller) *router.DataPlane { return router.NewDP(nil, nil, mock_router.NewMockBatchConn(ctrl), nil, - map[addr.HostSVC][]*net.UDPAddr{ - addr.HostSVCFromString("CS"): { + map[addr.SVC][]*net.UDPAddr{ + addr.SvcCS: { &net.UDPAddr{ IP: net.ParseIP("10.0.200.200").To4(), Port: topology.EndhostPort, @@ -799,7 +802,7 @@ func TestProcessPkt(t *testing.T) { }, mockMsg: func(afterProcessing bool) *ipv4.Message { spkt, dpath := prepBaseMsg(now) - _ = spkt.SetDstAddr(addr.HostSVCFromString("CS")) + _ = spkt.SetDstAddr(addr.MustParseHost("CS")) spkt.DstIA = xtest.MustParseIA("1-ff00:0:110") dpath.HopFields = []path.HopField{ {ConsIngress: 41, ConsEgress: 40}, @@ -822,12 +825,12 @@ func TestProcessPkt(t *testing.T) { "svc nobackend": { prepareDP: func(ctrl *gomock.Controller) *router.DataPlane { return router.NewDP(nil, nil, mock_router.NewMockBatchConn(ctrl), nil, - map[addr.HostSVC][]*net.UDPAddr{}, + map[addr.SVC][]*net.UDPAddr{}, xtest.MustParseIA("1-ff00:0:110"), nil, key) }, mockMsg: func(afterProcessing bool) *ipv4.Message { spkt, dpath := prepBaseMsg(now) - _ = spkt.SetDstAddr(addr.HostSVCFromString("CS")) + _ = spkt.SetDstAddr(addr.MustParseHost("CS")) spkt.DstIA = xtest.MustParseIA("1-ff00:0:110") dpath.HopFields = []path.HopField{ {ConsIngress: 41, ConsEgress: 40}, @@ -845,12 +848,12 @@ func TestProcessPkt(t *testing.T) { "svc invalid": { prepareDP: func(ctrl *gomock.Controller) *router.DataPlane { return router.NewDP(nil, nil, mock_router.NewMockBatchConn(ctrl), nil, - map[addr.HostSVC][]*net.UDPAddr{}, + map[addr.SVC][]*net.UDPAddr{}, xtest.MustParseIA("1-ff00:0:110"), nil, key) }, mockMsg: func(afterProcessing bool) *ipv4.Message { spkt, dpath := prepBaseMsg(now) - _ = spkt.SetDstAddr(addr.HostSVCFromString("BS")) + _ = spkt.SetDstAddr(addr.MustParseHost("CS")) spkt.DstIA = xtest.MustParseIA("1-ff00:0:110") dpath.HopFields = []path.HopField{ {ConsIngress: 41, ConsEgress: 40}, @@ -871,7 +874,7 @@ func TestProcessPkt(t *testing.T) { nil, nil, mock_router.NewMockBatchConn(ctrl), nil, - map[addr.HostSVC][]*net.UDPAddr{ + map[addr.SVC][]*net.UDPAddr{ addr.SvcCS: {&net.UDPAddr{ IP: net.ParseIP("172.0.2.10"), Port: topology.EndhostPort, @@ -887,7 +890,7 @@ func TestProcessPkt(t *testing.T) { spkt.PathType = onehop.PathType spkt.SrcIA = xtest.MustParseIA("1-ff00:0:111") spkt.DstIA = xtest.MustParseIA("1-ff00:0:110") - err := spkt.SetDstAddr(addr.SVCMcast | addr.SvcCS) + err := spkt.SetDstAddr(addr.HostSVC(addr.SvcCS.Multicast())) require.NoError(t, err) dpath := &onehop.Path{ Info: path.InfoField{ @@ -941,7 +944,7 @@ func TestProcessPkt(t *testing.T) { spkt.PathType = onehop.PathType spkt.SrcIA = xtest.MustParseIA("1-ff00:0:110") // sneaky spkt.DstIA = xtest.MustParseIA("1-ff00:0:111") - err := spkt.SetDstAddr(addr.SVCMcast | addr.SvcCS) + err := spkt.SetDstAddr(addr.HostSVC(addr.SvcCS.Multicast())) require.NoError(t, err) dpath := &onehop.Path{ Info: path.InfoField{ @@ -971,7 +974,7 @@ func TestProcessPkt(t *testing.T) { }, nil, mock_router.NewMockBatchConn(ctrl), nil, - map[addr.HostSVC][]*net.UDPAddr{ + map[addr.SVC][]*net.UDPAddr{ addr.SvcCS: {&net.UDPAddr{ IP: net.ParseIP("172.0.2.10"), Port: topology.EndhostPort, @@ -983,7 +986,7 @@ func TestProcessPkt(t *testing.T) { spkt, _ := prepBaseMsg(now) spkt.PathType = scion.PathType spkt.SrcIA = xtest.MustParseIA("1-ff00:0:110") - err := spkt.SetDstAddr(addr.SVCMcast | addr.SvcCS) + err := spkt.SetDstAddr(addr.HostSVC(addr.SvcCS.Multicast())) require.NoError(t, err) dpath := &onehop.Path{ Info: path.InfoField{ @@ -1041,7 +1044,7 @@ func TestProcessPkt(t *testing.T) { spkt.PathType = onehop.PathType spkt.SrcIA = xtest.MustParseIA("1-ff00:0:110") spkt.DstIA = xtest.MustParseIA("1-ff00:0:111") - err := spkt.SetDstAddr(addr.SVCMcast | addr.SvcCS) + err := spkt.SetDstAddr(addr.HostSVC(addr.SvcCS.Multicast())) require.NoError(t, err) dpath := &onehop.Path{ Info: path.InfoField{ @@ -1071,7 +1074,7 @@ func TestProcessPkt(t *testing.T) { "invalid dest": { prepareDP: func(ctrl *gomock.Controller) *router.DataPlane { return router.NewDP(nil, nil, mock_router.NewMockBatchConn(ctrl), nil, - map[addr.HostSVC][]*net.UDPAddr{}, + map[addr.SVC][]*net.UDPAddr{}, xtest.MustParseIA("1-ff00:0:110"), nil, key) }, mockMsg: func(afterProcessing bool) *ipv4.Message { @@ -1260,7 +1263,8 @@ func prepEpicMsg(t *testing.T, afterProcessing bool, key []byte, PHVF: make([]byte, 4), LHVF: make([]byte, 4), } - require.NoError(t, spkt.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("10.0.200.200").To4()})) + require.NoError(t, spkt.SetSrcAddr(addr.MustParseHost("10.0.200.200"))) + spkt.Path = epicpath return spkt, epicpath, dpath @@ -1287,11 +1291,11 @@ func prepareEpicCrypto(t *testing.T, spkt *slayers.SCION, func toIP(t *testing.T, spkt *slayers.SCION, path path.Path, afterProcessing bool) *ipv4.Message { // Encapsulate in IPv4 - dst := &net.IPAddr{IP: net.ParseIP("10.0.100.100").To4()} + dst := addr.MustParseHost("10.0.100.100") require.NoError(t, spkt.SetDstAddr(dst)) ret := toMsg(t, spkt, path) if afterProcessing { - ret.Addr = &net.UDPAddr{IP: dst.IP, Port: topology.EndhostPort} + ret.Addr = &net.UDPAddr{IP: dst.IP().AsSlice(), Port: topology.EndhostPort} ret.Flags, ret.NN, ret.N, ret.OOB = 0, 0, 0, nil } return ret diff --git a/router/export_test.go b/router/export_test.go index 3a9acc5c80..186bbeede8 100644 --- a/router/export_test.go +++ b/router/export_test.go @@ -16,6 +16,7 @@ package router import ( "net" + "net/netip" "golang.org/x/net/ipv4" @@ -36,7 +37,7 @@ func NewDP( linkTypes map[uint16]topology.LinkType, internal BatchConn, internalNextHops map[uint16]*net.UDPAddr, - svc map[addr.HostSVC][]*net.UDPAddr, + svc map[addr.SVC][]*net.UDPAddr, local addr.IA, neighbors map[uint16]addr.IA, key []byte) *DataPlane { @@ -49,7 +50,7 @@ func NewDP( internalNextHops: internalNextHops, svc: &services{m: svc}, internal: internal, - internalIP: &net.IPAddr{IP: net.ParseIP("198.51.100.1")}, + internalIP: netip.MustParseAddr("198.51.100.1"), } if err := dp.SetKey(key); err != nil { panic(err) @@ -74,6 +75,6 @@ func (d *DataPlane) ProcessPkt(ifID uint16, m *ipv4.Message) (ProcessResult, err return ProcessResult{processResult: result}, err } -func ExtractServices(s *services) map[addr.HostSVC][]*net.UDPAddr { +func ExtractServices(s *services) map[addr.SVC][]*net.UDPAddr { return s.m } diff --git a/router/svc.go b/router/svc.go index 98f14042bc..a86800b771 100644 --- a/router/svc.go +++ b/router/svc.go @@ -24,14 +24,14 @@ import ( type services struct { mtx sync.Mutex - m map[addr.HostSVC][]*net.UDPAddr + m map[addr.SVC][]*net.UDPAddr } func newServices() *services { - return &services{m: make(map[addr.HostSVC][]*net.UDPAddr)} + return &services{m: make(map[addr.SVC][]*net.UDPAddr)} } -func (s *services) AddSvc(svc addr.HostSVC, a *net.UDPAddr) { +func (s *services) AddSvc(svc addr.SVC, a *net.UDPAddr) { s.mtx.Lock() defer s.mtx.Unlock() @@ -42,7 +42,7 @@ func (s *services) AddSvc(svc addr.HostSVC, a *net.UDPAddr) { s.m[svc] = append(addrs, a) } -func (s *services) DelSvc(svc addr.HostSVC, a *net.UDPAddr) { +func (s *services) DelSvc(svc addr.SVC, a *net.UDPAddr) { s.mtx.Lock() defer s.mtx.Unlock() @@ -56,7 +56,7 @@ func (s *services) DelSvc(svc addr.HostSVC, a *net.UDPAddr) { s.m[svc] = addrs[:len(addrs)-1] } -func (s *services) Any(svc addr.HostSVC) (*net.UDPAddr, bool) { +func (s *services) Any(svc addr.SVC) (*net.UDPAddr, bool) { s.mtx.Lock() defer s.mtx.Unlock() diff --git a/scion-pki/certs/renew.go b/scion-pki/certs/renew.go index 498b6d2770..eea541680f 100644 --- a/scion-pki/certs/renew.go +++ b/scion-pki/certs/renew.go @@ -505,7 +505,7 @@ The template is expressed in JSON. A valid example:: switch { case len(cas) > 0: for _, ca := range cas { - remote := addr.SvcCS + remote := &snet.SVCAddr{SVC: addr.SvcCS} chain, err := request(ca, remote) if err != nil { continue @@ -647,9 +647,9 @@ func (r *renewer) requestLocal( ) ([]*x509.Certificate, error) { dialer := &grpc.TCPDialer{ - SvcResolver: func(hs addr.HostSVC) []resolver.Address { + SvcResolver: func(hs addr.SVC) []resolver.Address { // Do the SVC resolution - entries, err := r.Daemon.SVCInfo(ctx, []addr.HostSVC{hs}) + entries, err := r.Daemon.SVCInfo(ctx, []addr.SVC{hs}) if err != nil { fmt.Fprintf(r.StdErr, "Failed to resolve SVC address: %s\n", err) return nil @@ -709,10 +709,10 @@ func (r *renewer) requestRemote( Path: path.Dataplane(), NextHop: path.UnderlayNextHop(), } - case addr.HostSVC: + case *snet.SVCAddr: dst = &snet.SVCAddr{ IA: ca, - SVC: r, + SVC: r.SVC, Path: path.Dataplane(), NextHop: path.UnderlayNextHop(), } @@ -960,7 +960,7 @@ type svcRouter struct { Connector daemon.Connector } -func (r svcRouter) GetUnderlay(svc addr.HostSVC) (*net.UDPAddr, error) { +func (r svcRouter) GetUnderlay(svc addr.SVC) (*net.UDPAddr, error) { // XXX(karampok). We need to change the interface to not use TODO context. return daemon.TopoQuerier{Connector: r.Connector}.UnderlayAnycast(context.TODO(), svc) } diff --git a/scion/ping/util.go b/scion/ping/util.go index dd89ffbc8f..a9a1d25ddb 100644 --- a/scion/ping/util.go +++ b/scion/ping/util.go @@ -15,6 +15,8 @@ package ping import ( + "net/netip" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/snet" @@ -39,15 +41,23 @@ func pack(local, remote *snet.UDPAddr, req snet.SCMPEchoRequest) (*snet.Packet, if isEmpty && !local.IA.Equal(remote.IA) { return nil, serrors.New("no path for remote ISD-AS", "local", local.IA, "remote", remote.IA) } + remoteHostIP, ok := netip.AddrFromSlice(remote.Host.IP) + if !ok { + return nil, serrors.New("invalid remote host IP", "ip", remote.Host.IP) + } + localHostIP, ok := netip.AddrFromSlice(local.Host.IP) + if !ok { + return nil, serrors.New("invalid local host IP", "ip", local.Host.IP) + } pkt := &snet.Packet{ PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: remote.IA, - Host: addr.HostFromIP(remote.Host.IP), + Host: addr.HostIP(remoteHostIP), }, Source: snet.SCIONAddress{ IA: local.IA, - Host: addr.HostFromIP(local.Host.IP), + Host: addr.HostIP(localHostIP), }, Path: remote.Path, Payload: req, diff --git a/scion/showpaths/showpaths.go b/scion/showpaths/showpaths.go index 25475696db..37e328fd31 100644 --- a/scion/showpaths/showpaths.go +++ b/scion/showpaths/showpaths.go @@ -20,7 +20,7 @@ import ( "io" "math" "math/rand" - "net" + "net/netip" "strconv" "strings" "time" @@ -54,7 +54,7 @@ type Path struct { Latency []time.Duration `json:"latency" yaml:"latency"` Status string `json:"status,omitempty" yaml:"status,omitempty"` StatusInfo string `json:"status_info,omitempty" yaml:"status_info,omitempty"` - Local net.IP `json:"local_ip,omitempty" yaml:"local_ip,omitempty"` + Local netip.Addr `json:"local_ip,omitempty" yaml:"local_ip,omitempty"` } // Hop represents an hop on the path. diff --git a/scion/traceroute/traceroute.go b/scion/traceroute/traceroute.go index 8c9c75251c..d2805a30bc 100644 --- a/scion/traceroute/traceroute.go +++ b/scion/traceroute/traceroute.go @@ -19,6 +19,7 @@ import ( "context" "math/rand" "net" + "net/netip" "time" "github.com/scionproto/scion/pkg/addr" @@ -223,15 +224,24 @@ func (t *tracerouter) probeHop(ctx context.Context, hfIdx uint8, egress bool) (U RTTs: make([]time.Duration, 0, t.probesPerHop), } t.index++ + + remoteHostIP, ok := netip.AddrFromSlice(t.remote.Host.IP) + if !ok { + return Update{}, serrors.New("invalid remote host IP", "ip", t.remote.Host.IP) + } + localHostIP, ok := netip.AddrFromSlice(t.local.Host.IP) + if !ok { + return Update{}, serrors.New("invalid local host IP", "ip", t.local.Host.IP) + } pkt := &snet.Packet{ PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: t.remote.IA, - Host: addr.HostFromIP(t.remote.Host.IP), + Host: addr.HostIP(remoteHostIP), }, Source: snet.SCIONAddress{ IA: t.local.IA, - Host: addr.HostFromIP(t.local.Host.IP), + Host: addr.HostIP(localHostIP), }, Path: alertPath, Payload: snet.SCMPTracerouteRequest{Identifier: t.id}, @@ -310,11 +320,8 @@ func (h scmpHandler) Handle(pkt *snet.Packet) error { h.replies <- reply{ Received: time.Now(), Reply: r, - Remote: snet.SCIONAddress{ - IA: pkt.Source.IA, - Host: pkt.Source.Host.Copy(), - }, - Error: err, + Remote: pkt.Source, + Error: err, } return nil } diff --git a/tools/braccept/cases/bfd.go b/tools/braccept/cases/bfd.go index 2b901bb8d5..e178869caa 100644 --- a/tools/braccept/cases/bfd.go +++ b/tools/braccept/cases/bfd.go @@ -102,11 +102,11 @@ func ExternalBFD(artifactsDir string, mac hash.Hash) runner.Case { DstIA: localIA, SrcIA: remoteIA, } - err := scionL.SetSrcAddr(&net.IPAddr{IP: net.IP{192, 168, 13, 3}}) + err := scionL.SetSrcAddr(addr.MustParseHost("192.168.13.3")) if err != nil { panic(err) } - err = scionL.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 13, 2}}) + err = scionL.SetDstAddr(addr.MustParseHost("192.168.13.2")) if err != nil { panic(err) } @@ -134,11 +134,11 @@ func ExternalBFD(artifactsDir string, mac hash.Hash) runner.Case { udp.SrcPort, udp.DstPort = udp.DstPort, udp.SrcPort scionL.DstIA = remoteIA scionL.SrcIA = localIA - err = scionL.SetSrcAddr(&net.IPAddr{IP: net.IP{192, 168, 13, 2}}) + err = scionL.SetSrcAddr(addr.MustParseHost("192.168.13.2")) if err != nil { panic(err) } - err = scionL.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 13, 3}}) + err = scionL.SetDstAddr(addr.MustParseHost("192.168.13.3")) if err != nil { panic(err) } @@ -198,11 +198,11 @@ func InternalBFD(artifactsDir string, mac hash.Hash) runner.Case { SrcIA: localIA, DstIA: localIA, } - err := scionL.SetSrcAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 13}}) + err := scionL.SetSrcAddr(addr.MustParseHost("192.168.0.13")) if err != nil { panic(err) } - err = scionL.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 11}}) + err = scionL.SetDstAddr(addr.MustParseHost("192.168.0.11")) if err != nil { panic(err) } @@ -228,11 +228,11 @@ func InternalBFD(artifactsDir string, mac hash.Hash) runner.Case { ip.SrcIP = net.IP{192, 168, 0, 11} ip.DstIP = net.IP{192, 168, 0, 13} udp.SrcPort, udp.DstPort = udp.DstPort, udp.SrcPort - err = scionL.SetSrcAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 11}}) + err = scionL.SetSrcAddr(addr.MustParseHost("192.168.0.11")) if err != nil { panic(err) } - err = scionL.SetDstAddr(&net.IPAddr{IP: net.IP{192, 168, 0, 13}}) + err = scionL.SetDstAddr(addr.MustParseHost("192.168.0.13")) if err != nil { panic(err) } diff --git a/tools/braccept/cases/child_to_child_xover.go b/tools/braccept/cases/child_to_child_xover.go index 0371d9ffdf..74ec549e90 100644 --- a/tools/braccept/cases/child_to_child_xover.go +++ b/tools/braccept/cases/child_to_child_xover.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -107,10 +108,10 @@ func ChildToChildXover(artifactsDir string, mac hash.Hash) runner.Case { Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.5.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.5.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/child_to_internal.go b/tools/braccept/cases/child_to_internal.go index aadbb33cfb..88d5fcdcb9 100644 --- a/tools/braccept/cases/child_to_internal.go +++ b/tools/braccept/cases/child_to_internal.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -96,10 +97,10 @@ func ChildToInternalHost(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:1"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.4.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("192.168.0.51")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("192.168.0.51")); err != nil { panic(err) } @@ -203,10 +204,10 @@ func ChildToInternalHostShortcut(artifactsDir string, mac hash.Hash) runner.Case DstIA: xtest.MustParseIA("1-ff00:0:1"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.4.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("192.168.0.51")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("192.168.0.51")); err != nil { panic(err) } @@ -321,10 +322,10 @@ func ChildToInternalParent(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:9"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.4.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("172.16.9.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("172.16.9.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/child_to_parent.go b/tools/braccept/cases/child_to_parent.go index c09910e529..fb6f24092f 100644 --- a/tools/braccept/cases/child_to_parent.go +++ b/tools/braccept/cases/child_to_parent.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -104,10 +105,10 @@ func ChildToParent(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:3"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.4.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.3.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.3.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/internal_to_child.go b/tools/braccept/cases/internal_to_child.go index a717bcf0b4..5587e6141b 100644 --- a/tools/braccept/cases/internal_to_child.go +++ b/tools/braccept/cases/internal_to_child.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -100,10 +101,10 @@ func InternalHostToChild(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("192.168.0.51")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("192.168.0.51")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -226,10 +227,10 @@ func InternalParentToChild(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("174.16.9.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("174.16.9.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -353,10 +354,10 @@ func InvalidSrcInternalParentToChild(artifactsDir string, mac hash.Hash) runner. DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("174.16.9.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("174.16.9.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/jumbo.go b/tools/braccept/cases/jumbo.go index f93faac33d..b2695264c1 100644 --- a/tools/braccept/cases/jumbo.go +++ b/tools/braccept/cases/jumbo.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -104,10 +105,10 @@ func JumboPacket(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.3.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.3.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/onehop.go b/tools/braccept/cases/onehop.go index 06ec117b17..56890a6139 100644 --- a/tools/braccept/cases/onehop.go +++ b/tools/braccept/cases/onehop.go @@ -24,6 +24,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -78,10 +79,10 @@ func IncomingOneHop(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:1"), Path: ohp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.4.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("192.168.0.71")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("192.168.0.71")); err != nil { panic(err) } @@ -173,10 +174,10 @@ func OutgoingOneHop(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: ohp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("192.168.0.71")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("192.168.0.71")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("172.16.4.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/parent_to_child.go b/tools/braccept/cases/parent_to_child.go index ebf1d657f4..39615aa10a 100644 --- a/tools/braccept/cases/parent_to_child.go +++ b/tools/braccept/cases/parent_to_child.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -104,10 +105,10 @@ func ParentToChild(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.3.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.3.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/parent_to_internal.go b/tools/braccept/cases/parent_to_internal.go index 0026bd121b..cdc77ac649 100644 --- a/tools/braccept/cases/parent_to_internal.go +++ b/tools/braccept/cases/parent_to_internal.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -91,10 +92,10 @@ func ParentToInternalHost(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:1"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.3.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.3.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("192.168.0.51")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("192.168.0.51")); err != nil { panic(err) } @@ -205,10 +206,10 @@ func ParentToInternalHostMultiSegment(artifactsDir string, mac hash.Hash) runner DstIA: xtest.MustParseIA("1-ff00:0:1"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.3.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.3.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("192.168.0.51")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("192.168.0.51")); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_dest_unreachable.go b/tools/braccept/cases/scmp_dest_unreachable.go index 23009632eb..6af4ff1eb3 100644 --- a/tools/braccept/cases/scmp_dest_unreachable.go +++ b/tools/braccept/cases/scmp_dest_unreachable.go @@ -95,8 +95,8 @@ func SCMPDestinationUnreachable(artifactsDir string, mac hash.Hash) runner.Case DstIA: xtest.MustParseIA("1-ff00:0:1"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1")} - dstA := addr.HostSVC(15) + srcA := addr.MustParseHost("172.16.3.1") + dstA := addr.HostSVC(addr.SVC(15)) if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } @@ -135,7 +135,7 @@ func SCMPDestinationUnreachable(artifactsDir string, mac hash.Hash) runner.Case if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_expired_hop.go b/tools/braccept/cases/scmp_expired_hop.go index 371ff440cf..02a886cea5 100644 --- a/tools/braccept/cases/scmp_expired_hop.go +++ b/tools/braccept/cases/scmp_expired_hop.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -105,11 +106,11 @@ func SCMPExpiredHop(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -214,11 +215,11 @@ func SCMPExpiredHopMessageBack(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -255,7 +256,7 @@ func SCMPExpiredHopMessageBack(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -380,11 +381,11 @@ func SCMPExpiredHopAfterXoverMessageBack(artifactsDir string, mac hash.Hash) run Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1").To4()} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -431,7 +432,7 @@ func SCMPExpiredHopAfterXoverMessageBack(artifactsDir string, mac hash.Hash) run if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -556,11 +557,11 @@ func SCMPExpiredHopAfterXoverConsDirMessageBack(artifactsDir string, mac hash.Ha Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1").To4()} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -607,7 +608,7 @@ func SCMPExpiredHopAfterXoverConsDirMessageBack(artifactsDir string, mac hash.Ha if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -736,11 +737,11 @@ func SCMPExpiredHopAfterXoverInternalMessageBack(artifactsDir string, mac hash.H Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1").To4()} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -781,7 +782,7 @@ func SCMPExpiredHopAfterXoverInternalMessageBack(artifactsDir string, mac hash.H if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -907,11 +908,11 @@ func SCMPExpiredHopAfterXoverInternalConsDirMessageBack( Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1").To4()} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -952,7 +953,7 @@ func SCMPExpiredHopAfterXoverInternalConsDirMessageBack( if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_invalid_hop.go b/tools/braccept/cases/scmp_invalid_hop.go index 36b9a9339a..c458e12622 100644 --- a/tools/braccept/cases/scmp_invalid_hop.go +++ b/tools/braccept/cases/scmp_invalid_hop.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -97,11 +98,11 @@ func SCMPInvalidHopParentToParent(artifactsDir string, mac hash.Hash) runner.Cas DstIA: xtest.MustParseIA("1-ff00:0:9"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -146,7 +147,7 @@ func SCMPInvalidHopParentToParent(artifactsDir string, mac hash.Hash) runner.Cas if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -258,11 +259,11 @@ func SCMPInvalidHopChildToChild(artifactsDir string, mac hash.Hash) runner.Case DstIA: xtest.MustParseIA("1-ff00:0:5"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -307,7 +308,7 @@ func SCMPInvalidHopChildToChild(artifactsDir string, mac hash.Hash) runner.Case if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_invalid_ia.go b/tools/braccept/cases/scmp_invalid_ia.go index d5115bf670..f501ff308d 100644 --- a/tools/braccept/cases/scmp_invalid_ia.go +++ b/tools/braccept/cases/scmp_invalid_ia.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -99,11 +100,11 @@ func SCMPInvalidSrcIAInternalHostToChild(artifactsDir string, mac hash.Hash) run DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("192.168.0.51")} + srcA := addr.MustParseHost("192.168.0.51") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -136,7 +137,7 @@ func SCMPInvalidSrcIAInternalHostToChild(artifactsDir string, mac hash.Hash) run if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -246,11 +247,11 @@ func SCMPInvalidDstIAInternalHostToChild(artifactsDir string, mac hash.Hash) run DstIA: xtest.MustParseIA("1-ff00:0:1"), // == local IA, invalid Dst IA Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("192.168.0.51")} + srcA := addr.MustParseHost("192.168.0.51") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -283,7 +284,7 @@ func SCMPInvalidDstIAInternalHostToChild(artifactsDir string, mac hash.Hash) run if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -397,11 +398,11 @@ func SCMPInvalidSrcIAChildToParent(artifactsDir string, mac hash.Hash) runner.Ca DstIA: xtest.MustParseIA("1-ff00:0:3"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.4.1")} + srcA := addr.MustParseHost("172.16.4.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.3.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.3.1")); err != nil { panic(err) } @@ -434,7 +435,7 @@ func SCMPInvalidSrcIAChildToParent(artifactsDir string, mac hash.Hash) runner.Ca if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -553,11 +554,11 @@ func SCMPInvalidDstIAChildToParent(artifactsDir string, mac hash.Hash) runner.Ca DstIA: xtest.MustParseIA("1-ff00:0:1"), // == local IA, invalid Dst IA Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.4.1")} + srcA := addr.MustParseHost("172.16.4.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.3.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.3.1")); err != nil { panic(err) } @@ -590,7 +591,7 @@ func SCMPInvalidDstIAChildToParent(artifactsDir string, mac hash.Hash) runner.Ca if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_invalid_mac.go b/tools/braccept/cases/scmp_invalid_mac.go index 42d7334e91..ce94c1c20a 100644 --- a/tools/braccept/cases/scmp_invalid_mac.go +++ b/tools/braccept/cases/scmp_invalid_mac.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -103,11 +104,11 @@ func SCMPBadMAC(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1")} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -144,7 +145,7 @@ func SCMPBadMAC(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -259,11 +260,11 @@ func SCMPBadMACInternal(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1")} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -300,7 +301,7 @@ func SCMPBadMACInternal(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_invalid_pkt.go b/tools/braccept/cases/scmp_invalid_pkt.go index ec2c76d0d7..bf61dcd9cc 100644 --- a/tools/braccept/cases/scmp_invalid_pkt.go +++ b/tools/braccept/cases/scmp_invalid_pkt.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -92,11 +93,11 @@ func SCMPBadPktLen(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -138,7 +139,7 @@ func SCMPBadPktLen(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -246,11 +247,11 @@ func SCMPQuoteCut(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -296,7 +297,7 @@ func SCMPQuoteCut(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -407,11 +408,11 @@ func NoSCMPReplyForSCMPError(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_invalid_segment_change.go b/tools/braccept/cases/scmp_invalid_segment_change.go index 36dd425aea..20d52c2e6b 100644 --- a/tools/braccept/cases/scmp_invalid_segment_change.go +++ b/tools/braccept/cases/scmp_invalid_segment_change.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -106,11 +107,11 @@ func SCMPParentToParentXover(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:9"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -155,7 +156,7 @@ func SCMPParentToParentXover(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -281,11 +282,11 @@ func SCMPParentToChildXover(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:8"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -330,7 +331,7 @@ func SCMPParentToChildXover(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -458,11 +459,11 @@ func SCMPChildToParentXover(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:9"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -508,7 +509,7 @@ func SCMPChildToParentXover(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -636,11 +637,11 @@ func SCMPInternalXover(artifactsDir string, mac hash.Hash) runner.Case { Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.168.0.14").To4()} + srcA := addr.MustParseHost("172.168.0.14") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - dstA := &net.IPAddr{IP: net.ParseIP("172.16.4.1").To4()} + dstA := addr.MustParseHost("172.16.4.1") if err := scionL.SetDstAddr(dstA); err != nil { panic(err) } @@ -687,7 +688,7 @@ func SCMPInternalXover(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_invalid_segment_change_local.go b/tools/braccept/cases/scmp_invalid_segment_change_local.go index dd019f9122..e0198c686d 100644 --- a/tools/braccept/cases/scmp_invalid_segment_change_local.go +++ b/tools/braccept/cases/scmp_invalid_segment_change_local.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -106,11 +107,11 @@ func SCMPParentToParentLocalXover(artifactsDir string, mac hash.Hash) runner.Cas DstIA: xtest.MustParseIA("1-ff00:0:3"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -155,7 +156,7 @@ func SCMPParentToParentLocalXover(artifactsDir string, mac hash.Hash) runner.Cas if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -281,11 +282,11 @@ func SCMPParentToChildLocalXover(artifactsDir string, mac hash.Hash) runner.Case DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -330,7 +331,7 @@ func SCMPParentToChildLocalXover(artifactsDir string, mac hash.Hash) runner.Case if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -458,11 +459,11 @@ func SCMPChildToParentLocalXover(artifactsDir string, mac hash.Hash) runner.Case DstIA: xtest.MustParseIA("1-ff00:0:3"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.5.1")} + srcA := addr.MustParseHost("172.16.5.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -508,7 +509,7 @@ func SCMPChildToParentLocalXover(artifactsDir string, mac hash.Hash) runner.Case if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_traceroute.go b/tools/braccept/cases/scmp_traceroute.go index 271358d4b9..6242efe1ef 100644 --- a/tools/braccept/cases/scmp_traceroute.go +++ b/tools/braccept/cases/scmp_traceroute.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" @@ -95,11 +96,11 @@ func SCMPTracerouteIngress(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:2"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.4.1").To4()} + srcA := addr.MustParseHost("172.16.4.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.2.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.2.1")); err != nil { panic(err) } @@ -131,7 +132,7 @@ func SCMPTracerouteIngress(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -237,11 +238,11 @@ func SCMPTracerouteIngressWithSPAO(artifactsDir string, mac hash.Hash) runner.Ca DstIA: xtest.MustParseIA("1-ff00:0:2"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.4.1").To4()} + srcA := addr.MustParseHost("172.16.4.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.2.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.2.1")); err != nil { panic(err) } @@ -311,7 +312,7 @@ func SCMPTracerouteIngressWithSPAO(artifactsDir string, mac hash.Hash) runner.Ca if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -440,11 +441,11 @@ func SCMPTracerouteIngressConsDir(artifactsDir string, mac hash.Hash) runner.Cas DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -481,7 +482,7 @@ func SCMPTracerouteIngressConsDir(artifactsDir string, mac hash.Hash) runner.Cas if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -585,11 +586,11 @@ func SCMPTracerouteEgress(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:3"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.4.1").To4()} + srcA := addr.MustParseHost("172.16.4.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.2.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.2.1")); err != nil { panic(err) } @@ -621,7 +622,7 @@ func SCMPTracerouteEgress(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -724,11 +725,11 @@ func SCMPTracerouteEgressConsDir(artifactsDir string, mac hash.Hash) runner.Case DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -765,7 +766,7 @@ func SCMPTracerouteEgressConsDir(artifactsDir string, mac hash.Hash) runner.Case if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -884,11 +885,11 @@ func SCMPTracerouteEgressAfterXover(artifactsDir string, mac hash.Hash) runner.C Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.8.1").To4()} + srcA := addr.MustParseHost("172.16.8.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - dstA := &net.IPAddr{IP: net.ParseIP("172.16.4.1").To4()} + dstA := addr.MustParseHost("172.16.4.1") if err := scionL.SetDstAddr(dstA); err != nil { panic(err) } @@ -922,7 +923,7 @@ func SCMPTracerouteEgressAfterXover(artifactsDir string, mac hash.Hash) runner.C if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -1024,11 +1025,11 @@ func SCMPTracerouteInternal(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("192.168.0.51").To4()} + srcA := addr.MustParseHost("192.168.0.51") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -1061,7 +1062,7 @@ func SCMPTracerouteInternal(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/scmp_unknown_hop.go b/tools/braccept/cases/scmp_unknown_hop.go index af7fdf278e..f4c48b4d4b 100644 --- a/tools/braccept/cases/scmp_unknown_hop.go +++ b/tools/braccept/cases/scmp_unknown_hop.go @@ -23,6 +23,7 @@ import ( "github.com/google/gopacket" "github.com/google/gopacket/layers" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/slayers" @@ -104,11 +105,11 @@ func SCMPUnknownHop(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:4"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1").To4()} + srcA := addr.MustParseHost("172.16.3.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.4.1").To4()}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.4.1")); err != nil { panic(err) } @@ -145,7 +146,7 @@ func SCMPUnknownHop(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } @@ -262,8 +263,8 @@ func SCMPUnknownHopEgress(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:f1"), Path: sp, } - srcA := &net.IPAddr{IP: net.ParseIP("172.16.3.1")} - dstA := &net.IPAddr{IP: net.ParseIP("174.16.16.1")} + srcA := addr.MustParseHost("172.16.3.1") + dstA := addr.MustParseHost("174.16.16.1") if err := scionL.SetSrcAddr(srcA); err != nil { panic(err) } @@ -304,7 +305,7 @@ func SCMPUnknownHopEgress(artifactsDir string, mac hash.Hash) runner.Case { if err := scionL.SetDstAddr(srcA); err != nil { panic(err) } - intlA := &net.IPAddr{IP: net.IP{192, 168, 0, 11}} + intlA := addr.MustParseHost("192.168.0.11") if err := scionL.SetSrcAddr(intlA); err != nil { panic(err) } diff --git a/tools/braccept/cases/svc.go b/tools/braccept/cases/svc.go index 913255fe21..220522a031 100644 --- a/tools/braccept/cases/svc.go +++ b/tools/braccept/cases/svc.go @@ -95,10 +95,10 @@ func SVC(artifactsDir string, mac hash.Hash) runner.Case { DstIA: xtest.MustParseIA("1-ff00:0:1"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP("172.16.4.1")}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost("172.16.4.1")); err != nil { panic(err) } - if err := scionL.SetDstAddr(addr.HostSVCFromString("CS")); err != nil { + if err := scionL.SetDstAddr(addr.HostSVC(addr.SvcCS)); err != nil { panic(err) } scionudp := &slayers.UDP{} diff --git a/tools/braccept/runner/BUILD.bazel b/tools/braccept/runner/BUILD.bazel index 18ef04a7a8..4c66b4c9ad 100644 --- a/tools/braccept/runner/BUILD.bazel +++ b/tools/braccept/runner/BUILD.bazel @@ -27,6 +27,7 @@ go_test( srcs = ["compare_test.go"], embed = [":go_default_library"], deps = [ + "//pkg/addr:go_default_library", "//pkg/private/util:go_default_library", "//pkg/private/xtest:go_default_library", "//pkg/scrypto:go_default_library", diff --git a/tools/braccept/runner/compare_test.go b/tools/braccept/runner/compare_test.go index a827dd07e2..d2f8b327db 100644 --- a/tools/braccept/runner/compare_test.go +++ b/tools/braccept/runner/compare_test.go @@ -15,13 +15,13 @@ package runner import ( - "net" "testing" "time" "github.com/google/gopacket" "github.com/stretchr/testify/assert" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/scrypto" @@ -93,10 +93,10 @@ func prepareSCION(t *testing.T, diff string) gopacket.Packet { DstIA: xtest.MustParseIA("1-ff00:0:3"), Path: sp, } - if err := scionL.SetSrcAddr(&net.IPAddr{IP: net.ParseIP(diff)}); err != nil { + if err := scionL.SetSrcAddr(addr.MustParseHost(diff)); err != nil { assert.NoError(t, err) } - if err := scionL.SetDstAddr(&net.IPAddr{IP: net.ParseIP("174.16.3.1")}); err != nil { + if err := scionL.SetDstAddr(addr.MustParseHost("174.16.3.1")); err != nil { assert.NoError(t, err) } diff --git a/tools/end2end/main.go b/tools/end2end/main.go index 4db1e04f53..1018f2247c 100644 --- a/tools/end2end/main.go +++ b/tools/end2end/main.go @@ -23,6 +23,7 @@ import ( "flag" "fmt" "net" + "net/netip" "os" "time" @@ -331,15 +332,24 @@ func (c *client) ping(ctx context.Context, n int, path snet.Path) error { Port: topology.EndhostPort, } } + + remoteHostIP, ok := netip.AddrFromSlice(remote.Host.IP) + if !ok { + return serrors.New("invalid remote host IP", "ip", remote.Host.IP) + } + localHostIP, ok := netip.AddrFromSlice(integration.Local.Host.IP) + if !ok { + return serrors.New("invalid local host IP", "ip", integration.Local.Host.IP) + } pkt := &snet.Packet{ PacketInfo: snet.PacketInfo{ Destination: snet.SCIONAddress{ IA: remote.IA, - Host: addr.HostFromIP(remote.Host.IP), + Host: addr.HostIP(remoteHostIP), }, Source: snet.SCIONAddress{ IA: integration.Local.IA, - Host: addr.HostFromIP(integration.Local.Host.IP), + Host: addr.HostIP(localHostIP), }, Path: remote.Path, Payload: snet.UDPPayload{ diff --git a/tools/pktgen/cmd/pktgen/BUILD.bazel b/tools/pktgen/cmd/pktgen/BUILD.bazel index 4636177a86..d03afafbc8 100644 --- a/tools/pktgen/cmd/pktgen/BUILD.bazel +++ b/tools/pktgen/cmd/pktgen/BUILD.bazel @@ -10,6 +10,7 @@ go_library( importpath = "github.com/scionproto/scion/tools/pktgen/cmd/pktgen", visibility = ["//visibility:private"], deps = [ + "//pkg/addr:go_default_library", "//pkg/daemon:go_default_library", "//pkg/log:go_default_library", "//pkg/private/common:go_default_library", diff --git a/tools/pktgen/cmd/pktgen/main.go b/tools/pktgen/cmd/pktgen/main.go index 0c2cec2569..d56d951ace 100644 --- a/tools/pktgen/cmd/pktgen/main.go +++ b/tools/pktgen/cmd/pktgen/main.go @@ -18,13 +18,14 @@ import ( "context" "encoding/json" "fmt" - "net" + "net/netip" "os" "path/filepath" "github.com/google/gopacket" "github.com/spf13/cobra" + "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/daemon" "github.com/scionproto/scion/pkg/log" "github.com/scionproto/scion/pkg/private/common" @@ -155,10 +156,14 @@ func run(cfg flags, dst *snet.UDPAddr) error { scionLayer.SrcIA = localIA scionLayer.DstIA = path.Destination() scionLayer.Path = decPath - if err := scionLayer.SetDstAddr(&net.IPAddr{IP: dst.Host.IP, Zone: dst.Host.Zone}); err != nil { + dstHostIP, ok := netip.AddrFromSlice(dst.Host.IP) + if !ok { + return serrors.New("invalid destination host IP", "ip", dst.Host.IP) + } + if err := scionLayer.SetDstAddr(addr.HostIP(dstHostIP)); err != nil { return serrors.WrapStr("setting SCION dest address", err) } - if err := scionLayer.SetSrcAddr(&net.IPAddr{IP: localIP}); err != nil { + if err := scionLayer.SetSrcAddr(addr.HostIP(localIP)); err != nil { return serrors.WrapStr("setting SCION source address", err) } scionudpLayer := &slayers.UDP{} @@ -184,15 +189,18 @@ func run(cfg flags, dst *snet.UDPAddr) error { return nil } -func resolveLocal(dst *snet.UDPAddr) (net.IP, error) { +func resolveLocal(dst *snet.UDPAddr) (netip.Addr, error) { target := dst.Host.IP if dst.NextHop != nil { target = dst.NextHop.IP } - localIP, err := addrutil.ResolveLocal(target) + resolvedIP, err := addrutil.ResolveLocal(target) if err != nil { - return nil, serrors.WrapStr("resolving local address", err) - + return netip.Addr{}, serrors.WrapStr("resolving local address", err) + } + localIP, ok := netip.AddrFromSlice(resolvedIP) + if !ok { + return netip.Addr{}, serrors.New("invalid local IP", "ip", resolvedIP) } return localIP, nil }