From 6a96adf2b5354109c062c04b54810399bb5c454d Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Tue, 6 Aug 2024 18:17:34 +0200 Subject: [PATCH 01/29] scrypto: use ecdsa.VerifyASN1 instead of ecdsa.Verify (#4592) This allows us to profit from some optimizations the standard library does under the hood and simplifies the code. --- pkg/scrypto/signed/msg.go | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/pkg/scrypto/signed/msg.go b/pkg/scrypto/signed/msg.go index 353e057390..387b3d20a1 100644 --- a/pkg/scrypto/signed/msg.go +++ b/pkg/scrypto/signed/msg.go @@ -18,10 +18,8 @@ import ( "crypto" "crypto/ecdsa" "crypto/rand" - "encoding/asn1" "errors" "fmt" - "math/big" "time" "github.com/golang/protobuf/ptypes" @@ -131,21 +129,7 @@ func Verify(signed *cryptopb.SignedMessage, key crypto.PublicKey, switch pub := key.(type) { case *ecdsa.PublicKey: - type ecdsaSignature struct { - R, S *big.Int - } - - // XXX(roosd): Copied from x509/x509.go:checkSignature. - var sig ecdsaSignature - if rest, err := asn1.Unmarshal(signed.Signature, &sig); err != nil { - return nil, err - } else if len(rest) != 0 { - return nil, serrors.New("trailing data after ECDSA signature") - } - if sig.R.Sign() <= 0 || sig.S.Sign() <= 0 { - return nil, errors.New("ECDSA signature contained zero or negative values") - } - if !ecdsa.Verify(pub, input, sig.R, sig.S) { + if !ecdsa.VerifyASN1(pub, input, signed.Signature) { return nil, errors.New("ECDSA verification failure") } default: From 5b4d3a67d36b5fa0971e0cd33e590fc5efe144ff Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Fri, 9 Aug 2024 11:28:29 +0200 Subject: [PATCH 02/29] pkg/private/serrors: do not use reflect encoder for all context (#4594) Previously, the context was always encoded using the reflect encoder (which is just json marshaling). This has the bad side effect that the usual marshaling methods are not respected. E.g., error context that would in theory implement the fmt.Stringer method were just JSON encoded. With this change, we leave it up to zap to decide how the values are encoded based on their type. --- pkg/private/serrors/BUILD.bazel | 5 ++++- pkg/private/serrors/errors.go | 5 ++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkg/private/serrors/BUILD.bazel b/pkg/private/serrors/BUILD.bazel index d08177170c..ce5279d54d 100644 --- a/pkg/private/serrors/BUILD.bazel +++ b/pkg/private/serrors/BUILD.bazel @@ -8,7 +8,10 @@ go_library( ], importpath = "github.com/scionproto/scion/pkg/private/serrors", visibility = ["//visibility:public"], - deps = ["@org_uber_go_zap//zapcore:go_default_library"], + deps = [ + "@org_uber_go_zap//:go_default_library", + "@org_uber_go_zap//zapcore:go_default_library", + ], ) go_test( diff --git a/pkg/private/serrors/errors.go b/pkg/private/serrors/errors.go index 33c1c7aa31..012eb24f47 100644 --- a/pkg/private/serrors/errors.go +++ b/pkg/private/serrors/errors.go @@ -30,6 +30,7 @@ import ( "sort" "strings" + "go.uber.org/zap" "go.uber.org/zap/zapcore" ) @@ -98,9 +99,7 @@ func (e basicError) MarshalLogObject(enc zapcore.ObjectEncoder) error { } } for k, v := range e.fields { - if err := enc.AddReflected(k, v); err != nil { - return err - } + zap.Any(k, v).AddTo(enc) } return nil } From ad503c1fb89ba583093e2ea8004c7acd5027e010 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Mon, 12 Aug 2024 11:40:32 +0200 Subject: [PATCH 03/29] serrors: delete error context merging and code cleanup (#4586) The withCtx() function, in rare cases, created hybrid objects that required complicated support code and, in some cases could cause Is() to panic. Removed the feature, replaced WithCtx() with a shim that doesn't create hybrids. Removed all the complicated code that resulted. There are now two subclasses of errors: * basicError: dedicated to errors of the form string+cause - Constructed by Wrap() * joinedError: dedicated to errors of the form error+cause - Constructed by Join() This allows for Unwrap() to be different and do the right thing, so that there is no need for a custom implementatin of Is(). Introduced new constructors with obvious semantics to replace those already marked deprecated. Also replaced the ctx map by a slice of ctx pairs. Which removes some unnecessary conversion code. I still plan on editing the calls to deprecated constructors (and common.ErrMsg) out of everywhere, but in a subsequent PR. Fixes #4486 --- pkg/private/common/errors.go | 4 +- pkg/private/serrors/errors.go | 358 +++++++++--------- pkg/private/serrors/errors_test.go | 45 +-- pkg/private/serrors/stack.go | 3 +- pkg/private/serrors/testdata/error-list.log | 2 +- .../serrors/testdata/error-with-context.err | 2 +- .../serrors/testdata/error-with-context.log | 2 +- pkg/private/serrors/testdata/goroutine.log | 2 +- .../serrors/testdata/wrapped-error.log | 2 +- .../api/testdata/certificates-malformed.json | 2 +- private/mgmtapi/segments/api/api.go | 4 +- .../testdata/segments-malformed-query.json | 2 +- 12 files changed, 218 insertions(+), 210 deletions(-) diff --git a/pkg/private/common/errors.go b/pkg/private/common/errors.go index 7743cbe12e..f932d0f24c 100644 --- a/pkg/private/common/errors.go +++ b/pkg/private/common/errors.go @@ -15,8 +15,8 @@ package common -// ErrMsg should be used for error string constants. The constant can then be -// used for Is checking in the calling code. +// Deprecated: ErrMsg is not useful. It mimics errors.New() but fails to return a singleton. Just +// use errors.New() if you need cheap sentinel errors. type ErrMsg string func (e ErrMsg) Error() string { diff --git a/pkg/private/serrors/errors.go b/pkg/private/serrors/errors.go index 012eb24f47..c913183b6c 100644 --- a/pkg/private/serrors/errors.go +++ b/pkg/private/serrors/errors.go @@ -34,43 +34,24 @@ import ( "go.uber.org/zap/zapcore" ) -type errOrMsg struct { - str string - err error -} - -func (m errOrMsg) Error() string { - if m.err != nil { - return m.err.Error() - } - return m.str -} - -func (m errOrMsg) addToEncoder(enc zapcore.ObjectEncoder) error { - if m.err != nil { - if marshaler, ok := m.err.(zapcore.ObjectMarshaler); ok { - return enc.AddObject("msg", marshaler) - } - enc.AddString("msg", m.err.Error()) - return nil - } - enc.AddString("msg", m.str) - return nil +// ctxPair is one item of context info. +type ctxPair struct { + Key string + Value interface{} } -type basicError struct { - msg errOrMsg - fields map[string]interface{} - cause error - stack *stack +// errorInfo is a base class for two implementations of error: basicError and joinedError. +type errorInfo struct { + ctx *[]ctxPair + cause error + stack *stack } -func (e basicError) Error() string { +func (e errorInfo) error() string { var buf bytes.Buffer - buf.WriteString(e.msg.Error()) - if len(e.fields) != 0 { + if len(*e.ctx) != 0 { fmt.Fprint(&buf, " ") - encodeContext(&buf, e.ctxPairs()) + encodeContext(&buf, *e.ctx) } if e.cause != nil { fmt.Fprintf(&buf, ": %s", e.cause) @@ -80,10 +61,7 @@ func (e basicError) Error() string { // MarshalLogObject implements zapcore.ObjectMarshaler to have a nicer log // representation. -func (e basicError) MarshalLogObject(enc zapcore.ObjectEncoder) error { - if err := e.msg.addToEncoder(enc); err != nil { - return err - } +func (e errorInfo) marshalLogObject(enc zapcore.ObjectEncoder) error { if e.cause != nil { if m, ok := e.cause.(zapcore.ObjectMarshaler); ok { if err := enc.AddObject("cause", m); err != nil { @@ -98,54 +76,20 @@ func (e basicError) MarshalLogObject(enc zapcore.ObjectEncoder) error { return err } } - for k, v := range e.fields { - zap.Any(k, v).AddTo(enc) + for _, pair := range *e.ctx { + zap.Any(pair.Key, pair.Value).AddTo(enc) } return nil } -func (e basicError) Is(err error) bool { - switch other := err.(type) { - case basicError: - return e.msg == other.msg - default: - if e.msg.err != nil { - return e.msg.err == err - } - return false - } -} - -func (e basicError) As(as interface{}) bool { - if e.msg.err != nil { - return errors.As(e.msg.err, as) - } - return false -} - -func (e basicError) Unwrap() error { - return e.cause -} - // StackTrace returns the attached stack trace if there is any. -func (e basicError) StackTrace() StackTrace { +func (e errorInfo) StackTrace() StackTrace { if e.stack == nil { return nil } return e.stack.StackTrace() } -func (e basicError) ctxPairs() []ctxPair { - fields := make([]ctxPair, 0, len(e.fields)) - for k, v := range e.fields { - fields = append(fields, ctxPair{Key: k, Value: v}) - } - sort.Slice(fields, func(i, j int) bool { - return fields[i].Key < fields[j].Key - }) - return fields -} - // IsTimeout returns whether err is or is caused by a timeout error. func IsTimeout(err error) bool { var t interface{ Timeout() bool } @@ -158,75 +102,196 @@ func IsTemporary(err error) bool { return errors.As(err, &t) && t.Temporary() } -// WithCtx returns an error that is the same as the given error but contains the -// additional context. The additional context is printed in the Error method. -// The returned error implements Is and Is(err) returns true. -// Deprecated: use WrapStr or New instead. -func WithCtx(err error, errCtx ...interface{}) error { - if top, ok := err.(basicError); ok { - return basicError{ - msg: top.msg, - fields: combineFields(top.fields, errCtxToFields(errCtx)), - cause: top.cause, - stack: top.stack, - } +func mkErrorInfo(cause error, addStack bool, errCtx ...interface{}) errorInfo { + np := len(errCtx) / 2 + ctx := make([]ctxPair, np) + for i := 0; i < np; i++ { + k := errCtx[2*i] + v := errCtx[2*i+1] + ctx[i] = ctxPair{Key: fmt.Sprint(k), Value: v} + } + sort.Slice(ctx, func(a, b int) bool { + return ctx[a].Key < ctx[b].Key + }) + + r := errorInfo{ + cause: cause, + ctx: &ctx, + } + if !addStack { + return r + } + + var ( + t1 basicError + t2 *basicError + t3 joinedError + t4 *joinedError + ) + + // We attach a stacktrace if there is no basic error cause already. Note that if the innermost + // basicError was without a stack trace, then there'll never be one. That's to avoid looking + // for it in every level or every constructor. TB revisisted if necessary. + // TODO(jiceatscion): should we define a "stackertracer" interface? + if r.cause == nil || !(errors.As(cause, &t1) || errors.As(cause, &t2) || + errors.As(cause, &t3) || errors.As(cause, &t4)) { + + r.stack = callers() } + return r +} + +// basicError is an implementation of error that encapsulates various pieces of information besides +// a message. The msg field is strictly a string. +type basicError struct { + errorInfo + msg string +} + +func (e basicError) Error() string { + var buf bytes.Buffer + buf.WriteString(e.msg) + buf.WriteString(e.errorInfo.error()) + return buf.String() +} + +func (e basicError) Unwrap() error { + return e.cause +} +// MarshalLogObject implements zapcore.ObjectMarshaler to have a nicer log +// representation. +func (e basicError) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddString("msg", e.msg) + return e.errorInfo.marshalLogObject(enc) +} + +// WrapStr returns an error that associates the given error, with the given cause (an underlying +// error) unless nil, and the given context. +// +// A stack dump is added unless cause is a basicError (in which case it is assumed to contain a +// stack dump). +// +// The returned error supports Is. Is(cause)returns true. +// +// WrapStr will soon be renamed Wrap, once the name Wrap becomes available. Until then it is ok to +// use wrapStr(). +func WrapStr(msg string, cause error, errCtx ...interface{}) error { return basicError{ - msg: errOrMsg{err: err}, - fields: errCtxToFields(errCtx), + errorInfo: mkErrorInfo(cause, true, errCtx...), + msg: msg, } } -// Wrap wraps the cause with the msg error and adds context to the resulting -// error. The returned error implements Is and Is(msg) and Is(cause) returns -// true. -// Deprecated: use WrapStr instead. -func Wrap(msg, cause error, errCtx ...interface{}) error { +// WrapStrNoStack returns an error that associates the given error, with the given cause +// (an underlying error) unless nil, and the given context. A stack dump is not added. +// if cause is a basicError that contains a stack dump, that stack dump is preserved. The returned +// error supports Is. Is(cause) returns true. +func WrapStrNoStack(msg string, cause error, errCtx ...interface{}) error { return basicError{ - msg: errOrMsg{err: msg}, - cause: cause, - fields: errCtxToFields(errCtx), + errorInfo: mkErrorInfo(cause, false, errCtx...), + msg: msg, } } -// WrapStr wraps the cause with an error that has msg in the error message and -// adds the additional context. The returned error implements Is and Is(cause) -// returns true. -func WrapStr(msg string, cause error, errCtx ...interface{}) error { - var ( - existingVal basicError - existingPtr *basicError - st *stack - ) +// New creates a new basicError with the given message and context, plus a stack dump. +// It returns a pointer as the underlying type of the error interface object. +// Avoid using this in performance-critical code: it is the most expensive variant. If used to +// construct other errors, such as with Join, the embedded stack trace and context serve no +// purpose. Therefore, to make sentinel errors, errors.New() should be preferred. +func New(msg string, errCtx ...interface{}) error { + return &basicError{ + errorInfo: mkErrorInfo(nil, true, errCtx...), + msg: msg, + } +} + +// joinedError is an implementation of error that aggregates various pieces of information, around +// an existing error, the base error (for example a unique sentinel error). The base error isn't +// assumed to be of any particular implementation. +type joinedError struct { + errorInfo + error error +} + +func (e joinedError) Error() string { + var buf bytes.Buffer + buf.WriteString(e.error.Error()) + buf.WriteString(e.errorInfo.error()) + return buf.String() +} + +func (e joinedError) Unwrap() []error { + return []error{e.error, e.cause} +} + +// MarshalLogObject implements zapcore.ObjectMarshaler to have a nicer log +// representation. The base error is not dissected. It is treated as a most generic error. +func (e joinedError) MarshalLogObject(enc zapcore.ObjectEncoder) error { + enc.AddString("msg", e.error.Error()) + return e.errorInfo.marshalLogObject(enc) +} - // We attach a stacktrace if there is no basic error already. - if !errors.As(cause, &existingVal) && !errors.As(cause, &existingPtr) { - st = callers() +// Join returns an error that associates the given error, with the given cause (an underlying error) +// unless nil, and the given context. +// +// A stack dump is added unless cause is a basicError (in which case it is assume to contain a stack +// dump). +// +// The returned error supports Is. If cause isn't nil, Is(cause) returns true. Is(error) returns +// true. +func Join(err, cause error, errCtx ...interface{}) error { + if err == nil && cause == nil { + // Pointless. Will not. Also, maintaining backward compatibility with + // a previous Join function. + return nil } - return basicError{ - msg: errOrMsg{str: msg}, - cause: cause, - fields: errCtxToFields(errCtx), - stack: st, + return joinedError{ + errorInfo: mkErrorInfo(cause, true, errCtx...), + error: err, } } -// New creates a new error with the given message and context. -func New(msg string, errCtx ...interface{}) error { - if len(errCtx) == 0 { - return &basicError{ - msg: errOrMsg{str: msg}, - stack: callers(), - } +// JoinNoStack returns an error that associates the given error, with the given cause +// (an underlying error) unless nil, and the given context. +// +// A stack dump is not added. If cause is a basicError and contain a stack dump. That stack dump is +// preserved. +// +// The returned error supports Is. If cause isn't nil, Is(cause) returns true. Is(error) returns +// true. +func JoinNoStack(err, cause error, errCtx ...interface{}) error { + if err == nil && cause == nil { + // Pointless. Will not. + return nil } - return &basicError{ - msg: errOrMsg{str: msg}, - fields: errCtxToFields(errCtx), - stack: callers(), + return joinedError{ + errorInfo: mkErrorInfo(cause, false, errCtx...), + error: err, } } +// Deprecated: WithCtx should never have existed. Depending on intent, use: +// - Join(err, nil, errCtx): If err has no context to preserve. +// - WrapStr("some error with context added", err, errctx): if err is an error with error +// information that needs to be preserved. +// +// This shim does the latter for you for the time being. +// +// WithCtx used to attempt the merger of the given error into the newly created one with +// semantically incorrect results. That feature is gone and the results differ only slightly in the +// formated string output. WithCtx didn't try to add a stack, so this shim doesn't either. +func WithCtx(err error, errCtx ...interface{}) error { + return WrapStrNoStack("error", err, errCtx...) +} + +// Deprecated: Wrap has been renamed Join. Join and the historical Wrap do differ very slightly: +// any stack dump that might have be attached to err is ignored when logging. Like before, no stack +// dump is added to the returned error. +func Wrap(err, cause error, errCtx ...interface{}) error { + return JoinNoStack(err, cause, errCtx...) +} + // List is a slice of errors. type List []error @@ -262,55 +327,6 @@ func (e List) MarshalLogArray(ae zapcore.ArrayEncoder) error { return nil } -// Join returns an error that wraps the given errors in a List error. -// Any nil error values are discarded. -// Join returns nil if errs contains no non-nil values. -func Join(errs ...error) error { - n := 0 - for _, err := range errs { - if err != nil { - n++ - } - } - if n == 0 { - return nil - } - l := make(List, 0, n) - for _, err := range errs { - if err != nil { - l = append(l, err) - } - } - return l -} - -func errCtxToFields(errCtx []interface{}) map[string]interface{} { - if len(errCtx) == 0 { - return nil - } - fields := make(map[string]interface{}, len(errCtx)/2) - for i := 0; i < len(errCtx)-1; i += 2 { - fields[fmt.Sprint(errCtx[i])] = errCtx[i+1] - } - return fields -} - -func combineFields(a, b map[string]interface{}) map[string]interface{} { - fields := make(map[string]interface{}, len(a)+len(b)) - for k, v := range a { - fields[k] = v - } - for k, v := range b { - fields[k] = v - } - return fields -} - -type ctxPair struct { - Key string - Value interface{} -} - func encodeContext(buf io.Writer, pairs []ctxPair) { fmt.Fprint(buf, "{") for i, p := range pairs { diff --git a/pkg/private/serrors/errors_test.go b/pkg/private/serrors/errors_test.go index 803cd8c422..9f0443fc08 100644 --- a/pkg/private/serrors/errors_test.go +++ b/pkg/private/serrors/errors_test.go @@ -219,6 +219,9 @@ func TestEncoding(t *testing.T) { goldenFileBase: "testdata/wrapped-error", }, "error with context": { + // WithCtx is deprecated. The shim does it the new way: sets err as the cause of a new + // error. The string output isn't exactly the same. Which almost nothing ever notices... + // except this test. err: serrors.WithCtx(serrors.New("simple err"), "someCtx", "someValue"), goldenFileBase: "testdata/error-with-context", }, @@ -281,35 +284,9 @@ func TestList(t *testing.T) { } func TestJoinNil(t *testing.T) { - assert.Nil(t, serrors.Join()) - assert.Nil(t, serrors.Join(nil)) assert.Nil(t, serrors.Join(nil, nil)) } -func TestJoin(t *testing.T) { - err1 := serrors.New("err1") - err2 := serrors.New("err2") - for _, test := range []struct { - errs []error - want serrors.List - }{{ - errs: []error{err1}, - want: serrors.List{err1}, - }, { - errs: []error{err1}, - want: serrors.List{err1}, - }, { - errs: []error{err1, err2}, - want: serrors.List{err1, err2}, - }, { - errs: []error{err1, nil, err2}, - want: serrors.List{err1, err2}, - }} { - got := serrors.Join(test.errs...) - assert.Equal(t, got, test.want) - } -} - func TestAtMostOneStacktrace(t *testing.T) { err := errors.New("core") for i := range [20]int{} { @@ -353,13 +330,15 @@ func ExampleNew() { } func ExampleWithCtx() { + // It is not possible to augment the context of a basicError. + // WithCtx turns that into an error with a cause. // ErrBadL4 is an error defined at package scope. var ErrBadL4 = serrors.New("Unsupported L4 protocol") addedCtx := serrors.WithCtx(ErrBadL4, "type", "SCTP") fmt.Println(addedCtx) // Output: - // Unsupported L4 protocol {type=SCTP} + // error {type=SCTP}: Unsupported L4 protocol } func ExampleWrapStr() { @@ -411,3 +390,15 @@ func sanitizeLog(log []byte) []byte { } return log } + +func TestUncomparable(t *testing.T) { + t.Run("Is", func(t *testing.T) { + // We make two wrappers of uncomparable error objects. We could also create custom error + // types for the same result, but this is closer to our use cases. + errObject := serrors.WrapStr("simple err", nil, "dummy", "context") + wrapperA := serrors.Join(errObject, nil, "dummy", "context") + wrapperB := serrors.Join(errObject, nil, "dummy", "context") + assert.NotErrorIs(t, wrapperA, wrapperB) + // no panic + }) +} diff --git a/pkg/private/serrors/stack.go b/pkg/private/serrors/stack.go index b8a4f843a6..7cb19bcd3c 100644 --- a/pkg/private/serrors/stack.go +++ b/pkg/private/serrors/stack.go @@ -188,9 +188,10 @@ func (s *stack) StackTrace() StackTrace { } func callers() *stack { + // We skip 4 boilerplate frames: Ctor()->mkErrorInfo()->callers()->Callers() const depth = 32 var pcs [depth]uintptr - n := runtime.Callers(3, pcs[:]) + n := runtime.Callers(4, pcs[:]) var st stack = pcs[0 : n-1] // skip bottom runtime.goexit at bottom of each stack return &st } diff --git a/pkg/private/serrors/testdata/error-list.log b/pkg/private/serrors/testdata/error-list.log index 83775ffe9e..040ccf97fa 100644 --- a/pkg/private/serrors/testdata/error-list.log +++ b/pkg/private/serrors/testdata/error-list.log @@ -1 +1 @@ -{"err":[{"ctx1":"val1","msg":"test err","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:227","testing.tRunner gosdk"]},{"msg":"test err2","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:228","testing.tRunner gosdk"]}],"level":"info","msg":"Failed to do thing"} \ No newline at end of file +{"err":[{"ctx1":"val1","msg":"test err","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:230","testing.tRunner gosdk"]},{"msg":"test err2","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:231","testing.tRunner gosdk"]}],"level":"info","msg":"Failed to do thing"} \ No newline at end of file diff --git a/pkg/private/serrors/testdata/error-with-context.err b/pkg/private/serrors/testdata/error-with-context.err index fd33f3ae53..6ff4bd2dbf 100644 --- a/pkg/private/serrors/testdata/error-with-context.err +++ b/pkg/private/serrors/testdata/error-with-context.err @@ -1 +1 @@ -simple err {someCtx=someValue} \ No newline at end of file +error {someCtx=someValue}: simple err \ No newline at end of file diff --git a/pkg/private/serrors/testdata/error-with-context.log b/pkg/private/serrors/testdata/error-with-context.log index d341a89306..7548ec61c3 100644 --- a/pkg/private/serrors/testdata/error-with-context.log +++ b/pkg/private/serrors/testdata/error-with-context.log @@ -1 +1 @@ -{"err":{"msg":{"msg":"simple err","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:222","testing.tRunner gosdk"]},"someCtx":"someValue"},"level":"info","msg":"Failed to do thing"} \ No newline at end of file +{"err":{"cause":{"msg":"simple err","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:225","testing.tRunner gosdk"]},"msg":"error","someCtx":"someValue"},"level":"info","msg":"Failed to do thing"} \ No newline at end of file diff --git a/pkg/private/serrors/testdata/goroutine.log b/pkg/private/serrors/testdata/goroutine.log index b7d2540846..c9212c8f04 100644 --- a/pkg/private/serrors/testdata/goroutine.log +++ b/pkg/private/serrors/testdata/goroutine.log @@ -1 +1 @@ -{"err":{"msg":"msg","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding.func2.1 pkg/private/serrors/errors_test.go:236"]},"level":"info","msg":"Failed to do thing"} \ No newline at end of file +{"err":{"msg":"msg","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding.func2.1 pkg/private/serrors/errors_test.go:239"]},"level":"info","msg":"Failed to do thing"} \ No newline at end of file diff --git a/pkg/private/serrors/testdata/wrapped-error.log b/pkg/private/serrors/testdata/wrapped-error.log index d9f2212c13..93a7d47c98 100644 --- a/pkg/private/serrors/testdata/wrapped-error.log +++ b/pkg/private/serrors/testdata/wrapped-error.log @@ -1 +1 @@ -{"err":{"cause":{"msg":"msg cause","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:215","testing.tRunner gosdk"]},"k0":"v0","k1":1,"msg":{"msg":"msg error","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:214","testing.tRunner gosdk"]}},"level":"info","msg":"Failed to do thing"} \ No newline at end of file +{"err":{"cause":{"msg":"msg cause","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:215","testing.tRunner gosdk"]},"k0":"v0","k1":1,"msg":"msg error"},"level":"info","msg":"Failed to do thing"} \ No newline at end of file diff --git a/private/mgmtapi/cppki/api/testdata/certificates-malformed.json b/private/mgmtapi/cppki/api/testdata/certificates-malformed.json index 4af2e0a64a..1bdf82a991 100644 --- a/private/mgmtapi/cppki/api/testdata/certificates-malformed.json +++ b/private/mgmtapi/cppki/api/testdata/certificates-malformed.json @@ -1,5 +1,5 @@ { - "detail": "[ invalid ISD-AS {value=garbage} {parameter=isd_as} ]", + "detail": "[ error {parameter=isd_as}: invalid ISD-AS {value=garbage} ]", "status": 400, "title": "malformed query parameters", "type": "/problems/bad-request" diff --git a/private/mgmtapi/segments/api/api.go b/private/mgmtapi/segments/api/api.go index 2bb470001a..7a1b48f793 100644 --- a/private/mgmtapi/segments/api/api.go +++ b/private/mgmtapi/segments/api/api.go @@ -50,14 +50,14 @@ func (s *Server) GetSegments(w http.ResponseWriter, r *http.Request, params GetS if ia, err := addr.ParseIA(*params.StartIsdAs); err == nil { q.StartsAt = []addr.IA{ia} } else { - errs = append(errs, serrors.WithCtx(err, "parameter", "start_isd_as")) + errs = append(errs, serrors.WrapStr("invalid start ISD_AS", err)) } } if params.EndIsdAs != nil { if ia, err := addr.ParseIA(*params.EndIsdAs); err == nil { q.EndsAt = []addr.IA{ia} } else { - errs = append(errs, serrors.WithCtx(err, "parameter", "end_isd_as")) + errs = append(errs, serrors.WrapStr("invalid end ISD_AS", err)) } } if err := errs.ToError(); err != nil { diff --git a/private/mgmtapi/segments/api/testdata/segments-malformed-query.json b/private/mgmtapi/segments/api/testdata/segments-malformed-query.json index f4c280a5eb..facebfce96 100644 --- a/private/mgmtapi/segments/api/testdata/segments-malformed-query.json +++ b/private/mgmtapi/segments/api/testdata/segments-malformed-query.json @@ -1,5 +1,5 @@ { - "detail": "[ parsing AS part {index=0; parameter=start_isd_as; value=ff001:0:110}: strconv.ParseUint: parsing \"ff001\": value out of range; parsing AS part {index=0; parameter=end_isd_as; value=ff000:0:112}: strconv.ParseUint: parsing \"ff000\": value out of range ]", + "detail": "[ invalid start ISD_AS: parsing AS part {index=0; value=ff001:0:110}: strconv.ParseUint: parsing \"ff001\": value out of range; invalid end ISD_AS: parsing AS part {index=0; value=ff000:0:112}: strconv.ParseUint: parsing \"ff000\": value out of range ]", "status": 400, "title": "malformed query parameters", "type": "/problems/bad-request" From 6d392eeea0a3fa46fdd7a8ce03c65b72624e3397 Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Tue, 13 Aug 2024 15:00:46 +0200 Subject: [PATCH 04/29] control: check certificates available for beacons (#4587) Introduce a new beacon selection algorithm that ensures the certificate chain for all the selected beacons is available locally. Beacons for which this is not the case are not considered and not propagated. This is required to counteract some edge cases where either the certificate chain is lost (e.g., due to removing the trust database manually) or if one of the hop entries has a shorter expiration time and has expired in the meantime. --- control/beacon/BUILD.bazel | 8 + control/beacon/chain_checker.go | 166 +++++++++++++++++++++ control/beacon/selection_algo.go | 54 ++++++- control/beacon/store.go | 52 ++++++- control/cmd/control/main.go | 12 +- private/segment/segverifier/segverifier.go | 2 +- private/trust/fetching_provider.go | 2 +- private/trust/recurser.go | 6 + 8 files changed, 289 insertions(+), 13 deletions(-) create mode 100644 control/beacon/chain_checker.go diff --git a/control/beacon/BUILD.bazel b/control/beacon/BUILD.bazel index 4f192f0492..2029d2b1b9 100644 --- a/control/beacon/BUILD.bazel +++ b/control/beacon/BUILD.bazel @@ -4,6 +4,7 @@ go_library( name = "go_default_library", srcs = [ "beacon.go", + "chain_checker.go", "db.go", "policy.go", "selection_algo.go", @@ -18,7 +19,14 @@ go_library( "//pkg/private/ptr:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/proto/control_plane:go_default_library", + "//pkg/proto/crypto:go_default_library", + "//pkg/scrypto/cppki:go_default_library", + "//pkg/scrypto/signed:go_default_library", "//pkg/segment:go_default_library", + "//private/segment/segverifier:go_default_library", + "//private/segment/verifier:go_default_library", + "//private/trust:go_default_library", + "@com_github_patrickmn_go_cache//:go_default_library", "@in_gopkg_yaml_v2//:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", ], diff --git a/control/beacon/chain_checker.go b/control/beacon/chain_checker.go new file mode 100644 index 0000000000..34cb9b796d --- /dev/null +++ b/control/beacon/chain_checker.go @@ -0,0 +1,166 @@ +// Copyright 2024 Anapaya Systems +// +// 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 beacon + +import ( + "context" + "crypto/x509" + "fmt" + "net" + "time" + + "github.com/patrickmn/go-cache" + "google.golang.org/protobuf/proto" + + "github.com/scionproto/scion/pkg/addr" + "github.com/scionproto/scion/pkg/private/serrors" + cppb "github.com/scionproto/scion/pkg/proto/control_plane" + cryptopb "github.com/scionproto/scion/pkg/proto/crypto" + "github.com/scionproto/scion/pkg/scrypto/cppki" + "github.com/scionproto/scion/pkg/scrypto/signed" + infra "github.com/scionproto/scion/private/segment/verifier" + "github.com/scionproto/scion/private/trust" +) + +type ChainProvider interface { + GetChains(context.Context, trust.ChainQuery, ...trust.Option) ([][]*x509.Certificate, error) +} + +const ( + defaultCacheHitExpiration = 10 * time.Minute + defaultCacheMissExpiration = 30 * time.Second +) + +var _ infra.Verifier = (chainChecker{}) + +// chainChecker checks that the certificate chain is available locally. This is used +// to ensure we do not propagate beacons that are not verifiable. +type chainChecker struct { + BoundValidity cppki.Validity + Engine ChainProvider + + Cache *cache.Cache +} + +func (v chainChecker) WithValidity(val cppki.Validity) infra.Verifier { + v.BoundValidity = val + return v +} + +func (v chainChecker) Verify(ctx context.Context, signedMsg *cryptopb.SignedMessage, + associatedData ...[]byte) (*signed.Message, error) { + + hdr, err := signed.ExtractUnverifiedHeader(signedMsg) + if err != nil { + return nil, err + } + + var keyID cppb.VerificationKeyID + if err := proto.Unmarshal(hdr.VerificationKeyID, &keyID); err != nil { + return nil, serrors.WrapStr("parsing verification key ID", err) + } + if len(keyID.SubjectKeyId) == 0 { + return nil, serrors.WrapStr("subject key ID must be set", err) + } + ia := addr.IA(keyID.IsdAs) + if ia.IsWildcard() { + return nil, serrors.New("ISD-AS must not contain wildcard", "isd_as", ia) + } + if v.Engine == nil { + return nil, serrors.New("nil engine that provides cert chains") + } + query := trust.ChainQuery{ + IA: ia, + SubjectKeyID: keyID.SubjectKeyId, + Validity: v.BoundValidity, + } + if err := v.checkChains(ctx, query); err != nil { + return nil, serrors.WrapStr("getting chains", err, + "query.isd_as", query.IA, + "query.subject_key_id", fmt.Sprintf("%x", query.SubjectKeyID), + "query.validity", query.Validity.String(), + ) + } + return nil, nil +} + +func (v chainChecker) checkChains(ctx context.Context, q trust.ChainQuery) error { + key := fmt.Sprintf("chain-%s-%x", q.IA, q.SubjectKeyID) + + cachedChains, ok := v.getChainsCached(key) + if ok { + if len(cachedChains) == 0 { + return serrors.New("cached certificate chains are empty") + } + + var validChains int + for _, chain := range cachedChains { + if len(chain) == 0 { + continue // This should never happen. + } + chainValidity := cppki.Validity{ + NotBefore: chain[0].NotBefore, + NotAfter: chain[0].NotAfter, + } + if v.BoundValidity != (cppki.Validity{}) && !chainValidity.Covers(v.BoundValidity) { + continue + } + validChains++ + } + if validChains == 0 { + // Remove the invalid chains from the cache. This is a rare case if + // we have previously cached chains, but they have now expired. + // After the cache is cleared here, we will attempt to fetch and + // cache the empty result, thus, not hitting this code path again. + v.Cache.Delete(key) + return serrors.New("chached certificate chains do not cover required validity") + } + return nil + } + + chains, err := v.Engine.GetChains(ctx, q) + if err != nil { + return err + } + v.cacheChains(key, chains, v.cacheExpiration(chains)) + if len(chains) == 0 { + return serrors.New("no certificate chains found") + } + return nil +} + +func (v chainChecker) getChainsCached(key string) ([][]*x509.Certificate, bool) { + chain, ok := v.Cache.Get(key) + if !ok { + return nil, false + } + return chain.([][]*x509.Certificate), true +} + +func (v chainChecker) cacheChains(key string, chain [][]*x509.Certificate, d time.Duration) { + v.Cache.Set(key, chain, d) +} + +func (v chainChecker) cacheExpiration(chains [][]*x509.Certificate) time.Duration { + // In case of a miss, we cache the result for a short time. This allows us to + // learn about new chains more quickly. + if len(chains) == 0 { + return defaultCacheMissExpiration + } + return defaultCacheHitExpiration +} + +func (v chainChecker) WithServer(server net.Addr) infra.Verifier { return v } +func (v chainChecker) WithIA(ia addr.IA) infra.Verifier { return v } diff --git a/control/beacon/selection_algo.go b/control/beacon/selection_algo.go index 25c19dba07..a5c49b9749 100644 --- a/control/beacon/selection_algo.go +++ b/control/beacon/selection_algo.go @@ -14,11 +14,19 @@ package beacon -import "math" +import ( + "context" + "math" + + "github.com/patrickmn/go-cache" + + "github.com/scionproto/scion/pkg/log" + "github.com/scionproto/scion/private/segment/segverifier" +) type selectionAlgorithm interface { // SelectBeacons selects the `n` best beacons from the provided slice of beacons. - SelectBeacons(beacons []Beacon, resultSize int) []Beacon + SelectBeacons(ctx context.Context, beacons []Beacon, resultSize int) []Beacon } // baseAlgo implements a very simple selection algorithm that optimizes for @@ -30,7 +38,7 @@ type baseAlgo struct{} // beacons. The last beacon is either the most diverse beacon from the remaining // beacons, if the diversity exceeds what has already been served. Or the // shortest remaining beacon, otherwise. -func (a baseAlgo) SelectBeacons(beacons []Beacon, resultSize int) []Beacon { +func (a baseAlgo) SelectBeacons(_ context.Context, beacons []Beacon, resultSize int) []Beacon { if len(beacons) <= resultSize { return beacons } @@ -69,3 +77,43 @@ func (baseAlgo) selectMostDiverse(beacons []Beacon, best Beacon) (Beacon, int) { } return diverse, maxDiversity } + +type chainsAvailableAlgo struct { + verifier chainChecker + logThrottled *cache.Cache +} + +func newChainsAvailableAlgo(engine ChainProvider) chainsAvailableAlgo { + return chainsAvailableAlgo{ + verifier: chainChecker{ + Engine: engine, + Cache: cache.New(defaultCacheHitExpiration, defaultCacheHitExpiration), + }, + logThrottled: cache.New(defaultCacheHitExpiration, defaultCacheHitExpiration), + } +} + +func (a chainsAvailableAlgo) SelectBeacons( + ctx context.Context, + beacons []Beacon, + resultSize int, +) []Beacon { + withChain := make([]Beacon, 0, len(beacons)) + for _, b := range beacons { + err := segverifier.VerifySegment(ctx, a.verifier, nil, b.Segment) + if err == nil { + withChain = append(withChain, b) + continue + } + + id := b.Segment.GetLoggingID() + if _, ok := a.logThrottled.Get(id); !ok { + log.FromCtx(ctx).Info("Ignoring beacon due to missing crypto material", + "id", id, + "err", err, + ) + a.logThrottled.Set(id, struct{}{}, cache.DefaultExpiration) + } + } + return baseAlgo{}.SelectBeacons(ctx, withChain, resultSize) +} diff --git a/control/beacon/store.go b/control/beacon/store.go index 838a360682..f6c04312dc 100644 --- a/control/beacon/store.go +++ b/control/beacon/store.go @@ -27,6 +27,37 @@ type usager interface { Usage(beacon Beacon) Usage } +type storeOptions struct { + chainChecker ChainProvider +} + +type StoreOption interface { + apply(o *storeOptions) +} + +type chainCheckerOption struct{ ChainProvider } + +func (c chainCheckerOption) apply(o *storeOptions) { + o.chainChecker = c.ChainProvider +} + +// WithCheckChain ensures that only beacons for which all the required +// certificate chains are available are returned. This can be paired with a +// chain provider that only returns locally available chains to ensure that +// beacons are verifiable with cryptographic material available in the local +// trust store. +func WithCheckChain(p ChainProvider) StoreOption { + return chainCheckerOption{p} +} + +func applyStoreOptions(opts []StoreOption) storeOptions { + var o storeOptions + for _, f := range opts { + f.apply(&o) + } + return o +} + // Store provides abstracted access to the beacon database in a non-core AS. // The store helps inserting beacons and revocations, and selects the best beacons // for given purposes based on the configured policies. It should not be used in a @@ -37,15 +68,16 @@ type Store struct { } // NewBeaconStore creates a new beacon store for a non-core AS. -func NewBeaconStore(policies Policies, db DB) (*Store, error) { +func NewBeaconStore(policies Policies, db DB, opts ...StoreOption) (*Store, error) { policies.InitDefaults() if err := policies.Validate(); err != nil { return nil, err } + o := applyStoreOptions(opts) s := &Store{ baseStore: baseStore{ db: db, - algo: baseAlgo{}, + algo: selectAlgo(o), }, policies: policies, } @@ -81,7 +113,7 @@ func (s *Store) getBeacons(ctx context.Context, policy *Policy) ([]Beacon, error if err != nil { return nil, err } - return s.algo.SelectBeacons(beacons, policy.BestSetSize), nil + return s.algo.SelectBeacons(ctx, beacons, policy.BestSetSize), nil } // MaxExpTime returns the segment maximum expiration time for the given policy. @@ -107,15 +139,16 @@ type CoreStore struct { } // NewCoreBeaconStore creates a new beacon store for a non-core AS. -func NewCoreBeaconStore(policies CorePolicies, db DB) (*CoreStore, error) { +func NewCoreBeaconStore(policies CorePolicies, db DB, opts ...StoreOption) (*CoreStore, error) { policies.InitDefaults() if err := policies.Validate(); err != nil { return nil, err } + o := applyStoreOptions(opts) s := &CoreStore{ baseStore: baseStore{ db: db, - algo: baseAlgo{}, + algo: selectAlgo(o), }, policies: policies, } @@ -155,7 +188,7 @@ func (s *CoreStore) getBeacons(ctx context.Context, policy *Policy) ([]Beacon, e log.FromCtx(ctx).Error("Error getting candidate beacons", "src", src, "err", err) continue } - selBeacons := s.algo.SelectBeacons(candidateBeacons, policy.BestSetSize) + selBeacons := s.algo.SelectBeacons(ctx, candidateBeacons, policy.BestSetSize) beacons = append(beacons, selBeacons...) } return beacons, nil @@ -202,3 +235,10 @@ func (s *baseStore) InsertBeacon(ctx context.Context, beacon Beacon) (InsertStat func (s *baseStore) UpdatePolicy(ctx context.Context, policy Policy) error { return serrors.New("policy update not supported") } + +func selectAlgo(o storeOptions) selectionAlgorithm { + if o.chainChecker != nil { + return newChainsAvailableAlgo(o.chainChecker) + } + return baseAlgo{} +} diff --git a/control/cmd/control/main.go b/control/cmd/control/main.go index c591180d79..3a7d5eb957 100644 --- a/control/cmd/control/main.go +++ b/control/cmd/control/main.go @@ -252,6 +252,13 @@ func realMain(ctx context.Context) error { beaconDB, topo.Core(), globalCfg.BS.Policies, + trust.FetchingProvider{ + DB: trustDB, + Recurser: trust.NeverRecurser{}, + // XXX(roosd): Do not set fetcher or router because they are not + // used and we rather panic if they are reached due to a implementation + // bug. + }, ) if err != nil { return serrors.WrapStr("initializing beacon store", err) @@ -826,6 +833,7 @@ func createBeaconStore( db storage.BeaconDB, core bool, policyConfig config.Policies, + provider beacon.ChainProvider, ) (cs.Store, bool, error) { if core { @@ -833,14 +841,14 @@ func createBeaconStore( if err != nil { return nil, false, err } - store, err := beacon.NewCoreBeaconStore(policies, db) + store, err := beacon.NewCoreBeaconStore(policies, db, beacon.WithCheckChain(provider)) return store, *policies.Prop.Filter.AllowIsdLoop, err } policies, err := cs.LoadNonCorePolicies(policyConfig) if err != nil { return nil, false, err } - store, err := beacon.NewBeaconStore(policies, db) + store, err := beacon.NewBeaconStore(policies, db, beacon.WithCheckChain(provider)) return store, *policies.Prop.Filter.AllowIsdLoop, err } diff --git a/private/segment/segverifier/segverifier.go b/private/segment/segverifier/segverifier.go index 4b47de625a..af8184f07e 100644 --- a/private/segment/segverifier/segverifier.go +++ b/private/segment/segverifier/segverifier.go @@ -158,7 +158,7 @@ func VerifySegment(ctx context.Context, verifier infra.Verifier, server net.Addr } verifier := verifier.WithServer(server).WithIA(asEntry.Local).WithValidity(validity) if err := segment.VerifyASEntry(ctx, verifier, i); err != nil { - return serrors.Wrap(ErrSegment, err, "seg", segment, "as", asEntry.Local) + return serrors.Wrap(ErrSegment, err, "seg", segment.String(), "as", asEntry.Local) } } return nil diff --git a/private/trust/fetching_provider.go b/private/trust/fetching_provider.go index 32862cd987..9df9e52871 100644 --- a/private/trust/fetching_provider.go +++ b/private/trust/fetching_provider.go @@ -122,7 +122,7 @@ func (p FetchingProvider) GetChains(ctx context.Context, query ChainQuery, // recursion is allowed. if err := p.Recurser.AllowRecursion(o.client); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrNotAllowed), err) - return nil, serrors.WrapStr("recursion not allowed", err) + return nil, serrors.WrapStr("checking whether recursion is allowed", err) } if o.server == nil { if o.server, err = p.Router.ChooseServer(ctx, query.IA.ISD()); err != nil { diff --git a/private/trust/recurser.go b/private/trust/recurser.go index 9713c8a5d0..7d484b5160 100644 --- a/private/trust/recurser.go +++ b/private/trust/recurser.go @@ -74,3 +74,9 @@ func (r LocalOnlyRecurser) AllowRecursion(peer net.Addr) error { } return nil } + +type NeverRecurser struct{} + +func (r NeverRecurser) AllowRecursion(peer net.Addr) error { + return serrors.New("recursion never allowed") +} From 0e19e834f3497a7f72fbbcc90582f80ba050bcaa Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Wed, 14 Aug 2024 11:19:34 +0200 Subject: [PATCH 05/29] control/beaconing: include the beacon ID in the propagator (#4597) Include the beacon ID in the propagator when logging errors. This helps the operator to easily track down the offending beacon and take appropriate action. --- control/beaconing/propagator.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/control/beaconing/propagator.go b/control/beaconing/propagator.go index 588ea9acaf..85cb1ec0f4 100644 --- a/control/beaconing/propagator.go +++ b/control/beaconing/propagator.go @@ -287,17 +287,14 @@ func (p *propagator) Propagate(ctx context.Context) error { defer log.HandlePanic() defer wg.Done() - var id string - debugEnabled := logger.Enabled(log.DebugLevel) - if debugEnabled { - // Collect the ID before the segment is extended such that it - // matches the ID that was logged above in logCandidateBeacons. - id = b.Segment.GetLoggingID() - } + // Collect the ID before the segment is extended such that it + // matches the ID that was logged above in logCandidateBeacons. + id := b.Segment.GetLoggingID() if err := p.extender.Extend(ctx, b.Segment, b.InIfID, egress, p.peers); err != nil { logger.Error("Unable to extend beacon", "egress_interface", egress, + "beacon.id", id, "beacon.ingress_interface", b.InIfID, "beacon.segment", hopsDescription(b.Segment.ASEntries), "err", err, @@ -310,6 +307,7 @@ func (p *propagator) Propagate(ctx context.Context) error { if err := sender.Send(ctx, b.Segment); err != nil { logger.Info("Unable to send beacon", "egress_interface", egress, + "beacon.id", id, "beacon.ingress_interface", b.InIfID, "beacon.segment", hopsDescription(b.Segment.ASEntries), "waited_for", time.Since(sendStart).String(), @@ -323,7 +321,7 @@ func (p *propagator) Propagate(ctx context.Context) error { p.incMetric(b.Segment.FirstIA(), b.InIfID, egress, prom.Success) p.intf.Propagate(p.now) - if debugEnabled { + if logger.Enabled(log.DebugLevel) { logger.Debug("Propagated beacon", "egress_interface", egress, "candidate_id", id, From 261f66cd5c9e5fee815e07e471483b58e23b53d3 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:30:03 +0200 Subject: [PATCH 06/29] brload: fix premature socket closure (#4591) Brload borrows the file descriptor from a af_packet.TPacket structure in order to use it with sendmmsg (not available via TPacket). In the process it left the original TPacket, only used on the receiving side, exposed to garbage collection, resulting in the premature closure of the socket. Fixed it by keeping a reference to TPacket on the sending side. In passing: * increase the benchmark packet size to 1500 bytes, to show bandwidth (~10Gb/s) with normal frames. * display brload's output to help in diagnosing issues. Fixes #4590 --- acceptance/router_benchmark/benchmarklib.py | 4 +++- acceptance/router_benchmark/brload/main.go | 3 ++- acceptance/router_benchmark/brload/mmsg.go | 6 +++++- acceptance/router_benchmark/test.py | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/acceptance/router_benchmark/benchmarklib.py b/acceptance/router_benchmark/benchmarklib.py index cbcced3f2e..4290de20bb 100644 --- a/acceptance/router_benchmark/benchmarklib.py +++ b/acceptance/router_benchmark/benchmarklib.py @@ -185,6 +185,7 @@ def run_test_case(self, case: str, map_args: list[str]) -> (int, int): output = self.exec_br_load(case, map_args, 13) end = "0" for line in output.splitlines(): + logger.info("BrLoad output: " + line) if line.startswith("metricsBegin"): end = line.split()[3] # "... metricsEnd: " @@ -322,7 +323,8 @@ def run_bm(self, test_cases: [str]) -> Results: self.exec_br_load(test_cases[0], map_args, 5) # Fetch the core count once. It doesn't change while the router is running. - # We can't get it until the router has done some work, but the warmup is enough. + # We cannot get this until the router has been up for a few seconds. If you shorten + # the warmup for some reason, make sure to add a delay. cores = self.core_count() # At long last, run the tests. diff --git a/acceptance/router_benchmark/brload/main.go b/acceptance/router_benchmark/brload/main.go index 3b29d0c1f9..161f7d43a3 100644 --- a/acceptance/router_benchmark/brload/main.go +++ b/acceptance/router_benchmark/brload/main.go @@ -224,6 +224,7 @@ func run(cmd *cobra.Command) int { binary.BigEndian.PutUint16(allPkts[j][44:46], uint16(numPkt%int(numStreams))) numPkt++ } + if _, err := sender.sendAll(); err != nil { log.Error("writing input packet", "case", string(caseToRun), "error", err) return 1 @@ -303,7 +304,7 @@ func openDevices(interfaceNames []string) (map[string]*afpacket.TPacket, error) handles := make(map[string]*afpacket.TPacket) for _, intf := range interfaceNames { - handle, err := afpacket.NewTPacket(afpacket.OptInterface(intf)) + handle, err := afpacket.NewTPacket(afpacket.OptInterface(intf), afpacket.OptFrameSize(4096)) if err != nil { return nil, serrors.WrapStr("creating TPacket", err) } diff --git a/acceptance/router_benchmark/brload/mmsg.go b/acceptance/router_benchmark/brload/mmsg.go index 532266654f..3a9f59f68a 100644 --- a/acceptance/router_benchmark/brload/mmsg.go +++ b/acceptance/router_benchmark/brload/mmsg.go @@ -25,12 +25,14 @@ import ( type mmsgHdr struct { hdr unix.Msghdr len uint32 + _ [4]byte } // mpktSender is a helper class to add the ability of using the sendmmsg system call // with afpacket sockets. type mpktSender struct { fd int + tp *afpacket.TPacket msgs []mmsgHdr iovecs []unix.Iovec } @@ -42,6 +44,8 @@ func newMpktSender(tp *afpacket.TPacket) *mpktSender { // than this) to the afpacket project and get it merged. fdv := reflect.ValueOf(tp).Elem().FieldByName("fd") sender.fd = int(fdv.Int()) + // This is to make sure that tp cannot be finalized before we're done abusing its file desc. + sender.tp = tp return sender } @@ -66,7 +70,7 @@ func (sender *mpktSender) sendAll() (int, error) { // use case. n, _, err := unix.Syscall6(unix.SYS_SENDMMSG, uintptr(sender.fd), - (uintptr)(unsafe.Pointer(&sender.msgs[0])), + uintptr(unsafe.Pointer(&sender.msgs[0])), uintptr(len(sender.msgs)), 0, 0, 0) if err == 0 { diff --git a/acceptance/router_benchmark/test.py b/acceptance/router_benchmark/test.py index 6fe8e4affc..af1049140a 100644 --- a/acceptance/router_benchmark/test.py +++ b/acceptance/router_benchmark/test.py @@ -34,7 +34,7 @@ logger = logging.getLogger(__name__) # Default packet length for CI testing -BM_PACKET_SIZE = 172 +BM_PACKET_SIZE = 1500 # Router profiling ON or OFF? PROFILING = False From 06d821309c6dcb11c2c4cc831731688f81cb08f1 Mon Sep 17 00:00:00 2001 From: FR4NK-W Date: Wed, 14 Aug 2024 16:45:59 +0200 Subject: [PATCH 07/29] tools: fixup the wireshark lua packet dissector heuristic filter (#4599) This fixes bug #4598 where the first SCION packet in a capture is never dissected as a SCION packet. The filter function is (only) called on the first packet of the conversation (4-tuple) since we set the dissector for the conversation. To also dissect the initial packet of a conversation for which a heuristic dissector function is registered, the dissector has to be called explicitly at the end of the filter function when a packet matches. From the docs: https://www.wireshark.org/docs/wsdg_html/#lua_fn_proto_register_heuristic_listname__func_ >The function should perform as much verification as possible to ensure the payload is for it, and **dissect the packet** (including setting TreeItem info and such) only if the payload is for it, before returning true or false. Also look at the comments there: https://github.com/wireshark/wireshark/blob/master/test/lua/dissector.lua#L523 https://github.com/wireshark/wireshark/blob/afff4e02/test/lua/dissector.lua#L523 --- tools/wireshark/scion.lua | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tools/wireshark/scion.lua b/tools/wireshark/scion.lua index 3ef19b2f2e..6270fc615c 100644 --- a/tools/wireshark/scion.lua +++ b/tools/wireshark/scion.lua @@ -143,11 +143,17 @@ local function scion_proto_filter(tvbuf, pktinfo, root) local addr_type_src_valid = (addrTypes[bit.band(tvbuf(9, 1):uint(), 0xf)] ~= nil) local rsv_valid = (tvbuf(10, 2):uint() == 0) - if version_valid and next_hdr_valid and path_type_valid and addr_type_dst_valid and addr_type_src_valid and rsv_valid then - pktinfo.conversation = scion_proto - return true + if not (version_valid and next_hdr_valid and path_type_valid and addr_type_dst_valid and addr_type_src_valid and rsv_valid) then + return false end - return false + + -- This looks like a SCION packet, dissect it. + scion_proto.dissector(tvbuf, pktinfo, root) + -- Set the scion_proto dissector for the conversation, so that all packets with the same + -- 4-tuple use directly the scion_proto dissector (instead of calling again this + -- heuristic function). + pktinfo.conversation = scion_proto + return true end function scion_proto.dissector(tvbuf, pktinfo, root) From 4648e333ddd582bf9dd4cef628a2969912137f9f Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Wed, 14 Aug 2024 21:13:27 +0200 Subject: [PATCH 08/29] private/app/path: include IA in Sort function (#4600) fixes #4596 --- private/app/path/path.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/private/app/path/path.go b/private/app/path/path.go index 96666805e3..3b34749a43 100644 --- a/private/app/path/path.go +++ b/private/app/path/path.go @@ -46,7 +46,7 @@ func Sort(paths []snet.Path) { return len(intfA) < len(intfB) } for i := range intfA { - if iaA, iaB := intfA[i].IA, intfA[i].IA; iaA != iaB { + if iaA, iaB := intfA[i].IA, intfB[i].IA; iaA != iaB { return iaA < iaB } if idA, idB := intfA[i].ID, intfB[i].ID; idA != idB { From 4c929f6b440c568663b4194c125df15cad544bb4 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Thu, 15 Aug 2024 19:13:31 +0200 Subject: [PATCH 09/29] pkg/private/serrors: act the constructors deprecations (#4595) Implement the deprecation of the serrors constructors. Wrap() -> JoinNoStack() WithCtx() -> WrapNoStack()/JoinNoStack() WrapStr() -> Wrap() To apply the matching changes to other go src code, use "gopatch -p patchfile ./..." where patchfile is one of (in that order): ``` @@ @@ - serrors.WithCtx(...) + serrors.WrapNoStack("error", ...) ``` ``` @@ @@ - serrors.Wrap(...) + serrors.JoinNoStack(...) ``` ``` @@ @@ - serrors.WrapStr(...) + serrors.Wrap(...) ``` --- acceptance/router_benchmark/brload/main.go | 2 +- control/beacon/chain_checker.go | 6 +- control/beacon/policy.go | 4 +- control/beaconing/extender.go | 12 +- control/beaconing/grpc/beacon_sender.go | 2 +- control/beaconing/grpc/creation_server.go | 4 +- control/beaconing/handler.go | 4 +- control/beaconing/originator.go | 15 +-- control/beaconing/propagator.go | 8 +- control/beaconing/staticinfo_config.go | 6 +- control/cmd/control/main.go | 32 ++--- control/cmd/control/sample.go | 2 +- control/drkey/arc.go | 2 +- control/drkey/grpc/drkey_service.go | 40 +++---- control/drkey/grpc/fetcher.go | 16 +-- control/drkey/grpc/protobuf.go | 12 +- control/drkey/secret_value_mgr.go | 6 +- control/drkey/service_engine.go | 18 +-- control/messaging.go | 2 +- control/mgmtapi/api.go | 2 +- control/observability.go | 2 +- control/policy.go | 2 +- control/revhandler.go | 6 +- control/segreq/authoritative.go | 6 +- control/segreq/expander.go | 2 +- control/segreq/fetcher.go | 4 +- control/segreq/forwarder.go | 23 ++-- control/segreq/helpers.go | 2 +- control/trust.go | 4 +- control/trust/grpc/proto.go | 4 +- control/trust/signer.go | 8 +- daemon/cmd/daemon/main.go | 22 ++-- daemon/daemon.go | 5 +- daemon/drkey/client_engine.go | 18 +-- daemon/drkey/grpc/fetcher.go | 18 +-- daemon/drkey/grpc/protobuf.go | 12 +- daemon/internal/servers/grpc.go | 22 ++-- demo/drkey/main.go | 16 +-- dispatcher/cmd/dispatcher/main.go | 6 +- dispatcher/dispatcher.go | 10 +- gateway/cmd/gateway/main.go | 14 +-- gateway/control/engine.go | 2 +- gateway/control/enginecontroller.go | 8 +- gateway/control/grpc/discoverer.go | 8 +- gateway/control/grpc/prefix_fetcher.go | 2 +- gateway/control/grpc/probeserver.go | 2 +- gateway/control/router.go | 8 +- gateway/control/sessionmonitor.go | 4 +- gateway/control/sessionpolicy.go | 8 +- gateway/control/watcher.go | 2 +- gateway/dataplane/ipforwarder.go | 2 +- gateway/gateway.go | 20 ++-- gateway/loader.go | 4 +- gateway/pathhealth/pathwatcher.go | 6 +- gateway/pktcls/json.go | 3 +- gateway/pktcls/parse.go | 28 +++-- gateway/pktcls/pred_ipv4.go | 4 +- gateway/routemgr/device.go | 4 +- gateway/routemgr/linux.go | 2 +- gateway/routing/file.go | 4 +- gateway/routing/marshal.go | 12 +- gateway/xnet/xnet.go | 13 ++- pkg/addr/addr.go | 6 +- pkg/addr/fmt.go | 4 +- pkg/addr/isdas.go | 6 +- pkg/daemon/apitypes.go | 2 +- pkg/daemon/grpc.go | 20 ++-- pkg/drkey/generic/generic.go | 14 +-- pkg/drkey/protocol.go | 2 +- pkg/drkey/specific/specific.go | 14 +-- pkg/experimental/hiddenpath/discovery.go | 8 +- pkg/experimental/hiddenpath/group.go | 21 ++-- pkg/experimental/hiddenpath/grpc/discovery.go | 6 +- pkg/experimental/hiddenpath/grpc/requester.go | 6 +- .../hiddenpath/registrationpolicy.go | 16 +-- pkg/experimental/hiddenpath/registry.go | 4 +- pkg/grpc/dialer.go | 2 +- pkg/log/log.go | 8 +- .../processmetrics/processmetrics_linux.go | 7 +- pkg/private/serrors/errors.go | 79 ++++++------- pkg/private/serrors/errors_test.go | 110 ++++++++++-------- .../serrors/testdata/error-with-context.log | 2 +- .../{wrapped-error.err => joined-error.err} | 0 .../{wrapped-error.log => joined-error.log} | 0 pkg/private/xtest/graph/graph.go | 2 +- pkg/private/xtest/graphupdater/updater.go | 10 +- pkg/scrypto/cppki/ca.go | 10 +- pkg/scrypto/cppki/certs.go | 20 ++-- pkg/scrypto/cppki/id.go | 2 +- pkg/scrypto/cppki/signed_trc.go | 19 +-- pkg/scrypto/cppki/trc.go | 48 ++++---- pkg/scrypto/cppki/trc_asn1.go | 16 +-- pkg/scrypto/mac.go | 4 +- pkg/scrypto/signed/msg.go | 8 +- pkg/segment/as.go | 4 +- pkg/segment/hop.go | 4 +- pkg/segment/seg.go | 10 +- pkg/slayers/path/onehop/onehop.go | 4 +- pkg/snet/addrutil/addrutil.go | 2 +- pkg/snet/packet.go | 12 +- pkg/snet/packet_conn.go | 10 +- pkg/snet/packet_test.go | 2 +- pkg/snet/path/scion.go | 2 +- pkg/snet/reader.go | 2 +- pkg/snet/reply_pather.go | 6 +- pkg/snet/snet.go | 3 +- pkg/snet/squic/net.go | 8 +- pkg/snet/udpaddr.go | 8 +- pkg/spao/mac.go | 6 +- private/app/appnet/addr.go | 4 +- private/app/appnet/infraenv.go | 14 +-- private/app/env/env.go | 2 +- private/app/flag/env.go | 10 +- private/app/launcher/launcher.go | 12 +- private/app/path/path.go | 8 +- private/app/path/pathprobe/paths.go | 16 +-- private/ca/renewal/ca_signer_gen.go | 10 +- private/ca/renewal/grpc/delegating_handler.go | 6 +- private/ca/renewal/grpc/renewal.go | 4 +- private/ca/renewal/request.go | 40 +++---- private/config/config.go | 6 +- private/env/docker.go | 2 +- private/env/env.go | 2 +- private/keyconf/keyconf.go | 6 +- private/mgmtapi/cppki/api/api.go | 2 +- .../api/testdata/certificates-malformed.json | 2 +- private/mgmtapi/jwtauth/jwt.go | 8 +- private/mgmtapi/segments/api/api.go | 4 +- private/mgmtapi/segments/api/api_test.go | 4 +- private/path/pathpol/hop_pred.go | 8 +- private/path/pathpol/sequence.go | 3 +- private/segment/segfetcher/fetcher.go | 6 +- private/segment/segfetcher/grpc/requester.go | 2 +- private/segment/segfetcher/pather.go | 2 +- private/segment/seghandler/seghandler.go | 4 +- private/segment/seghandler/seghandler_test.go | 6 +- private/segment/segverifier/segverifier.go | 3 +- private/service/statuspages.go | 2 +- private/storage/beacon/sqlite/db.go | 6 +- private/storage/db/errors.go | 10 +- private/storage/db/sqlite.go | 20 ++-- private/storage/path/sqlite/sqlite.go | 30 ++--- private/storage/trust/sqlite/db.go | 39 ++++--- private/svc/resolver.go | 13 ++- private/svc/svc.go | 2 +- private/topology/interface.go | 13 ++- private/topology/json/json.go | 4 +- private/topology/raw.go | 4 +- private/topology/reload.go | 4 +- private/topology/topology.go | 32 ++--- private/trust/db_inspector.go | 6 +- private/trust/fetching_provider.go | 22 ++-- private/trust/grpc/fetcher.go | 14 +-- private/trust/grpc/proto.go | 4 +- private/trust/recurser.go | 6 +- private/trust/router.go | 6 +- private/trust/signer.go | 2 +- private/trust/signer_gen.go | 2 +- private/trust/store.go | 23 ++-- private/trust/tls_verifier.go | 12 +- private/trust/verifier.go | 8 +- private/underlay/conn/conn.go | 17 +-- private/underlay/sockctrl/sockctrl.go | 6 +- router/bfd/session.go | 4 +- router/cmd/router/main.go | 8 +- router/connector.go | 16 +-- router/control/iactx.go | 6 +- router/dataplane.go | 61 +++++----- scion-pki/certs/create.go | 36 +++--- scion-pki/certs/fingerprint.go | 2 +- scion-pki/certs/inspect.go | 12 +- scion-pki/certs/match.go | 6 +- scion-pki/certs/renew.go | 43 +++---- scion-pki/certs/sign.go | 18 +-- scion-pki/certs/verify.go | 20 ++-- scion-pki/cmd/scion-pki/gendocs.go | 4 +- scion-pki/conf/trc.go | 6 +- scion-pki/file/file.go | 6 +- scion-pki/key/fingerprint.go | 14 +-- scion-pki/key/match.go | 6 +- scion-pki/key/private.go | 8 +- scion-pki/key/public.go | 10 +- scion-pki/key/symmetric.go | 8 +- scion-pki/testcrypto/config.go | 4 +- scion-pki/testcrypto/testcrypto.go | 24 ++-- scion-pki/testcrypto/update.go | 49 ++++---- scion-pki/trcs/combine.go | 10 +- scion-pki/trcs/extract.go | 10 +- scion-pki/trcs/format.go | 6 +- scion-pki/trcs/human.go | 4 +- scion-pki/trcs/payload.go | 12 +- scion-pki/trcs/sign.go | 18 +-- scion-pki/trcs/verify.go | 24 ++-- scion/cmd/scion/address.go | 2 +- scion/cmd/scion/gendocs.go | 4 +- scion/cmd/scion/ping.go | 12 +- scion/cmd/scion/showpaths.go | 8 +- scion/cmd/scion/traceroute.go | 12 +- scion/ping/ping.go | 4 +- scion/showpaths/showpaths.go | 8 +- scion/traceroute/traceroute.go | 16 +-- tools/braccept/runner/compare.go | 2 +- tools/braccept/runner/run.go | 15 +-- tools/buildkite/buildkite.go | 4 +- .../buildkite/cmd/buildkite_artifacts/main.go | 2 +- tools/end2end/main.go | 28 ++--- tools/end2end_integration/main.go | 14 +-- tools/integration/aslist.go | 4 +- tools/integration/binary.go | 8 +- tools/integration/cmd.go | 2 +- tools/integration/done.go | 2 +- tools/integration/integration.go | 6 +- tools/integration/integrationlib/common.go | 4 +- tools/pktgen/cmd/pktgen/config.go | 4 +- tools/pktgen/cmd/pktgen/main.go | 28 ++--- tools/pktgen/pcap.go | 6 +- 216 files changed, 1164 insertions(+), 1095 deletions(-) rename pkg/private/serrors/testdata/{wrapped-error.err => joined-error.err} (100%) rename pkg/private/serrors/testdata/{wrapped-error.log => joined-error.log} (100%) diff --git a/acceptance/router_benchmark/brload/main.go b/acceptance/router_benchmark/brload/main.go index 161f7d43a3..22eafa432e 100644 --- a/acceptance/router_benchmark/brload/main.go +++ b/acceptance/router_benchmark/brload/main.go @@ -306,7 +306,7 @@ func openDevices(interfaceNames []string) (map[string]*afpacket.TPacket, error) for _, intf := range interfaceNames { handle, err := afpacket.NewTPacket(afpacket.OptInterface(intf), afpacket.OptFrameSize(4096)) if err != nil { - return nil, serrors.WrapStr("creating TPacket", err) + return nil, serrors.Wrap("creating TPacket", err) } handles[intf] = handle } diff --git a/control/beacon/chain_checker.go b/control/beacon/chain_checker.go index 34cb9b796d..b5d95fb5a8 100644 --- a/control/beacon/chain_checker.go +++ b/control/beacon/chain_checker.go @@ -69,10 +69,10 @@ func (v chainChecker) Verify(ctx context.Context, signedMsg *cryptopb.SignedMess var keyID cppb.VerificationKeyID if err := proto.Unmarshal(hdr.VerificationKeyID, &keyID); err != nil { - return nil, serrors.WrapStr("parsing verification key ID", err) + return nil, serrors.Wrap("parsing verification key ID", err) } if len(keyID.SubjectKeyId) == 0 { - return nil, serrors.WrapStr("subject key ID must be set", err) + return nil, serrors.Wrap("subject key ID must be set", err) } ia := addr.IA(keyID.IsdAs) if ia.IsWildcard() { @@ -87,7 +87,7 @@ func (v chainChecker) Verify(ctx context.Context, signedMsg *cryptopb.SignedMess Validity: v.BoundValidity, } if err := v.checkChains(ctx, query); err != nil { - return nil, serrors.WrapStr("getting chains", err, + return nil, serrors.Wrap("getting chains", err, "query.isd_as", query.IA, "query.subject_key_id", fmt.Sprintf("%x", query.SubjectKeyID), "query.validity", query.Validity.String(), diff --git a/control/beacon/policy.go b/control/beacon/policy.go index ee0ea5ac34..44b2fa8bdd 100644 --- a/control/beacon/policy.go +++ b/control/beacon/policy.go @@ -216,7 +216,7 @@ func (p *Policy) initDefaults(t PolicyType) { func ParsePolicyYaml(b []byte, t PolicyType) (*Policy, error) { p := &Policy{} if err := yaml.UnmarshalStrict(b, p); err != nil { - return nil, serrors.WrapStr("Unable to parse policy", err) + return nil, serrors.Wrap("Unable to parse policy", err) } if p.Type != "" && p.Type != t { return nil, serrors.New("specified policy type does not match", @@ -231,7 +231,7 @@ func ParsePolicyYaml(b []byte, t PolicyType) (*Policy, error) { func LoadPolicyFromYaml(path string, t PolicyType) (*Policy, error) { b, err := os.ReadFile(path) if err != nil { - return nil, serrors.WrapStr("Unable to read policy file", err, "path", path) + return nil, serrors.Wrap("Unable to read policy file", err, "path", path) } return ParsePolicyYaml(b, t) } diff --git a/control/beaconing/extender.go b/control/beaconing/extender.go index 34374f2d10..561d3b0790 100644 --- a/control/beaconing/extender.go +++ b/control/beaconing/extender.go @@ -113,7 +113,7 @@ func (s *DefaultExtender) Extend( signers, err := s.SignerGen.Generate(ctx) if err != nil { - return serrors.WrapStr("getting signer", err) + return serrors.Wrap("getting signer", err) } now := time.Now() signer, err := trust.LastExpiring(signers, cppki.Validity{ @@ -121,7 +121,7 @@ func (s *DefaultExtender) Extend( NotAfter: now, }) if err != nil { - return serrors.WrapStr("selecting signer", err) + return serrors.Wrap("selecting signer", err) } // Make sure the hop expiration time is not longer than the signer expiration time. expTime := s.MaxExpTime() @@ -131,7 +131,7 @@ func (s *DefaultExtender) Extend( var err error expTime, err = path.ExpTimeFromDuration(signerExp.Sub(ts)) if err != nil { - return serrors.WrapStr( + return serrors.Wrap( "calculating expiry time from signer expiration time", err, "signer_expiration", signerExp, ) @@ -142,7 +142,7 @@ func (s *DefaultExtender) Extend( hopBeta := extractBeta(pseg) hopEntry, epicHopMac, err := s.createHopEntry(ingress, egress, expTime, ts, hopBeta) if err != nil { - return serrors.WrapStr("creating hop entry", err) + return serrors.Wrap("creating hop entry", err) } // The peer hop fields chain to the main hop field, just like any child hop field. @@ -234,7 +234,7 @@ func (s *DefaultExtender) createHopEntry( remoteInMTU, err := s.remoteMTU(ingress) if err != nil { - return seg.HopEntry{}, nil, serrors.WrapStr("checking remote ingress interface (mtu)", err, + return seg.HopEntry{}, nil, serrors.Wrap("checking remote ingress interface (mtu)", err, "interfaces", ingress) } hopF, epicMac := s.createHopF(ingress, egress, expTime, ts, beta) @@ -254,7 +254,7 @@ func (s *DefaultExtender) createPeerEntry(ingress, egress uint16, expTime uint8, remoteInIA, remoteInIfID, remoteInMTU, err := s.remoteInfo(ingress) if err != nil { - return seg.PeerEntry{}, nil, serrors.WrapStr("checking remote ingress interface", err, + return seg.PeerEntry{}, nil, serrors.Wrap("checking remote ingress interface", err, "ingress_interface", ingress) } hopF, epicMac := s.createHopF(ingress, egress, expTime, ts, beta) diff --git a/control/beaconing/grpc/beacon_sender.go b/control/beaconing/grpc/beacon_sender.go index 2f8cb96ed8..b926a484a1 100644 --- a/control/beaconing/grpc/beacon_sender.go +++ b/control/beaconing/grpc/beacon_sender.go @@ -50,7 +50,7 @@ func (f *BeaconSenderFactory) NewSender( } conn, err := f.Dialer.Dial(ctx, addr) if err != nil { - return nil, serrors.WrapStr("dialing gRPC conn", err) + return nil, serrors.Wrap("dialing gRPC conn", err) } return &BeaconSender{ Conn: conn, diff --git a/control/beaconing/grpc/creation_server.go b/control/beaconing/grpc/creation_server.go index 26c3440caa..0cf49e414f 100644 --- a/control/beaconing/grpc/creation_server.go +++ b/control/beaconing/grpc/creation_server.go @@ -73,7 +73,7 @@ func (s SegmentCreationServer) Beacon(ctx context.Context, if err := s.Handler.HandleBeacon(ctx, b, peer); err != nil { logger.Debug("Failed to handle beacon", "peer", peer, "err", err) // TODO(roosd): return better error with status code. - return nil, serrors.WrapStr("handling beacon", err) + return nil, serrors.Wrap("handling beacon", err) } return &cppb.BeaconResponse{}, nil @@ -91,7 +91,7 @@ func extractIngressIfID(path snet.DataplanePath) (uint16, error) { } hf, err := rawScionPath.GetCurrentHopField() if err != nil { - return 0, serrors.WrapStr("getting current hop field", err) + return 0, serrors.Wrap("getting current hop field", err) } return hf.ConsIngress, nil } diff --git a/control/beaconing/handler.go b/control/beaconing/handler.go index 886ffee737..0773526aca 100644 --- a/control/beaconing/handler.go +++ b/control/beaconing/handler.go @@ -87,13 +87,13 @@ func (h Handler) HandleBeacon(ctx context.Context, b beacon.Beacon, peer *snet.U if err := h.verifySegment(ctx, b.Segment, peer); err != nil { logger.Info("Beacon verification failed", "err", err) h.updateMetric(span, labels.WithResult(prom.ErrVerify), err) - return serrors.WrapStr("verifying beacon", err) + return serrors.Wrap("verifying beacon", err) } stat, err := h.Inserter.InsertBeacon(ctx, b) if err != nil { logger.Debug("Failed to insert beacon", "err", err) h.updateMetric(span, labels.WithResult(prom.ErrDB), err) - return serrors.WrapStr("inserting beacon", err) + return serrors.Wrap("inserting beacon", err) } labels = labels.WithResult(resultValue(stat.Inserted, stat.Updated, stat.Filtered)) diff --git a/control/beaconing/originator.go b/control/beaconing/originator.go index 7219c6c1ba..c35b4e9038 100644 --- a/control/beaconing/originator.go +++ b/control/beaconing/originator.go @@ -163,7 +163,7 @@ func (o *beaconOriginator) originateBeacon(ctx context.Context) error { beacon, err := o.createBeacon(ctx) if err != nil { o.incrementMetrics(labels.WithResult("err_create")) - return serrors.WrapStr("creating beacon", err, "egress_interface", o.intf.TopoInfo().ID) + return serrors.Wrap("creating beacon", err, "egress_interface", o.intf.TopoInfo().ID) } senderStart := time.Now() @@ -178,17 +178,18 @@ func (o *beaconOriginator) originateBeacon(ctx context.Context) error { ) if err != nil { o.incrementMetrics(labels.WithResult(prom.ErrNetwork)) - return serrors.WrapStr("getting beacon sender", err, + return serrors.Wrap("getting beacon sender", err, "waited_for", time.Since(senderStart).String()) + } defer sender.Close() sendStart := time.Now() if err := sender.Send(ctx, beacon); err != nil { o.incrementMetrics(labels.WithResult(prom.ErrNetwork)) - return serrors.WrapStr("sending beacon", err, - "waited_for", time.Since(sendStart).String(), - ) + return serrors.Wrap("sending beacon", err, + "waited_for", time.Since(sendStart).String()) + } o.onSuccess(o.intf) o.incrementMetrics(labels.WithResult(prom.Success)) @@ -202,11 +203,11 @@ func (o *beaconOriginator) createBeacon(ctx context.Context) (*seg.PathSegment, } beacon, err := seg.CreateSegment(o.timestamp, uint16(segID.Uint64())) if err != nil { - return nil, serrors.WrapStr("creating segment", err) + return nil, serrors.Wrap("creating segment", err) } if err := o.Extender.Extend(ctx, beacon, 0, o.intf.TopoInfo().ID, nil); err != nil { - return nil, serrors.WrapStr("extending segment", err) + return nil, serrors.Wrap("extending segment", err) } return beacon, nil } diff --git a/control/beaconing/propagator.go b/control/beaconing/propagator.go index 85cb1ec0f4..46b7fdf483 100644 --- a/control/beaconing/propagator.go +++ b/control/beaconing/propagator.go @@ -165,7 +165,7 @@ func (p *Propagator) beaconsPerInterface( allBeacons, err := p.Provider.BeaconsToPropagate(ctx) if err != nil { - return nil, serrors.WrapStr("fetching beacons to propagate", err) + return nil, serrors.Wrap("fetching beacons to propagate", err) } var beacons []beacon.Beacon for _, b := range allBeacons { @@ -273,9 +273,9 @@ func (p *propagator) Propagate(ctx context.Context) error { for _, b := range p.beacons { p.incMetric(b.Segment.FirstIA(), b.InIfID, egress, prom.ErrNetwork) } - return serrors.WrapStr("getting beacon sender", err, - "waited_for", time.Since(senderStart).String(), - ) + return serrors.Wrap("getting beacon sender", err, + "waited_for", time.Since(senderStart).String()) + } defer sender.Close() diff --git a/control/beaconing/staticinfo_config.go b/control/beaconing/staticinfo_config.go index aa8c4f8a3d..34e485ad8a 100644 --- a/control/beaconing/staticinfo_config.go +++ b/control/beaconing/staticinfo_config.go @@ -91,13 +91,15 @@ type StaticInfoCfg struct { func ParseStaticInfoCfg(file string) (*StaticInfoCfg, error) { raw, err := os.ReadFile(file) if err != nil { - return nil, serrors.WrapStr("failed to read static info config: ", + return nil, serrors.Wrap("failed to read static info config: ", err, "file", file) + } var cfg StaticInfoCfg if err := json.Unmarshal(raw, &cfg); err != nil { - return nil, serrors.WrapStr("failed to parse static info config: ", + return nil, serrors.Wrap("failed to parse static info config: ", err, "file ", file) + } cfg.clean() return &cfg, nil diff --git a/control/cmd/control/main.go b/control/cmd/control/main.go index 3a7d5eb957..78be343ead 100644 --- a/control/cmd/control/main.go +++ b/control/cmd/control/main.go @@ -119,7 +119,7 @@ func realMain(ctx context.Context) error { Metrics: metrics.TopoLoader, }) if err != nil { - return serrors.WrapStr("creating topology loader", err) + return serrors.Wrap("creating topology loader", err) } g, errCtx := errgroup.WithContext(ctx) g.Go(func() error { @@ -143,7 +143,7 @@ func realMain(ctx context.Context) error { closer, err := cs.InitTracer(globalCfg.Tracing, globalCfg.General.ID) if err != nil { - return serrors.WrapStr("initializing tracer", err) + return serrors.Wrap("initializing tracer", err) } defer closer.Close() @@ -151,7 +151,7 @@ func realMain(ctx context.Context) error { defer revCache.Close() pathDB, err := storage.NewPathStorage(globalCfg.PathDB) if err != nil { - return serrors.WrapStr("initializing path storage", err) + return serrors.Wrap("initializing path storage", err) } pathDB = pathstoragemetrics.WrapDB(pathDB, pathstoragemetrics.Config{ Driver: string(storage.BackendSqlite), @@ -166,7 +166,7 @@ func realMain(ctx context.Context) error { trustDB, err := storage.NewTrustStorage(globalCfg.TrustDB) if err != nil { - return serrors.WrapStr("initializing trust storage", err) + return serrors.Wrap("initializing trust storage", err) } defer trustDB.Close() fileWrites := libmetrics.NewPromCounter(metrics.TrustTRCFileWritesTotal) @@ -224,11 +224,11 @@ func realMain(ctx context.Context) error { } quicStack, err := nc.QUICStack() if err != nil { - return serrors.WrapStr("initializing QUIC stack", err) + return serrors.Wrap("initializing QUIC stack", err) } tcpStack, err := nc.TCPStack() if err != nil { - return serrors.WrapStr("initializing TCP stack", err) + return serrors.Wrap("initializing TCP stack", err) } dialer := &libgrpc.QUICDialer{ Rewriter: &onehop.AddressRewriter{ @@ -240,7 +240,7 @@ func realMain(ctx context.Context) error { beaconDB, err := storage.NewBeaconStorage(globalCfg.BeaconDB, topo.IA()) if err != nil { - return serrors.WrapStr("initializing beacon storage", err) + return serrors.Wrap("initializing beacon storage", err) } defer beaconDB.Close() beaconDB = beaconstoragemetrics.WrapDB(beaconDB, beaconstoragemetrics.Config{ @@ -261,7 +261,7 @@ func realMain(ctx context.Context) error { }, ) if err != nil { - return serrors.WrapStr("initializing beacon store", err) + return serrors.Wrap("initializing beacon store", err) } trustengineCache := globalCfg.TrustEngine.Cache.New() @@ -594,11 +594,11 @@ func realMain(ctx context.Context) error { log.Debug("DRKey debug info", "epoch duration", epochDuration.String()) masterKey, err := loadMasterSecret(globalCfg.General.ConfigDir) if err != nil { - return serrors.WrapStr("loading master secret in DRKey", err) + return serrors.Wrap("loading master secret in DRKey", err) } svBackend, err := storage.NewDRKeySecretValueStorage(globalCfg.DRKey.SecretValueDB) if err != nil { - return serrors.WrapStr("initializing Secret Value DB", err) + return serrors.Wrap("initializing Secret Value DB", err) } svCounter := libmetrics.NewPromCounter(metrics.DRKeySecretValueQueriesTotal) svDB := &secret.Database{ @@ -615,7 +615,7 @@ func realMain(ctx context.Context) error { defer svDB.Close() level1Backend, err := storage.NewDRKeyLevel1Storage(globalCfg.DRKey.Level1DB) if err != nil { - return serrors.WrapStr("initializing DRKey DB", err) + return serrors.Wrap("initializing DRKey DB", err) } lvl1Counter := libmetrics.NewPromCounter(metrics.DRKeyLevel1QueriesTotal) level1DB := &level1.Database{ @@ -670,7 +670,7 @@ func realMain(ctx context.Context) error { g.Go(func() error { defer log.HandlePanic() if err := quicServer.Serve(quicStack.Listener); err != nil { - return serrors.WrapStr("serving gRPC/QUIC API", err) + return serrors.Wrap("serving gRPC/QUIC API", err) } return nil }) @@ -678,7 +678,7 @@ func realMain(ctx context.Context) error { g.Go(func() error { defer log.HandlePanic() if err := tcpServer.Serve(tcpStack); err != nil { - return serrors.WrapStr("serving gRPC/TCP API", err) + return serrors.Wrap("serving gRPC/TCP API", err) } return nil }) @@ -720,7 +720,7 @@ func realMain(ctx context.Context) error { g.Go(func() error { defer log.HandlePanic() if err := s.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { - return serrors.WrapStr("serving service management API", err) + return serrors.Wrap("serving service management API", err) } return nil }) @@ -810,7 +810,7 @@ func realMain(ctx context.Context) error { EPIC: globalCfg.BS.EPIC, }) if err != nil { - return serrors.WrapStr("starting periodic tasks", err) + return serrors.Wrap("starting periodic tasks", err) } defer tasks.Kill() log.Info("Started periodic tasks") @@ -1018,7 +1018,7 @@ func updateCAHealthMetrics(caHealthGauge libmetrics.Gauge, caStatus api.CAHealth func loadMasterSecret(dir string) (keyconf.Master, error) { masterKey, err := keyconf.LoadMaster(filepath.Join(dir, "keys")) if err != nil { - return keyconf.Master{}, serrors.WrapStr("error getting master secret", err) + return keyconf.Master{}, serrors.Wrap("error getting master secret", err) } return masterKey, nil } diff --git a/control/cmd/control/sample.go b/control/cmd/control/sample.go index 28b0b09a7a..818512f95a 100644 --- a/control/cmd/control/sample.go +++ b/control/cmd/control/sample.go @@ -35,7 +35,7 @@ func newSamplePolicy(pather command.Pather) *cobra.Command { var sample beacon.Policy sample.InitDefaults() if err := yaml.NewEncoder(os.Stdout).Encode(sample); err != nil { - return serrors.WrapStr("producing sample policy", err) + return serrors.Wrap("producing sample policy", err) } return nil }, diff --git a/control/drkey/arc.go b/control/drkey/arc.go index ff9641f4b9..0db997a46f 100644 --- a/control/drkey/arc.go +++ b/control/drkey/arc.go @@ -30,7 +30,7 @@ type Level1ARC struct { func NewLevel1ARC(size int) (*Level1ARC, error) { cache, err := arc.NewARC[Level1PrefetchInfo, struct{}](size) if err != nil { - return nil, serrors.WrapStr("creating Level1ARC cache", err) + return nil, serrors.Wrap("creating Level1ARC cache", err) } return &Level1ARC{ cache: cache, diff --git a/control/drkey/grpc/drkey_service.go b/control/drkey/grpc/drkey_service.go index 23434a3913..5821722025 100644 --- a/control/drkey/grpc/drkey_service.go +++ b/control/drkey/grpc/drkey_service.go @@ -73,12 +73,12 @@ func (d *Server) DRKeyLevel1( } dstIA, err := d.validateClientCertificate(peer) if err != nil { - return nil, serrors.WrapStr("retrieving info from certificate", err) + return nil, serrors.Wrap("retrieving info from certificate", err) } lvl1Meta, err := getMeta(req.ProtocolId, req.ValTime, d.LocalIA, dstIA) if err != nil { - return nil, serrors.WrapStr("invalid DRKey Level1 request", err) + return nil, serrors.Wrap("invalid DRKey Level1 request", err) } // validate requested ProtoID is specific @@ -89,7 +89,7 @@ func (d *Server) DRKeyLevel1( lvl1Key, err := d.Engine.DeriveLevel1(lvl1Meta) if err != nil { - return nil, serrors.WrapStr("deriving level 1 key", err) + return nil, serrors.Wrap("deriving level 1 key", err) } resp := keyToLevel1Resp(lvl1Key) return resp, nil @@ -112,15 +112,15 @@ func (d *Server) DRKeyIntraLevel1( meta, err := getMeta(req.ProtocolId, req.ValTime, addr.IA(req.SrcIa), addr.IA(req.DstIa)) if err != nil { - return nil, serrors.WrapStr("parsing AS-AS request", err) + return nil, serrors.Wrap("parsing AS-AS request", err) } if err := d.validateAllowedHost(meta.ProtoId, peer.Addr); err != nil { - return nil, serrors.WrapStr("validating AS-AS request", err) + return nil, serrors.Wrap("validating AS-AS request", err) } lvl1Key, err := d.Engine.GetLevel1Key(ctx, meta) if err != nil { - return nil, serrors.WrapStr("getting AS-AS host key", err) + return nil, serrors.Wrap("getting AS-AS host key", err) } resp := keyToASASResp(lvl1Key) @@ -140,15 +140,15 @@ func (d *Server) DRKeyASHost( meta, err := requestToASHostMeta(req) if err != nil { - return nil, serrors.WrapStr("parsing DRKey AS-Host request", err) + return nil, serrors.Wrap("parsing DRKey AS-Host request", err) } if err := validateASHostReq(meta, d.LocalIA, peer.Addr); err != nil { - return nil, serrors.WrapStr("validating AS-Host request", err) + return nil, serrors.Wrap("validating AS-Host request", err) } asHostKey, err := d.Engine.DeriveASHost(ctx, meta) if err != nil { - return nil, serrors.WrapStr("deriving AS-Host request", err) + return nil, serrors.Wrap("deriving AS-Host request", err) } resp := keyToASHostResp(asHostKey) @@ -168,14 +168,14 @@ func (d *Server) DRKeyHostAS( meta, err := requestToHostASMeta(req) if err != nil { - return nil, serrors.WrapStr("parsing Host-AS request", err) + return nil, serrors.Wrap("parsing Host-AS request", err) } if err := validateHostASReq(meta, d.LocalIA, peer.Addr); err != nil { - return nil, serrors.WrapStr("validating Host-AS request", err) + return nil, serrors.Wrap("validating Host-AS request", err) } key, err := d.Engine.DeriveHostAS(ctx, meta) if err != nil { - return nil, serrors.WrapStr("deriving Host-AS request", err) + return nil, serrors.Wrap("deriving Host-AS request", err) } resp := keyToHostASResp(key) @@ -195,15 +195,15 @@ func (d *Server) DRKeyHostHost( meta, err := requestToHostHostMeta(req) if err != nil { - return nil, serrors.WrapStr("parsing Host-Host request", err) + return nil, serrors.Wrap("parsing Host-Host request", err) } if err := validateHostHostReq(meta, d.LocalIA, peer.Addr); err != nil { - return nil, serrors.WrapStr("validating Host-Host request", err) + return nil, serrors.Wrap("validating Host-Host request", err) } key, err := d.Engine.DeriveHostHost(ctx, meta) if err != nil { - return nil, serrors.WrapStr("deriving Host-Host request", err) + return nil, serrors.Wrap("deriving Host-Host request", err) } resp := keyToHostHostResp(key) @@ -223,14 +223,14 @@ func (d *Server) DRKeySecretValue( meta, err := secretRequestToMeta(req) if err != nil { - return nil, serrors.WrapStr("parsing Host-Host request", err) + return nil, serrors.Wrap("parsing Host-Host request", err) } if err := d.validateAllowedHost(meta.ProtoId, peer.Addr); err != nil { - return nil, serrors.WrapStr("validating SV request", err) + return nil, serrors.Wrap("validating SV request", err) } sv, err := d.Engine.GetSecretValue(ctx, meta) if err != nil { - return nil, serrors.WrapStr("getting SV from persistence", err) + return nil, serrors.Wrap("getting SV from persistence", err) } resp := secretToProtoResp(sv) return resp, nil @@ -251,7 +251,7 @@ func (d *Server) validateClientCertificate(peer *peer.Peer) (addr.IA, error) { } certIA, err := d.ClientCertificateVerifier.VerifyParsedClientCertificate(chain) if err != nil { - return 0, serrors.WrapStr("invalid certificate", err) + return 0, serrors.Wrap("invalid certificate", err) } return certIA, nil } @@ -366,7 +366,7 @@ func getMeta(protoId drkeypb.Protocol, ts *timestamppb.Timestamp, srcIA, dstIA addr.IA) (drkey.Level1Meta, error) { err := ts.CheckValid() if err != nil { - return drkey.Level1Meta{}, serrors.WrapStr("invalid valTime from pb req", err) + return drkey.Level1Meta{}, serrors.Wrap("invalid valTime from pb req", err) } return drkey.Level1Meta{ Validity: ts.AsTime(), diff --git a/control/drkey/grpc/fetcher.go b/control/drkey/grpc/fetcher.go index 4a1c26602d..03706b1d66 100644 --- a/control/drkey/grpc/fetcher.go +++ b/control/drkey/grpc/fetcher.go @@ -79,18 +79,18 @@ func (f *Fetcher) Level1( if err == nil { lvl1Key, err := getLevel1KeyFromReply(meta, rep) if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("obtaining level 1 key from reply", err) + return drkey.Level1Key{}, serrors.Wrap("obtaining level 1 key from reply", err) } return lvl1Key, nil } errList = append(errList, - serrors.WrapStr("fetching level1", err, "try", i+1, "peer", meta.SrcIA), + serrors.Wrap("fetching level1", err, "try", i+1, "peer", meta.SrcIA), ) } - return drkey.Level1Key{}, serrors.WrapStr( + return drkey.Level1Key{}, serrors.Wrap( "reached max retry attempts fetching level1 key", - errList, - ) + errList) + } func (f *Fetcher) getLevel1Key( @@ -113,13 +113,13 @@ func (f *Fetcher) getLevel1Key( defer cancelF() conn, err := f.Dialer.Dial(dialCtx, remote) if err != nil { - return nil, serrors.WrapStr("dialing", err) + return nil, serrors.Wrap("dialing", err) } defer conn.Close() client := cppb.NewDRKeyInterServiceClient(conn) rep, err := client.DRKeyLevel1(ctx, req) if err != nil { - return nil, serrors.WrapStr("requesting level 1 key", err) + return nil, serrors.Wrap("requesting level 1 key", err) } return rep, nil } @@ -127,7 +127,7 @@ func (f *Fetcher) getLevel1Key( func (f *Fetcher) pathToDst(ctx context.Context, dst addr.IA) (snet.Path, error) { paths, err := f.Router.AllRoutes(ctx, dst) if err != nil { - return nil, serrors.Wrap(errNotReachable, err) + return nil, serrors.JoinNoStack(errNotReachable, err) } if len(paths) == 0 { return nil, errNotReachable diff --git a/control/drkey/grpc/protobuf.go b/control/drkey/grpc/protobuf.go index 988c76bda8..848d72ed41 100644 --- a/control/drkey/grpc/protobuf.go +++ b/control/drkey/grpc/protobuf.go @@ -28,7 +28,7 @@ import ( func secretRequestToMeta(req *cppb.DRKeySecretValueRequest) (drkey.SecretValueMeta, error) { err := req.ValTime.CheckValid() if err != nil { - return drkey.SecretValueMeta{}, serrors.WrapStr("invalid valTime from request", err) + return drkey.SecretValueMeta{}, serrors.Wrap("invalid valTime from request", err) } return drkey.SecretValueMeta{ Validity: req.ValTime.AsTime(), @@ -58,11 +58,11 @@ func getLevel1KeyFromReply( err := rep.EpochBegin.CheckValid() if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("invalid EpochBegin from response", err) + return drkey.Level1Key{}, serrors.Wrap("invalid EpochBegin from response", err) } err = rep.EpochEnd.CheckValid() if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("invalid EpochEnd from response", err) + return drkey.Level1Key{}, serrors.Wrap("invalid EpochEnd from response", err) } epoch := drkey.Epoch{ Validity: cppki.Validity{ @@ -103,7 +103,7 @@ func keyToASASResp(drkey drkey.Level1Key) *cppb.DRKeyIntraLevel1Response { func requestToASHostMeta(req *cppb.DRKeyASHostRequest) (drkey.ASHostMeta, error) { err := req.ValTime.CheckValid() if err != nil { - return drkey.ASHostMeta{}, serrors.WrapStr("invalid valTime from pb request", err) + return drkey.ASHostMeta{}, serrors.Wrap("invalid valTime from pb request", err) } return drkey.ASHostMeta{ ProtoId: drkey.Protocol(req.ProtocolId), @@ -125,7 +125,7 @@ func keyToASHostResp(drkey drkey.ASHostKey) *cppb.DRKeyASHostResponse { func requestToHostASMeta(req *cppb.DRKeyHostASRequest) (drkey.HostASMeta, error) { err := req.ValTime.CheckValid() if err != nil { - return drkey.HostASMeta{}, serrors.WrapStr("invalid valTime from pb request", err) + return drkey.HostASMeta{}, serrors.Wrap("invalid valTime from pb request", err) } return drkey.HostASMeta{ ProtoId: drkey.Protocol(req.ProtocolId), @@ -147,7 +147,7 @@ func keyToHostASResp(drkey drkey.HostASKey) *cppb.DRKeyHostASResponse { func requestToHostHostMeta(req *cppb.DRKeyHostHostRequest) (drkey.HostHostMeta, error) { err := req.ValTime.CheckValid() if err != nil { - return drkey.HostHostMeta{}, serrors.WrapStr("invalid valTime from pb request", err) + return drkey.HostHostMeta{}, serrors.Wrap("invalid valTime from pb request", err) } return drkey.HostHostMeta{ ProtoId: drkey.Protocol(req.ProtocolId), diff --git a/control/drkey/secret_value_mgr.go b/control/drkey/secret_value_mgr.go index b70549c0be..812172ab1c 100644 --- a/control/drkey/secret_value_mgr.go +++ b/control/drkey/secret_value_mgr.go @@ -56,7 +56,7 @@ func (s *secretValueBackend) getSecretValue( return k, nil } if err != drkey.ErrKeyNotFound { - return drkey.SecretValue{}, serrors.WrapStr("retrieving SV from db", err) + return drkey.SecretValue{}, serrors.Wrap("retrieving SV from db", err) } idx := meta.Validity.Unix() / duration @@ -65,11 +65,11 @@ func (s *secretValueBackend) getSecretValue( epoch := drkey.NewEpoch(begin, end) sv, err := drkey.DeriveSV(meta.ProtoId, epoch, s.masterKey) if err != nil { - return drkey.SecretValue{}, serrors.WrapStr("deriving DRKey secret value", err) + return drkey.SecretValue{}, serrors.Wrap("deriving DRKey secret value", err) } err = s.db.InsertValue(ctx, sv.ProtoId, sv.Epoch) if err != nil { - return drkey.SecretValue{}, serrors.WrapStr("inserting SV in persistence", err) + return drkey.SecretValue{}, serrors.Wrap("inserting SV in persistence", err) } return sv, nil } diff --git a/control/drkey/service_engine.go b/control/drkey/service_engine.go index ffc018192d..c9c0641b06 100644 --- a/control/drkey/service_engine.go +++ b/control/drkey/service_engine.go @@ -97,11 +97,11 @@ func (s *ServiceEngine) DeriveLevel1(meta drkey.Level1Meta) (drkey.Level1Key, er Validity: meta.Validity, }) if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("getting secret value", err) + return drkey.Level1Key{}, serrors.Wrap("getting secret value", err) } key, err := deriveLevel1(meta, sv) if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("deriving level 1 key", err) + return drkey.Level1Key{}, serrors.Wrap("deriving level 1 key", err) } return key, nil } @@ -117,7 +117,7 @@ func (s *ServiceEngine) DeriveASHost( level1Key, err := s.obtainLevel1Key(ctx, meta.ProtoId, meta.Validity, meta.SrcIA, meta.DstIA) if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("getting level1 key", err) + return drkey.ASHostKey{}, serrors.Wrap("getting level1 key", err) } var deriver interface { @@ -152,7 +152,7 @@ func (s *ServiceEngine) DeriveHostAS( level1Key, err := s.obtainLevel1Key(ctx, meta.ProtoId, meta.Validity, meta.SrcIA, meta.DstIA) if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("getting level1 key", err) + return drkey.HostASKey{}, serrors.Wrap("getting level1 key", err) } var deriver interface { @@ -195,7 +195,7 @@ func (s *ServiceEngine) DeriveHostHost( hostASKey, err := s.DeriveHostAS(ctx, hostASMeta) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("computing intermediate Host-AS key", err) + return drkey.HostHostKey{}, serrors.Wrap("computing intermediate Host-AS key", err) } var deriver interface { @@ -255,18 +255,18 @@ func (s *ServiceEngine) getLevel1Key( return k, nil } if err != drkey.ErrKeyNotFound { - return drkey.Level1Key{}, serrors.WrapStr("retrieving key from DB", err) + return drkey.Level1Key{}, serrors.Wrap("retrieving key from DB", err) } // get it from another server. remoteKey, err := s.Fetcher.Level1(ctx, meta) if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("obtaining level 1 key from CS", err) + return drkey.Level1Key{}, serrors.Wrap("obtaining level 1 key from CS", err) } // keep it in our DB. err = s.DB.InsertLevel1Key(ctx, remoteKey) if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("storing obtained key in DB", err) + return drkey.Level1Key{}, serrors.Wrap("storing obtained key in DB", err) } return remoteKey, nil } @@ -297,7 +297,7 @@ type fromPrefetcher struct{} func deriveLevel1(meta drkey.Level1Meta, sv drkey.SecretValue) (drkey.Level1Key, error) { key, err := specific.Deriver{}.DeriveLevel1(meta.DstIA, sv.Key) if err != nil { - return drkey.Level1Key{}, serrors.WrapStr("computing level1 raw key", err) + return drkey.Level1Key{}, serrors.Wrap("computing level1 raw key", err) } return drkey.Level1Key{ Epoch: sv.Epoch, diff --git a/control/messaging.go b/control/messaging.go index 14d26b15a6..f3a145e40d 100644 --- a/control/messaging.go +++ b/control/messaging.go @@ -27,7 +27,7 @@ import ( func MACGenFactory(configDir string) (func() hash.Hash, error) { mk, err := keyconf.LoadMaster(filepath.Join(configDir, "keys")) if err != nil { - return nil, serrors.WrapStr("loading master key", err) + return nil, serrors.Wrap("loading master key", err) } hfMacFactory, err := scrypto.HFMacFactory(mk.Key0) if err != nil { diff --git a/control/mgmtapi/api.go b/control/mgmtapi/api.go index 666df8bfe3..9f89921399 100644 --- a/control/mgmtapi/api.go +++ b/control/mgmtapi/api.go @@ -122,7 +122,7 @@ func (s *Server) GetBeacons(w http.ResponseWriter, r *http.Request, params GetBe if ia, err := addr.ParseIA(*params.StartIsdAs); err == nil { q.StartsAt = []addr.IA{ia} } else { - errs = append(errs, serrors.WrapStr("parsing start_isd_as", err)) + errs = append(errs, serrors.Wrap("parsing start_isd_as", err)) } } if params.Usages != nil { diff --git a/control/observability.go b/control/observability.go index 2ddabc1fca..b4d439603a 100644 --- a/control/observability.go +++ b/control/observability.go @@ -342,7 +342,7 @@ func RegisterHTTPEndpoints( statusPages["ca"] = caStatusPage(ca) } if err := statusPages.Register(http.DefaultServeMux, elemId); err != nil { - return serrors.WrapStr("registering status pages", err) + return serrors.Wrap("registering status pages", err) } return nil } diff --git a/control/policy.go b/control/policy.go index 62dbd82df5..aeaf942549 100644 --- a/control/policy.go +++ b/control/policy.go @@ -54,7 +54,7 @@ func loadPolicy(fn string, t beacon.PolicyType) (beacon.Policy, error) { if fn != "" { p, err := beacon.LoadPolicyFromYaml(fn, t) if err != nil { - return policy, serrors.WrapStr("loading beaconing policy", err, "file", fn, "type", t) + return policy, serrors.Wrap("loading beaconing policy", err, "file", fn, "type", t) } policy = *p } diff --git a/control/revhandler.go b/control/revhandler.go index 141eb06aa8..76bb1ef646 100644 --- a/control/revhandler.go +++ b/control/revhandler.go @@ -30,11 +30,11 @@ type RevocationHandler struct { func (h RevocationHandler) Revoke(ctx context.Context, revInfo *path_mgmt.RevInfo) error { if _, err := h.RevCache.Insert(ctx, revInfo); err != nil { - return serrors.WrapStr("inserting revocation", err, + return serrors.Wrap("inserting revocation", err, "isd_as", revInfo.IA(), "interface_id", revInfo.IfID, - "expiration", revInfo.Expiration(), - ) + "expiration", revInfo.Expiration()) + } return nil } diff --git a/control/segreq/authoritative.go b/control/segreq/authoritative.go index 9d24bbff52..f379131d01 100644 --- a/control/segreq/authoritative.go +++ b/control/segreq/authoritative.go @@ -58,11 +58,13 @@ func (a AuthoritativeLookup) classify(ctx context.Context, switch { case src != a.LocalIA: - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "src must be local AS") + case dst.ISD() == 0: - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "zero ISD dst") + case dst.ISD() == a.LocalIA.ISD(): dstCore, err := a.CoreChecker.IsCore(ctx, dst) if err != nil { diff --git a/control/segreq/expander.go b/control/segreq/expander.go index b23a62ff6c..c348bf4d29 100644 --- a/control/segreq/expander.go +++ b/control/segreq/expander.go @@ -63,7 +63,7 @@ func (e *WildcardExpander) ExpandSrcWildcard(ctx context.Context, func (e *WildcardExpander) coreASes(ctx context.Context, isd addr.ISD) ([]addr.IA, error) { coreASes, err := e.Inspector.ByAttributes(ctx, isd, trust.Core) if err != nil { - return nil, serrors.WrapStr("failed to get local core ASes", err) + return nil, serrors.Wrap("failed to get local core ASes", err) } return coreASes, nil } diff --git a/control/segreq/fetcher.go b/control/segreq/fetcher.go index 2252bc6801..c909557231 100644 --- a/control/segreq/fetcher.go +++ b/control/segreq/fetcher.go @@ -182,7 +182,7 @@ func (p *dstProvider) Dst(ctx context.Context, req segfetcher.Request) (net.Addr // would then lead to an infinite recursion. up, err := p.upPath(ctx, dst) if err != nil { - return nil, serrors.Wrap(segfetcher.ErrNotReachable, err) + return nil, serrors.JoinNoStack(segfetcher.ErrNotReachable, err) } path = up case seg.TypeDown: @@ -191,7 +191,7 @@ func (p *dstProvider) Dst(ctx context.Context, req segfetcher.Request) (net.Addr // allows clients to retry with possibly different path in case of failure. paths, err := p.router.AllRoutes(ctx, dst) if err != nil { - return nil, serrors.Wrap(segfetcher.ErrNotReachable, err) + return nil, serrors.JoinNoStack(segfetcher.ErrNotReachable, err) } if len(paths) == 0 { return nil, segfetcher.ErrNotReachable diff --git a/control/segreq/forwarder.go b/control/segreq/forwarder.go index 0d4ab28a8d..89c906ea4d 100644 --- a/control/segreq/forwarder.go +++ b/control/segreq/forwarder.go @@ -54,7 +54,7 @@ func (f ForwardingLookup) LookupSegments(ctx context.Context, src, }, ) if err != nil { - return nil, serrors.WrapStr("expanding wildcard request", err) + return nil, serrors.Wrap("expanding wildcard request", err) } return f.Fetcher.Fetch(ctx, reqs, false) } @@ -64,13 +64,15 @@ func (f ForwardingLookup) classify(ctx context.Context, src, dst addr.IA) (seg.Type, error) { if src.ISD() == 0 || dst.ISD() == 0 { - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "zero ISD src or dst") + } if dst == f.LocalIA { // this could be an otherwise valid request, but probably the requester switched Src and Dst - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "dst is local AS, confusion?") + } srcCore, err := f.CoreChecker.IsCore(ctx, src) if err != nil { @@ -84,30 +86,35 @@ func (f ForwardingLookup) classify(ctx context.Context, case srcCore && dstCore: // core if src.ISD() != f.LocalIA.ISD() { - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "core segment request src ISD not local ISD") + } return seg.TypeCore, nil case srcCore: // down if src.ISD() != dst.ISD() { - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "down segment request src/dst in different ISD") + } return seg.TypeDown, nil case dstCore: // up if src != f.LocalIA { - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "up segment request src not local AS") + } if dst.ISD() != f.LocalIA.ISD() { - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "up segment request dst in different ISD") + } return seg.TypeUp, nil default: - return 0, serrors.WithCtx(segfetcher.ErrInvalidRequest, + return 0, serrors.JoinNoStack(segfetcher.ErrInvalidRequest, nil, "src", src, "dst", dst, "reason", "non-core src & dst") + } } diff --git a/control/segreq/helpers.go b/control/segreq/helpers.go index 391f243c77..fad893c0f2 100644 --- a/control/segreq/helpers.go +++ b/control/segreq/helpers.go @@ -66,7 +66,7 @@ func (s *SegSelector) SelectSeg(ctx context.Context, return revcache.NoRevokedHopIntf(ctx, s.RevCache, ps) }) if err != nil { - return nil, serrors.WrapStr("failed to filter segments", err) + return nil, serrors.Wrap("failed to filter segments", err) } if len(segs) < 1 { return nil, serrors.New("no segments found") diff --git a/control/trust.go b/control/trust.go index c05087b907..b16e49c05f 100644 --- a/control/trust.go +++ b/control/trust.go @@ -35,7 +35,7 @@ func LoadTrustMaterial(ctx context.Context, configDir string, db trust.DB) error certsDir := filepath.Join(configDir, "certs") loaded, err := trust.LoadTRCs(context.Background(), certsDir, db) if err != nil { - return serrors.WrapStr("loading TRCs from disk", err) + return serrors.Wrap("loading TRCs from disk", err) } logger.Info("TRCs loaded", "files", loaded.Loaded) for f, r := range loaded.Ignored { @@ -48,7 +48,7 @@ func LoadTrustMaterial(ctx context.Context, configDir string, db trust.DB) error localCertsDir := filepath.Join(configDir, "crypto/as") loaded, err = trust.LoadChains(context.Background(), localCertsDir, db) if err != nil { - return serrors.WrapStr("loading certificate chains from disk", err) + return serrors.Wrap("loading certificate chains from disk", err) } logger.Info("Certificate chains loaded", "files", loaded.Loaded) for f, r := range loaded.Ignored { diff --git a/control/trust/grpc/proto.go b/control/trust/grpc/proto.go index 5c1644e9a5..2eee5c53b1 100644 --- a/control/trust/grpc/proto.go +++ b/control/trust/grpc/proto.go @@ -29,7 +29,7 @@ func requestToChainQuery(req *cppb.ChainsRequest) (trust.ChainQuery, error) { var validity cppki.Validity if req.AtLeastValidUntil != nil { if err := req.AtLeastValidUntil.CheckValid(); err != nil { - return trust.ChainQuery{}, serrors.WrapStr("validating at_least_valid_until", err) + return trust.ChainQuery{}, serrors.Wrap("validating at_least_valid_until", err) } validity.NotAfter = req.AtLeastValidUntil.AsTime() @@ -43,7 +43,7 @@ func requestToChainQuery(req *cppb.ChainsRequest) (trust.ChainQuery, error) { } if req.AtLeastValidSince != nil { if err := req.AtLeastValidSince.CheckValid(); err != nil { - return trust.ChainQuery{}, serrors.WrapStr("validating at_least_valid_since", err) + return trust.ChainQuery{}, serrors.Wrap("validating at_least_valid_since", err) } validity.NotBefore = req.AtLeastValidSince.AsTime() } diff --git a/control/trust/signer.go b/control/trust/signer.go index 471ae724f2..a0a52c0615 100644 --- a/control/trust/signer.go +++ b/control/trust/signer.go @@ -43,7 +43,7 @@ func (s RenewingSigner) Sign( signers, err := s.SignerGen.Generate(ctx) if err != nil { - return nil, serrors.WrapStr("failed to generate signer", err) + return nil, serrors.Wrap("failed to generate signer", err) } now := time.Now() signer, err := trust.LastExpiring(signers, cppki.Validity{ @@ -51,7 +51,7 @@ func (s RenewingSigner) Sign( NotAfter: now, }) if err != nil { - return nil, serrors.WrapStr("selecting signer for current time", err) + return nil, serrors.Wrap("selecting signer for current time", err) } return signer.Sign(ctx, msg, associatedData...) } @@ -60,7 +60,7 @@ func (s RenewingSigner) Sign( func (s RenewingSigner) SignCMS(ctx context.Context, msg []byte) ([]byte, error) { signers, err := s.SignerGen.Generate(ctx) if err != nil { - return nil, serrors.WrapStr("failed to generate signer", err) + return nil, serrors.Wrap("failed to generate signer", err) } now := time.Now() signer, err := trust.LastExpiring(signers, cppki.Validity{ @@ -68,7 +68,7 @@ func (s RenewingSigner) SignCMS(ctx context.Context, msg []byte) ([]byte, error) NotAfter: now, }) if err != nil { - return nil, serrors.WrapStr("selecting signer for current time", err) + return nil, serrors.Wrap("selecting signer for current time", err) } return signer.SignCMS(ctx, msg) } diff --git a/daemon/cmd/daemon/main.go b/daemon/cmd/daemon/main.go index 5b3f7c3e05..5faf0c9bc2 100644 --- a/daemon/cmd/daemon/main.go +++ b/daemon/cmd/daemon/main.go @@ -90,7 +90,7 @@ func realMain(ctx context.Context) error { Metrics: loaderMetrics(), }) if err != nil { - return serrors.WrapStr("creating topology loader", err) + return serrors.Wrap("creating topology loader", err) } g, errCtx := errgroup.WithContext(ctx) g.Go(func() error { @@ -100,14 +100,14 @@ func realMain(ctx context.Context) error { closer, err := daemon.InitTracer(globalCfg.Tracing, globalCfg.General.ID) if err != nil { - return serrors.WrapStr("initializing tracer", err) + return serrors.Wrap("initializing tracer", err) } defer closer.Close() revCache := storage.NewRevocationStorage() pathDB, err := storage.NewPathStorage(globalCfg.PathDB) if err != nil { - return serrors.WrapStr("initializing path storage", err) + return serrors.Wrap("initializing path storage", err) } pathDB = pathstoragemetrics.WrapDB(pathDB, pathstoragemetrics.Config{ Driver: string(storage.BackendSqlite), @@ -136,7 +136,7 @@ func realMain(ctx context.Context) error { trustDB, err := storage.NewTrustStorage(globalCfg.TrustDB) if err != nil { - return serrors.WrapStr("initializing trust database", err) + return serrors.Wrap("initializing trust database", err) } defer trustDB.Close() trustDB = truststoragemetrics.WrapDB(trustDB, truststoragemetrics.Config{ @@ -151,7 +151,7 @@ func realMain(ctx context.Context) error { }) engine, err := daemon.TrustEngine(globalCfg.General.ConfigDir, topo.IA(), trustDB, dialer) if err != nil { - return serrors.WrapStr("creating trust engine", err) + return serrors.Wrap("creating trust engine", err) } engine.Inspector = trust.CachingInspector{ Inspector: engine.Inspector, @@ -178,7 +178,7 @@ func realMain(ctx context.Context) error { if globalCfg.DRKeyLevel2DB.Connection != "" { backend, err := storage.NewDRKeyLevel2Storage(globalCfg.DRKeyLevel2DB) if err != nil { - return serrors.WrapStr("creating level2 DRKey DB", err) + return serrors.Wrap("creating level2 DRKey DB", err) } counter := metrics.NewPromCounter( promauto.NewCounterVec( @@ -222,12 +222,12 @@ func realMain(ctx context.Context) error { listen := daemon.APIAddress(globalCfg.SD.Address) listener, err := net.Listen("tcp", listen) if err != nil { - return serrors.WrapStr("listening", err) + return serrors.Wrap("listening", err) } hpGroups, err := hiddenpath.LoadHiddenPathGroups(globalCfg.SD.HiddenPathGroups) if err != nil { - return serrors.WrapStr("loading hidden path groups", err) + return serrors.Wrap("loading hidden path groups", err) } var requester segfetcher.RPC = &segfetchergrpc.Requester{ Dialer: dialer, @@ -287,7 +287,7 @@ func realMain(ctx context.Context) error { g.Go(func() error { defer log.HandlePanic() if err := server.Serve(listener); err != nil { - return serrors.WrapStr("serving gRPC API", err, "addr", listen) + return serrors.Wrap("serving gRPC API", err, "addr", listen) } return nil }) @@ -321,7 +321,7 @@ func realMain(ctx context.Context) error { defer log.HandlePanic() err := mgmtServer.ListenAndServe() if err != nil && !errors.Is(err, http.ErrServerClosed) { - return serrors.WrapStr("serving service management API", err) + return serrors.Wrap("serving service management API", err) } return nil }) @@ -336,7 +336,7 @@ func realMain(ctx context.Context) error { "topology": service.NewTopologyStatusPage(topo), } if err := statusPages.Register(http.DefaultServeMux, globalCfg.General.ID); err != nil { - return serrors.WrapStr("registering status pages", err) + return serrors.Wrap("registering status pages", err) } g.Go(func() error { diff --git a/daemon/daemon.go b/daemon/daemon.go index 30c92918bc..aa9476fca9 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -62,7 +62,7 @@ func TrustEngine( certsDir := filepath.Join(cfgDir, "certs") loaded, err := trust.LoadTRCs(context.Background(), certsDir, db) if err != nil { - return trust.Engine{}, serrors.WrapStr("loading TRCs", err) + return trust.Engine{}, serrors.Wrap("loading TRCs", err) } log.Info("TRCs loaded", "files", loaded.Loaded) for f, r := range loaded.Ignored { @@ -74,8 +74,9 @@ func TrustEngine( } loaded, err = trust.LoadChains(context.Background(), certsDir, db) if err != nil { - return trust.Engine{}, serrors.WrapStr("loading certificate chains", + return trust.Engine{}, serrors.Wrap("loading certificate chains", err) + } log.Info("Certificate chains loaded", "files", loaded.Loaded) for f, r := range loaded.Ignored { diff --git a/daemon/drkey/client_engine.go b/daemon/drkey/client_engine.go index 658e997dbd..4f781e5381 100644 --- a/daemon/drkey/client_engine.go +++ b/daemon/drkey/client_engine.go @@ -50,16 +50,16 @@ func (e *ClientEngine) GetASHostKey( return k, nil } if err != drkey.ErrKeyNotFound { - return drkey.ASHostKey{}, serrors.WrapStr("looking up AS-HOST key in DB", err) + return drkey.ASHostKey{}, serrors.Wrap("looking up AS-HOST key in DB", err) } // if not, ask our CS for it remoteKey, err := e.Fetcher.ASHostKey(ctx, meta) if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("fetching AS-Host key from local CS", err) + return drkey.ASHostKey{}, serrors.Wrap("fetching AS-Host key from local CS", err) } if err = e.DB.InsertASHostKey(ctx, remoteKey); err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("inserting AS-Host key in DB", err) + return drkey.ASHostKey{}, serrors.Wrap("inserting AS-Host key in DB", err) } return remoteKey, nil } @@ -76,16 +76,16 @@ func (e *ClientEngine) GetHostASKey( return k, nil } if err != drkey.ErrKeyNotFound { - return drkey.HostASKey{}, serrors.WrapStr("looking up Host-AS key in DB", err) + return drkey.HostASKey{}, serrors.Wrap("looking up Host-AS key in DB", err) } // if not, ask our CS for it remoteKey, err := e.Fetcher.HostASKey(ctx, meta) if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("fetching Host-AS key from local CS", err) + return drkey.HostASKey{}, serrors.Wrap("fetching Host-AS key from local CS", err) } if err = e.DB.InsertHostASKey(ctx, remoteKey); err != nil { - return drkey.HostASKey{}, serrors.WrapStr("inserting Host-AS key in DB", err) + return drkey.HostASKey{}, serrors.Wrap("inserting Host-AS key in DB", err) } return remoteKey, nil } @@ -103,16 +103,16 @@ func (e *ClientEngine) GetHostHostKey( return k, nil } if err != drkey.ErrKeyNotFound { - return drkey.HostHostKey{}, serrors.WrapStr("looking up Host-Host key in DB", err) + return drkey.HostHostKey{}, serrors.Wrap("looking up Host-Host key in DB", err) } // if not, ask our CS for it remoteKey, err := e.Fetcher.HostHostKey(ctx, meta) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("fetching Host-Host key from local CS", err) + return drkey.HostHostKey{}, serrors.Wrap("fetching Host-Host key from local CS", err) } if err = e.DB.InsertHostHostKey(ctx, remoteKey); err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("inserting Host-Host key in DB", err) + return drkey.HostHostKey{}, serrors.Wrap("inserting Host-Host key in DB", err) } return remoteKey, nil } diff --git a/daemon/drkey/grpc/fetcher.go b/daemon/drkey/grpc/fetcher.go index a6e51ffe75..49efb436ea 100644 --- a/daemon/drkey/grpc/fetcher.go +++ b/daemon/drkey/grpc/fetcher.go @@ -37,19 +37,19 @@ func (f *Fetcher) ASHostKey( conn, err := f.Dialer.Dial(ctx, &snet.SVCAddr{SVC: addr.SvcCS}) if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("dialing", err) + return drkey.ASHostKey{}, serrors.Wrap("dialing", err) } defer conn.Close() client := cppb.NewDRKeyIntraServiceClient(conn) protoReq := asHostMetaToProtoRequest(meta) rep, err := client.DRKeyASHost(ctx, protoReq) if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("requesting AS-HOST key", err) + return drkey.ASHostKey{}, serrors.Wrap("requesting AS-HOST key", err) } key, err := getASHostKeyFromReply(rep, meta) if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("obtaining AS-HOST key from reply", err) + return drkey.ASHostKey{}, serrors.Wrap("obtaining AS-HOST key from reply", err) } return key, nil @@ -62,19 +62,19 @@ func (f *Fetcher) HostASKey( conn, err := f.Dialer.Dial(ctx, &snet.SVCAddr{SVC: addr.SvcCS}) if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("dialing", err) + return drkey.HostASKey{}, serrors.Wrap("dialing", err) } defer conn.Close() client := cppb.NewDRKeyIntraServiceClient(conn) protoReq := hostASMetaToProtoRequest(meta) rep, err := client.DRKeyHostAS(ctx, protoReq) if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("requesting HOST-AS key", err) + return drkey.HostASKey{}, serrors.Wrap("requesting HOST-AS key", err) } key, err := getHostASKeyFromReply(rep, meta) if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("obtaining HOST-AS key from reply", err) + return drkey.HostASKey{}, serrors.Wrap("obtaining HOST-AS key from reply", err) } return key, nil @@ -87,19 +87,19 @@ func (f *Fetcher) HostHostKey( conn, err := f.Dialer.Dial(ctx, &snet.SVCAddr{SVC: addr.SvcCS}) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("dialing", err) + return drkey.HostHostKey{}, serrors.Wrap("dialing", err) } defer conn.Close() client := cppb.NewDRKeyIntraServiceClient(conn) protoReq := hostHostMetaToProtoRequest(meta) rep, err := client.DRKeyHostHost(ctx, protoReq) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("requesting Host-Host key", err) + return drkey.HostHostKey{}, serrors.Wrap("requesting Host-Host key", err) } key, err := getHostHostKeyFromReply(rep, meta) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("obtaining Host-Host key from reply", err) + return drkey.HostHostKey{}, serrors.Wrap("obtaining Host-Host key from reply", err) } return key, nil diff --git a/daemon/drkey/grpc/protobuf.go b/daemon/drkey/grpc/protobuf.go index bcc4b64136..cb32f7ba44 100644 --- a/daemon/drkey/grpc/protobuf.go +++ b/daemon/drkey/grpc/protobuf.go @@ -41,11 +41,11 @@ func getASHostKeyFromReply( err := rep.EpochBegin.CheckValid() if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("invalid EpochBegin from response", err) + return drkey.ASHostKey{}, serrors.Wrap("invalid EpochBegin from response", err) } err = rep.EpochEnd.CheckValid() if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("invalid EpochEnd from response", err) + return drkey.ASHostKey{}, serrors.Wrap("invalid EpochEnd from response", err) } epoch := drkey.Epoch{ Validity: cppki.Validity{ @@ -87,11 +87,11 @@ func getHostASKeyFromReply( err := rep.EpochBegin.CheckValid() if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("invalid EpochBegin from response", err) + return drkey.HostASKey{}, serrors.Wrap("invalid EpochBegin from response", err) } err = rep.EpochEnd.CheckValid() if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("invalid EpochEnd from response", err) + return drkey.HostASKey{}, serrors.Wrap("invalid EpochEnd from response", err) } epoch := drkey.Epoch{ Validity: cppki.Validity{ @@ -133,11 +133,11 @@ func getHostHostKeyFromReply( err := rep.EpochBegin.CheckValid() if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("invalid EpochBegin from response", err) + return drkey.HostHostKey{}, serrors.Wrap("invalid EpochBegin from response", err) } err = rep.EpochEnd.CheckValid() if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("invalid EpochEnd from response", err) + return drkey.HostHostKey{}, serrors.Wrap("invalid EpochEnd from response", err) } epoch := drkey.Epoch{ Validity: cppki.Validity{ diff --git a/daemon/internal/servers/grpc.go b/daemon/internal/servers/grpc.go index 16b64b9d15..58f8a59837 100644 --- a/daemon/internal/servers/grpc.go +++ b/daemon/internal/servers/grpc.go @@ -247,7 +247,7 @@ func (s *DaemonServer) as(ctx context.Context, req *sdpb.ASRequest) (*sdpb.ASRes core, err := s.ASInspector.HasAttributes(ctx, reqIA, trust.Core) if err != nil { log.FromCtx(ctx).Error("Inspecting ISD-AS", "err", err, "isd_as", reqIA) - return nil, serrors.WrapStr("inspecting ISD-AS", err, "isd_as", reqIA) + return nil, serrors.Wrap("inspecting ISD-AS", err, "isd_as", reqIA) } reply := &sdpb.ASResponse{ IsdAs: uint64(reqIA), @@ -346,7 +346,7 @@ func (s *DaemonServer) notifyInterfaceDown(ctx context.Context, if err != nil { log.FromCtx(ctx).Error("Inserting revocation", "err", err, "req", req) return nil, metricsError{ - err: serrors.WrapStr("inserting revocation", err), + err: serrors.Wrap("inserting revocation", err), result: prom.ErrDB, } } @@ -376,12 +376,12 @@ func (s *DaemonServer) DRKeyASHost( } meta, err := requestToASHostMeta(req) if err != nil { - return nil, serrors.WrapStr("parsing protobuf ASHostReq", err) + return nil, serrors.Wrap("parsing protobuf ASHostReq", err) } lvl2Key, err := s.DRKeyClient.GetASHostKey(ctx, meta) if err != nil { - return nil, serrors.WrapStr("getting AS-Host from client store", err) + return nil, serrors.Wrap("getting AS-Host from client store", err) } return &sdpb.DRKeyASHostResponse{ @@ -401,12 +401,12 @@ func (s *DaemonServer) DRKeyHostAS( } meta, err := requestToHostASMeta(req) if err != nil { - return nil, serrors.WrapStr("parsing protobuf HostASReq", err) + return nil, serrors.Wrap("parsing protobuf HostASReq", err) } lvl2Key, err := s.DRKeyClient.GetHostASKey(ctx, meta) if err != nil { - return nil, serrors.WrapStr("getting Host-AS from client store", err) + return nil, serrors.Wrap("getting Host-AS from client store", err) } return &sdpb.DRKeyHostASResponse{ @@ -426,11 +426,11 @@ func (s *DaemonServer) DRKeyHostHost( } meta, err := requestToHostHostMeta(req) if err != nil { - return nil, serrors.WrapStr("parsing protobuf HostHostReq", err) + return nil, serrors.Wrap("parsing protobuf HostHostReq", err) } lvl2Key, err := s.DRKeyClient.GetHostHostKey(ctx, meta) if err != nil { - return nil, serrors.WrapStr("getting Host-Host from client store", err) + return nil, serrors.Wrap("getting Host-Host from client store", err) } return &sdpb.DRKeyHostHostResponse{ @@ -443,7 +443,7 @@ func (s *DaemonServer) DRKeyHostHost( func requestToASHostMeta(req *sdpb.DRKeyASHostRequest) (drkey.ASHostMeta, error) { err := req.ValTime.CheckValid() if err != nil { - return drkey.ASHostMeta{}, serrors.WrapStr("invalid valTime from pb request", err) + return drkey.ASHostMeta{}, serrors.Wrap("invalid valTime from pb request", err) } return drkey.ASHostMeta{ ProtoId: drkey.Protocol(req.ProtocolId), @@ -457,7 +457,7 @@ func requestToASHostMeta(req *sdpb.DRKeyASHostRequest) (drkey.ASHostMeta, error) func requestToHostASMeta(req *sdpb.DRKeyHostASRequest) (drkey.HostASMeta, error) { err := req.ValTime.CheckValid() if err != nil { - return drkey.HostASMeta{}, serrors.WrapStr("invalid valTime from pb request", err) + return drkey.HostASMeta{}, serrors.Wrap("invalid valTime from pb request", err) } return drkey.HostASMeta{ ProtoId: drkey.Protocol(req.ProtocolId), @@ -471,7 +471,7 @@ func requestToHostASMeta(req *sdpb.DRKeyHostASRequest) (drkey.HostASMeta, error) func requestToHostHostMeta(req *sdpb.DRKeyHostHostRequest) (drkey.HostHostMeta, error) { err := req.ValTime.CheckValid() if err != nil { - return drkey.HostHostMeta{}, serrors.WrapStr("invalid valTime from pb request", err) + return drkey.HostHostMeta{}, serrors.Wrap("invalid valTime from pb request", err) } return drkey.HostHostMeta{ ProtoId: drkey.Protocol(req.ProtocolId), diff --git a/demo/drkey/main.go b/demo/drkey/main.go index 3337fabd74..d70d5755e8 100644 --- a/demo/drkey/main.go +++ b/demo/drkey/main.go @@ -206,15 +206,15 @@ func (s Server) DeriveHostHostKeySpecific( var deriver specific.Deriver lvl1, err := deriver.DeriveLevel1(meta.DstIA, sv.Key) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("deriving level 1 key", err) + return drkey.HostHostKey{}, serrors.Wrap("deriving level 1 key", err) } asHost, err := deriver.DeriveHostAS(meta.SrcHost, lvl1) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("deriving host-AS key", err) + return drkey.HostHostKey{}, serrors.Wrap("deriving host-AS key", err) } hosthost, err := deriver.DeriveHostHost(meta.DstHost, asHost) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("deriving host-host key", err) + return drkey.HostHostKey{}, serrors.Wrap("deriving host-host key", err) } return drkey.HostHostKey{ ProtoId: sv.ProtoId, @@ -237,7 +237,7 @@ func (s Server) DeriveHostHostKeyGeneric( } hosthost, err := deriver.DeriveHostHost(meta.DstHost, hostAS.Key) if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("deriving host-host key", err) + return drkey.HostHostKey{}, serrors.Wrap("deriving host-host key", err) } return drkey.HostHostKey{ ProtoId: hostAS.ProtoId, @@ -262,7 +262,7 @@ func (s Server) FetchSV( // Obtain CS address from scion daemon svcs, err := s.daemon.SVCInfo(ctx, nil) if err != nil { - return drkey.SecretValue{}, serrors.WrapStr("obtaining control service address", err) + return drkey.SecretValue{}, serrors.Wrap("obtaining control service address", err) } cs := svcs[addr.SvcCS] if len(cs) == 0 { @@ -272,7 +272,7 @@ func (s Server) FetchSV( // Contact CS directly for SV conn, err := grpc.DialContext(ctx, cs[0], grpc.WithInsecure()) if err != nil { - return drkey.SecretValue{}, serrors.WrapStr("dialing control service", err) + return drkey.SecretValue{}, serrors.Wrap("dialing control service", err) } defer conn.Close() client := cppb.NewDRKeyIntraServiceClient(conn) @@ -282,12 +282,12 @@ func (s Server) FetchSV( ProtocolId: dkpb.Protocol(meta.ProtoId), }) if err != nil { - return drkey.SecretValue{}, serrors.WrapStr("requesting drkey secret value", err) + return drkey.SecretValue{}, serrors.Wrap("requesting drkey secret value", err) } key, err := getSecretFromReply(meta.ProtoId, rep) if err != nil { - return drkey.SecretValue{}, serrors.WrapStr("validating drkey secret value reply", err) + return drkey.SecretValue{}, serrors.Wrap("validating drkey secret value reply", err) } return key, nil diff --git a/dispatcher/cmd/dispatcher/main.go b/dispatcher/cmd/dispatcher/main.go index 3eaed918e2..dd981fe9b5 100644 --- a/dispatcher/cmd/dispatcher/main.go +++ b/dispatcher/cmd/dispatcher/main.go @@ -96,7 +96,7 @@ func realMain(ctx context.Context) error { defer log.HandlePanic() err := mgmtServer.ListenAndServe() if err != nil && !errors.Is(err, http.ErrServerClosed) { - return serrors.WrapStr("serving service management API", err) + return serrors.Wrap("serving service management API", err) } return nil }) @@ -109,7 +109,7 @@ func realMain(ctx context.Context) error { "log/level": service.NewLogLevelStatusPage(), } if err := statusPages.Register(http.DefaultServeMux, globalCfg.Dispatcher.ID); err != nil { - return serrors.WrapStr("registering status pages", err) + return serrors.Wrap("registering status pages", err) } g.Go(func() error { @@ -149,7 +149,7 @@ func requiredIPs() ([]net.IP, error) { } promAddr, err := net.ResolveTCPAddr("tcp", globalCfg.Metrics.Prometheus) if err != nil { - return nil, serrors.WrapStr("parsing prometheus address", err) + return nil, serrors.Wrap("parsing prometheus address", err) } return []net.IP{promAddr.IP}, nil } diff --git a/dispatcher/dispatcher.go b/dispatcher/dispatcher.go index 2bb71e6d89..776b3192c8 100644 --- a/dispatcher/dispatcher.go +++ b/dispatcher/dispatcher.go @@ -299,17 +299,17 @@ func (s *Server) reverseSCION() error { s.scionLayer.DstIA, s.scionLayer.SrcIA = s.scionLayer.SrcIA, s.scionLayer.DstIA src, err := s.scionLayer.SrcAddr() if err != nil { - return serrors.WrapStr("parsing source address", err) + return serrors.Wrap("parsing source address", err) } dst, err := s.scionLayer.DstAddr() if err != nil { - return serrors.WrapStr("parsing destination address", err) + return serrors.Wrap("parsing destination address", err) } if err := s.scionLayer.SetSrcAddr(dst); err != nil { - return serrors.WrapStr("setting source address", err) + return serrors.Wrap("setting source address", err) } if err := s.scionLayer.SetDstAddr(src); err != nil { - return serrors.WrapStr("setting destination address", err) + return serrors.Wrap("setting destination address", err) } if s.scionLayer.PathType == epic.PathType { // Received packet with EPIC path type, hence extract the SCION path @@ -321,7 +321,7 @@ func (s *Server) reverseSCION() error { s.scionLayer.PathType = scion.PathType } if s.scionLayer.Path, err = s.scionLayer.Path.Reverse(); err != nil { - return serrors.WrapStr("reversing path", err) + return serrors.Wrap("reversing path", err) } return nil } diff --git a/gateway/cmd/gateway/main.go b/gateway/cmd/gateway/main.go index ca64ebc203..5195c516d2 100644 --- a/gateway/cmd/gateway/main.go +++ b/gateway/cmd/gateway/main.go @@ -56,22 +56,22 @@ func realMain(ctx context.Context) error { } daemon, err := daemonService.Connect(ctx) if err != nil { - return serrors.WrapStr("connecting to daemon", err) + return serrors.Wrap("connecting to daemon", err) } defer daemon.Close() localIA, err := daemon.LocalIA(ctx) if err != nil { - return serrors.WrapStr("retrieving local ISD-AS", err) + return serrors.Wrap("retrieving local ISD-AS", err) } controlAddress, err := net.ResolveUDPAddr("udp", globalCfg.Gateway.CtrlAddr) if err != nil { - return serrors.WrapStr("parsing control address", err) + return serrors.Wrap("parsing control address", err) } if len(controlAddress.IP) == 0 { controlAddress.IP, err = addrutil.DefaultLocalIP(ctx, daemon) if err != nil { - return serrors.WrapStr("determine default local IP", err) + return serrors.Wrap("determine default local IP", err) } } controlAddressIP, ok := netip.AddrFromSlice(controlAddress.IP) @@ -80,7 +80,7 @@ func realMain(ctx context.Context) error { } dataAddress, err := net.ResolveUDPAddr("udp", globalCfg.Gateway.DataAddr) if err != nil { - return serrors.WrapStr("parsing data address", err) + return serrors.Wrap("parsing data address", err) } if len(dataAddress.IP) == 0 { dataAddress.IP = controlAddress.IP @@ -88,7 +88,7 @@ func realMain(ctx context.Context) error { } probeAddress, err := net.ResolveUDPAddr("udp", globalCfg.Gateway.ProbeAddr) if err != nil { - return serrors.WrapStr("parsing probe address", err) + return serrors.Wrap("parsing probe address", err) } if len(probeAddress.IP) == 0 { probeAddress.IP = controlAddress.IP @@ -119,7 +119,7 @@ func realMain(ctx context.Context) error { defer log.HandlePanic() err := mgmtServer.ListenAndServe() if err != nil && !errors.Is(err, http.ErrServerClosed) { - return serrors.WrapStr("serving service management API", err) + return serrors.Wrap("serving service management API", err) } return nil }) diff --git a/gateway/control/engine.go b/gateway/control/engine.go index 0c69af8805..b10c9e2b71 100644 --- a/gateway/control/engine.go +++ b/gateway/control/engine.go @@ -342,7 +342,7 @@ func (e *Engine) initWorkers(ctx context.Context) error { deviceHandle, err := e.DeviceManager.Get(ctx, remoteIA) if err != nil { - return serrors.WrapStr("getting tun device handle", err) + return serrors.Wrap("getting tun device handle", err) } e.deviceHandles = append(e.deviceHandles, deviceHandle) diff --git a/gateway/control/enginecontroller.go b/gateway/control/enginecontroller.go index 5233667dfa..98716eb4e2 100644 --- a/gateway/control/enginecontroller.go +++ b/gateway/control/enginecontroller.go @@ -161,7 +161,7 @@ func (c *EngineController) run(ctx context.Context) error { // session configurations. rt, err := c.RoutingTableFactory.New(rcs) if err != nil { - return serrors.WrapStr("creating routing table", err) + return serrors.Wrap("creating routing table", err) } routingTable := NewPublishingRoutingTable(rcs, rt, c.RoutePublisherFactory.NewPublisher(), net.IP{}, c.RouteSourceIPv4, c.RouteSourceIPv6) @@ -171,7 +171,7 @@ func (c *EngineController) run(ctx context.Context) error { logger.Info("Starting new forwarding engine.", "routing_chain_mapping", routingChainMappingForLog(rcMapping)) if err := newEngine.Run(ctx); err != nil { - return serrors.WrapStr("setting up the engine", err) + return serrors.Wrap("setting up the engine", err) } time.Sleep(c.SwapDelay) @@ -180,14 +180,14 @@ func (c *EngineController) run(ctx context.Context) error { old := c.RoutingTableSwapper.SetRoutingTable(routingTable) if old != nil { if err := old.Close(); err != nil { - return serrors.WrapStr("closing old routing table", err) + return serrors.Wrap("closing old routing table", err) } } if c.engine != nil { logger.Debug("Shutting down old forwarding engine.") if err := c.engine.Close(ctx); err != nil { - return serrors.WrapStr("shutting down engine", err) + return serrors.Wrap("shutting down engine", err) } logger.Debug("Shut down old forwarding engine") } diff --git a/gateway/control/grpc/discoverer.go b/gateway/control/grpc/discoverer.go index c972fb5a64..f7ba9e515b 100644 --- a/gateway/control/grpc/discoverer.go +++ b/gateway/control/grpc/discoverer.go @@ -52,21 +52,21 @@ func (d Discoverer) Gateways(ctx context.Context) ([]control.Gateway, error) { client := dpb.NewDiscoveryServiceClient(conn) rep, err := client.Gateways(ctx, &dpb.GatewaysRequest{}, grpc.RetryProfile...) if err != nil { - return nil, serrors.WrapStr("receiving gateways", err) + return nil, serrors.Wrap("receiving gateways", err) } gateways := make([]control.Gateway, 0, len(rep.Gateways)) for _, pb := range rep.Gateways { ctrl, err := net.ResolveUDPAddr("udp", pb.ControlAddress) if err != nil { - return nil, serrors.WrapStr("parsing control address", err) + return nil, serrors.Wrap("parsing control address", err) } data, err := net.ResolveUDPAddr("udp", pb.DataAddress) if err != nil { - return nil, serrors.WrapStr("parsing data address", err) + return nil, serrors.Wrap("parsing data address", err) } probe, err := net.ResolveUDPAddr("udp", pb.ProbeAddress) if err != nil { - return nil, serrors.WrapStr("parsing probe address", err) + return nil, serrors.Wrap("parsing probe address", err) } gateways = append(gateways, control.Gateway{ Control: ctrl, diff --git a/gateway/control/grpc/prefix_fetcher.go b/gateway/control/grpc/prefix_fetcher.go index 14695b969a..cf2bff35cb 100644 --- a/gateway/control/grpc/prefix_fetcher.go +++ b/gateway/control/grpc/prefix_fetcher.go @@ -51,7 +51,7 @@ func (f PrefixFetcher) Prefixes(ctx context.Context, gateway *net.UDPAddr) ([]*n client := gpb.NewIPPrefixesServiceClient(conn) rep, err := client.Prefixes(ctx, &gpb.PrefixesRequest{}, grpc.RetryProfile...) if err != nil { - return nil, serrors.WrapStr("receiving IP prefixes", err) + return nil, serrors.Wrap("receiving IP prefixes", err) } prefixes := make([]*net.IPNet, 0, len(rep.Prefixes)) for _, pb := range rep.Prefixes { diff --git a/gateway/control/grpc/probeserver.go b/gateway/control/grpc/probeserver.go index 8d58dc6a6f..8f17a7facd 100644 --- a/gateway/control/grpc/probeserver.go +++ b/gateway/control/grpc/probeserver.go @@ -75,7 +75,7 @@ func (d *ProbeDispatcher) dispatch(conn net.PacketConn, raw []byte, addr net.Add } packed, err := proto.Marshal(reply) if err != nil { - return serrors.WrapStr("packing probe response", err, "session_id", c.Probe.SessionId) + return serrors.Wrap("packing probe response", err, "session_id", c.Probe.SessionId) } _, err = conn.WriteTo(packed, addr) return err diff --git a/gateway/control/router.go b/gateway/control/router.go index fb3fe84903..aa18a084ca 100644 --- a/gateway/control/router.go +++ b/gateway/control/router.go @@ -181,7 +181,7 @@ func (r *Router) handleEvent(ctx context.Context, event SessionEvent) error { if err != nil { // if the routing table doesn't know the index it means // something was wrongly programmed. - panic(serrors.WrapStr("adding to routing table", err, "id", rtID)) + panic(serrors.Wrap("adding to routing table", err, "id", rtID)) } r.currentSessions[rtID] = event.SessionID continue @@ -199,7 +199,7 @@ func (r *Router) handleEvent(ctx context.Context, event SessionEvent) error { if err != nil { // if the routing table doesn't know the index it means // something was wrongly programmed. - panic(serrors.WrapStr("adding to routing table", err, "id", rtID)) + panic(serrors.Wrap("adding to routing table", err, "id", rtID)) } r.currentSessions[rtID] = bestID } @@ -218,7 +218,7 @@ func (r *Router) handleEvent(ctx context.Context, event SessionEvent) error { if err := r.RoutingTable.ClearSession(rtID); err != nil { // if the routing table doesn't know the index it means // something was wrongly programmed. - panic(serrors.WrapStr("deleting from routing table", err, "id", rtID)) + panic(serrors.Wrap("deleting from routing table", err, "id", rtID)) } delete(r.currentSessions, rtID) } else { @@ -227,7 +227,7 @@ func (r *Router) handleEvent(ctx context.Context, event SessionEvent) error { if err := r.RoutingTable.SetSession(rtID, r.DataplaneSessions[newID]); err != nil { // if the routing table doesn't know the index it means // something was wrongly programmed. - panic(serrors.WrapStr("adding to routing table", err, "id", rtID)) + panic(serrors.Wrap("adding to routing table", err, "id", rtID)) } r.currentSessions[rtID] = newID } diff --git a/gateway/control/sessionmonitor.go b/gateway/control/sessionmonitor.go index a0fd7ad953..f3e2d16ee6 100644 --- a/gateway/control/sessionmonitor.go +++ b/gateway/control/sessionmonitor.go @@ -190,7 +190,7 @@ func (m *SessionMonitor) setupInternalState(ctx context.Context) error { } raw, err := proto.Marshal(probe) if err != nil { - return serrors.WrapStr("marshaling probe", err) + return serrors.Wrap("marshaling probe", err) } m.rawProbe = raw m.receivedProbe = make(chan struct{}) @@ -298,7 +298,7 @@ func (m *SessionMonitor) drainConn(ctx context.Context) { func (m *SessionMonitor) handlePkt(raw []byte) error { var ctrl gatewaypb.ControlResponse if err := proto.Unmarshal(raw, &ctrl); err != nil { - return serrors.WrapStr("parsing control response", err) + return serrors.Wrap("parsing control response", err) } probe, ok := ctrl.Response.(*gatewaypb.ControlResponse_Probe) if !ok { diff --git a/gateway/control/sessionpolicy.go b/gateway/control/sessionpolicy.go index 925312e487..cf660e7a57 100644 --- a/gateway/control/sessionpolicy.go +++ b/gateway/control/sessionpolicy.go @@ -53,7 +53,7 @@ func (LegacySessionPolicyAdapter) Parse(ctx context.Context, raw []byte) (Sessio } cfg := &JSONFormat{} if err := json.Unmarshal(raw, cfg); err != nil { - return nil, serrors.WrapStr("parsing JSON", err) + return nil, serrors.Wrap("parsing JSON", err) } policies := make(SessionPolicies, 0, len(cfg.ASes)) for ia, asEntry := range cfg.ASes { @@ -83,7 +83,7 @@ func parsePrefixes(rawNets []string) ([]*net.IPNet, error) { for _, s := range rawNets { ip, ipnet, err := net.ParseCIDR(s) if err != nil { - return nil, serrors.WrapStr("parsing CIDR", err) + return nil, serrors.Wrap("parsing CIDR", err) } if !ip.Equal(ipnet.IP) { return nil, serrors.New("network must be canonical", "raw", s) @@ -108,11 +108,11 @@ func LoadSessionPolicies(ctx context.Context, file string, raw, err := os.ReadFile(file) if err != nil { - return nil, serrors.WrapStr("reading file", err) + return nil, serrors.Wrap("reading file", err) } p, err := parser.Parse(ctx, raw) if err != nil { - return nil, serrors.WithCtx(err, "file", file) + return nil, serrors.Wrap("parsing", err, "file", file) } return p, nil } diff --git a/gateway/control/watcher.go b/gateway/control/watcher.go index aaf2abac3d..3586fd229b 100644 --- a/gateway/control/watcher.go +++ b/gateway/control/watcher.go @@ -295,7 +295,7 @@ func (w *GatewayWatcher) validateParameters() error { w.DiscoverTimeout = defaultGatewayDiscoveryTimeout } if err := w.Template.validateParameters(); err != nil { - return serrors.WrapStr("validating PrefixWatcher template", err) + return serrors.Wrap("validating PrefixWatcher template", err) } return nil } diff --git a/gateway/dataplane/ipforwarder.go b/gateway/dataplane/ipforwarder.go index dc6149ca31..f1f92fd518 100644 --- a/gateway/dataplane/ipforwarder.go +++ b/gateway/dataplane/ipforwarder.go @@ -83,7 +83,7 @@ func (f *IPForwarder) Run(ctx context.Context) error { length, err := f.Reader.Read(buf) if err != nil { metrics.CounterInc(f.Metrics.ReceiveLocalErrors) - return serrors.WrapStr("read device error", err) + return serrors.Wrap("read device error", err) } metrics.CounterInc(f.Metrics.IPPktsLocalRecv) metrics.CounterAdd(f.Metrics.IPPktBytesLocalRecv, float64(length)) diff --git a/gateway/gateway.go b/gateway/gateway.go index 5ad5b84530..c6395be076 100644 --- a/gateway/gateway.go +++ b/gateway/gateway.go @@ -101,7 +101,7 @@ func (pcf PacketConnFactory) New() (net.PacketConn, error) { defer cancel() conn, err := pcf.Network.Listen(ctx, "udp", pcf.Addr) if err != nil { - return nil, serrors.WrapStr("creating packet conn", err) + return nil, serrors.Wrap("creating packet conn", err) } return conn, nil } @@ -242,7 +242,7 @@ func (g *Gateway) Run(ctx context.Context) error { // ********************************************* localIA, err := g.Daemon.LocalIA(context.Background()) if err != nil { - return serrors.WrapStr("unable to learn local ISD-AS number", err) + return serrors.Wrap("unable to learn local ISD-AS number", err) } logger.Info("Learned local IA from SCION Daemon", "ia", localIA) @@ -403,7 +403,7 @@ func (g *Gateway) Run(ctx context.Context) error { // Generate throwaway self-signed TLS certificates. These DO NOT PROVIDE ANY SECURITY. ephemeralTLSConfig, err := infraenv.GenerateTLSConfig() if err != nil { - return serrors.WrapStr("unable to generate TLS config", err) + return serrors.Wrap("unable to generate TLS config", err) } // scionNetworkNoSCMP is the network for the QUIC server connection. Because SCMP errors @@ -431,7 +431,7 @@ func (g *Gateway) Run(ctx context.Context) error { &net.UDPAddr{IP: g.ControlClientIP}, ) if err != nil { - return serrors.WrapStr("unable to initialize client QUIC connection", err) + return serrors.Wrap("unable to initialize client QUIC connection", err) } logger.Info("QUIC client connection initialized", "local_addr", clientConn.LocalAddr()) @@ -524,14 +524,14 @@ func (g *Gateway) Run(ctx context.Context) error { g.ControlServerAddr, ) if err != nil { - return serrors.WrapStr("unable to initialize server QUIC connection", err) + return serrors.Wrap("unable to initialize server QUIC connection", err) } logger.Info("QUIC server connection initialized", "local_addr", serverConn.LocalAddr()) internalQUICServerListener, err := quic.Listen(serverConn, ephemeralTLSConfig, nil) if err != nil { - return serrors.WrapStr("unable to initializer server QUIC listener", err) + return serrors.Wrap("unable to initializer server QUIC listener", err) } // Wrap in net.Listener for use with gRPC quicServerListener := squic.NewConnListener(internalQUICServerListener) @@ -571,7 +571,7 @@ func (g *Gateway) Run(ctx context.Context) error { probeConn, err := scionNetwork.Listen(context.TODO(), "udp", g.ProbeServerAddr) if err != nil { - return serrors.WrapStr("creating server probe conn", err) + return serrors.Wrap("creating server probe conn", err) } probeServer := controlgrpc.ProbeDispatcher{} probeServerCtx, probeServerCancel := context.WithCancel(context.Background()) @@ -684,7 +684,7 @@ func (g *Gateway) Run(ctx context.Context) error { } if err := g.HTTPEndpoints.Register(g.HTTPServeMux, g.ID); err != nil { - return serrors.WrapStr("registering HTTP pages", err) + return serrors.Wrap("registering HTTP pages", err) } <-ctx.Done() return nil @@ -769,7 +769,7 @@ func StartIngress(ctx context.Context, scionNetwork *snet.SCIONNetwork, dataAddr dataAddr, ) if err != nil { - return serrors.WrapStr("creating ingress conn", err) + return serrors.Wrap("creating ingress conn", err) } ingressMetrics := CreateIngressMetrics(metrics) ingressServer := &dataplane.IngressServer{ @@ -871,7 +871,7 @@ func (r *TunnelReader) GetDeviceOpenerWithAsyncReader(ctx context.Context) contr logger := log.FromCtx(ctx) handle, err := r.DeviceOpener.Open(ctx, ia) if err != nil { - return nil, serrors.WrapStr("opening device", err) + return nil, serrors.Wrap("opening device", err) } forwarder := &dataplane.IPForwarder{ diff --git a/gateway/loader.go b/gateway/loader.go index 411ea8f330..bf6be43392 100644 --- a/gateway/loader.go +++ b/gateway/loader.go @@ -98,11 +98,11 @@ func (l *Loader) loadFiles(ctx context.Context) (control.SessionPolicies, *routi var errors serrors.List sp, err := control.LoadSessionPolicies(ctx, l.SessionPoliciesFile, l.SessionPolicyParser) if err != nil { - errors = append(errors, serrors.WrapStr("loading session policies", err)) + errors = append(errors, serrors.Wrap("loading session policies", err)) } rp, err := l.loadRoutingPolicy() if err != nil { - errors = append(errors, serrors.WrapStr("loading routing policiy", err)) + errors = append(errors, serrors.Wrap("loading routing policiy", err)) } return sp, rp, errors.ToError() } diff --git a/gateway/pathhealth/pathwatcher.go b/gateway/pathhealth/pathwatcher.go index a61ae80ca4..ee53d29e53 100644 --- a/gateway/pathhealth/pathwatcher.go +++ b/gateway/pathhealth/pathwatcher.go @@ -94,7 +94,7 @@ func (f *DefaultPathWatcherFactory) New( Topology: f.Topology, }).OpenRaw(ctx, &net.UDPAddr{IP: f.LocalIP.AsSlice()}) if err != nil { - return nil, serrors.WrapStr("creating connection for probing", err) + return nil, serrors.Wrap("creating connection for probing", err) } return &pathWatcher{ remote: remote, @@ -348,7 +348,7 @@ func createPathWrap(path snet.Path) pathWrap { var decoded scion.Decoded if err := decoded.DecodeFromBytes(original.Raw); err != nil { - p.err = serrors.WrapStr("decoding path", err) + p.err = serrors.Wrap("decoding path", err) return p } if len(decoded.InfoFields) > 0 { @@ -362,7 +362,7 @@ func createPathWrap(path snet.Path) pathWrap { alert, err := snetpath.NewSCIONFromDecoded(decoded) if err != nil { - p.err = serrors.WrapStr("serializing path", err) + p.err = serrors.Wrap("serializing path", err) return p } p.dpPath = alert diff --git a/gateway/pktcls/json.go b/gateway/pktcls/json.go index e69d78a4ac..15380061e9 100644 --- a/gateway/pktcls/json.go +++ b/gateway/pktcls/json.go @@ -234,8 +234,9 @@ func unmarshalUintField(b []byte, name, field string, width int) (uint64, error) } i, err := strconv.ParseUint(s, 0, width) if err != nil { - return 0, serrors.WrapStr("Unable to parse uint field", err, + return 0, serrors.Wrap("Unable to parse uint field", err, "name", name, "field", field) + } return i, nil } diff --git a/gateway/pktcls/parse.go b/gateway/pktcls/parse.go index 990479aa25..d617cadc8a 100644 --- a/gateway/pktcls/parse.go +++ b/gateway/pktcls/parse.go @@ -75,7 +75,7 @@ func (l *classListener) EnterMatchDst(ctx *traffic_class.MatchDstContext) { mdst := &IPv4MatchDestination{} _, mdst.Net, err = net.ParseCIDR(ctx.GetStop().GetText()) if err != nil { - l.err = serrors.WrapStr("CIDR parsing failed!", err, "cidr", ctx.GetStop().GetText()) + l.err = serrors.Wrap("CIDR parsing failed!", err, "cidr", ctx.GetStop().GetText()) } l.pushCond(NewCondIPv4(mdst)) } @@ -86,7 +86,7 @@ func (l *classListener) EnterMatchSrc(ctx *traffic_class.MatchSrcContext) { msrc := &IPv4MatchSource{} _, msrc.Net, err = net.ParseCIDR(ctx.GetStop().GetText()) if err != nil { - l.err = serrors.WrapStr("CIDR parsing failed!", err, "cidr", ctx.GetStop().GetText()) + l.err = serrors.Wrap("CIDR parsing failed!", err, "cidr", ctx.GetStop().GetText()) } l.pushCond(NewCondIPv4(msrc)) } @@ -96,7 +96,7 @@ func (l *classListener) EnterMatchDSCP(ctx *traffic_class.MatchDSCPContext) { mdscp := &IPv4MatchDSCP{} dscp, err := strconv.ParseUint(ctx.GetStop().GetText(), 16, 8) if err != nil { - l.err = serrors.WrapStr("DSCP parsing failed!", err, "dscp", ctx.GetStop().GetText()) + l.err = serrors.Wrap("DSCP parsing failed!", err, "dscp", ctx.GetStop().GetText()) } mdscp.DSCP = uint8(dscp) l.pushCond(NewCondIPv4(mdscp)) @@ -107,7 +107,7 @@ func (l *classListener) EnterMatchTOS(ctx *traffic_class.MatchTOSContext) { mtos := &IPv4MatchToS{} tos, err := strconv.ParseUint(ctx.GetStop().GetText(), 16, 8) if err != nil { - l.err = serrors.WrapStr("TOS parsing failed!", err, "tos", ctx.GetStop().GetText()) + l.err = serrors.Wrap("TOS parsing failed!", err, "tos", ctx.GetStop().GetText()) } mtos.TOS = uint8(tos) l.pushCond(NewCondIPv4(mtos)) @@ -118,8 +118,9 @@ func (l *classListener) EnterMatchProtocol(ctx *traffic_class.MatchProtocolConte prot := &IPv4MatchProtocol{} number, err := protocolNameToNumber(ctx.GetStop().GetText()) if err != nil { - l.err = serrors.WrapStr("Protocol parsing failed!", err, + l.err = serrors.Wrap("Protocol parsing failed!", err, "protocol", ctx.GetStop().GetText()) + } prot.Protocol = number l.pushCond(NewCondIPv4(prot)) @@ -130,8 +131,9 @@ func (l *classListener) EnterMatchSrcPort(ctx *traffic_class.MatchSrcPortContext src := &PortMatchSource{} msrc, err := strconv.ParseUint(ctx.GetStop().GetText(), 10, 16) if err != nil { - l.err = serrors.WrapStr("SRCPORT parsing failed!", err, + l.err = serrors.Wrap("SRCPORT parsing failed!", err, "srcport", ctx.GetStop().GetText()) + } src.MinPort = uint16(msrc) src.MaxPort = uint16(msrc) @@ -145,11 +147,11 @@ func (l *classListener) EnterMatchSrcPortRange(ctx *traffic_class.MatchSrcPortRa max := ctx.GetToken(traffic_class.TrafficClassLexerDIGITS, 1).GetText() msrcMin, err := strconv.ParseUint(min, 10, 16) if err != nil { - l.err = serrors.WrapStr("SRCPORT parsing failed!", err, "srcport", min) + l.err = serrors.Wrap("SRCPORT parsing failed!", err, "srcport", min) } msrcMax, err := strconv.ParseUint(max, 10, 16) if err != nil { - l.err = serrors.WrapStr("SRCPORT parsing failed!", err, "srcport", max) + l.err = serrors.Wrap("SRCPORT parsing failed!", err, "srcport", max) } src.MinPort = uint16(msrcMin) src.MaxPort = uint16(msrcMax) @@ -161,8 +163,9 @@ func (l *classListener) EnterMatchDstPort(ctx *traffic_class.MatchDstPortContext dst := &PortMatchDestination{} mdst, err := strconv.ParseUint(ctx.GetStop().GetText(), 10, 16) if err != nil { - l.err = serrors.WrapStr("DSTPORT parsing failed!", err, + l.err = serrors.Wrap("DSTPORT parsing failed!", err, "dstport", ctx.GetStop().GetText()) + } dst.MinPort = uint16(mdst) dst.MaxPort = uint16(mdst) @@ -176,11 +179,11 @@ func (l *classListener) EnterMatchDstPortRange(ctx *traffic_class.MatchDstPortRa max := ctx.GetToken(traffic_class.TrafficClassLexerDIGITS, 1).GetText() mdstMin, err := strconv.ParseUint(min, 10, 16) if err != nil { - l.err = serrors.WrapStr("SRCPORT parsing failed!", err, "dstport", min) + l.err = serrors.Wrap("SRCPORT parsing failed!", err, "dstport", min) } mdstMax, err := strconv.ParseUint(max, 10, 16) if err != nil { - l.err = serrors.WrapStr("SRCPORT parsing failed!", err, "dstport", max) + l.err = serrors.Wrap("SRCPORT parsing failed!", err, "dstport", max) } dst.MinPort = uint16(mdstMin) dst.MaxPort = uint16(mdstMax) @@ -223,8 +226,9 @@ func (l *classListener) ExitCondNot(ctx *traffic_class.CondNotContext) { func (l *classListener) EnterCondBool(ctx *traffic_class.CondBoolContext) { bool, err := strconv.ParseBool(ctx.GetStop().GetText()) if err != nil { - l.err = serrors.WrapStr("CondBool parsing failed!", err, + l.err = serrors.Wrap("CondBool parsing failed!", err, "bool", ctx.GetStop().GetText()) + } l.pushCond(CondBool(bool)) } diff --git a/gateway/pktcls/pred_ipv4.go b/gateway/pktcls/pred_ipv4.go index 3a951116f3..24e145f013 100644 --- a/gateway/pktcls/pred_ipv4.go +++ b/gateway/pktcls/pred_ipv4.go @@ -71,7 +71,7 @@ func (m *IPv4MatchSource) UnmarshalJSON(b []byte) error { } _, network, err := net.ParseCIDR(s) if err != nil { - return serrors.WrapStr("Unable to parse MatchSource operand", err) + return serrors.Wrap("Unable to parse MatchSource operand", err) } m.Net = network return nil @@ -115,7 +115,7 @@ func (m *IPv4MatchDestination) UnmarshalJSON(b []byte) error { } _, network, err := net.ParseCIDR(s) if err != nil { - return serrors.WrapStr("Unable to parse MatchDestination operand", err) + return serrors.Wrap("Unable to parse MatchDestination operand", err) } m.Net = network return nil diff --git a/gateway/routemgr/device.go b/gateway/routemgr/device.go index 18602c1f70..6b993db0e7 100644 --- a/gateway/routemgr/device.go +++ b/gateway/routemgr/device.go @@ -128,7 +128,7 @@ func (h *deviceHandle) ioWrapper(f func([]byte) (int, error), b []byte) (int, er if err != nil && h.destroyed() { // always give the correct number of bytes to the caller (e.g., so it can know up to // where it read/wrote on a device which supports streaming). - return n, serrors.Wrap(control.ObjectDestroyedError, err) + return n, serrors.JoinNoStack(control.ObjectDestroyedError, err) } return n, err } @@ -151,7 +151,7 @@ func (h *deviceHandle) routeWrapper(ctx context.Context, } err := f(ctx, r) if err != nil && h.destroyed() { - return serrors.Wrap(control.ObjectDestroyedError, err) + return serrors.JoinNoStack(control.ObjectDestroyedError, err) } return err } diff --git a/gateway/routemgr/linux.go b/gateway/routemgr/linux.go index 50745b3871..950d52422d 100644 --- a/gateway/routemgr/linux.go +++ b/gateway/routemgr/linux.go @@ -80,7 +80,7 @@ func (l *Linux) publishToLinux(ctx context.Context, update control.RouteUpdate) logger := log.FromCtx(ctx) handle, err := l.DeviceManager.Get(ctx, update.IA) if err != nil { - return serrors.WrapStr("retrieving device for ISD-AS", err, "isd_as", update.IA) + return serrors.Wrap("retrieving device for ISD-AS", err, "isd_as", update.IA) } defer func() { if err := handle.Close(); err != nil { diff --git a/gateway/routing/file.go b/gateway/routing/file.go index 80a2b74e5b..cf05b7ae9b 100644 --- a/gateway/routing/file.go +++ b/gateway/routing/file.go @@ -30,10 +30,10 @@ func LoadPolicy(path string) (Policy, error) { p := Policy{} raw, err := os.ReadFile(path) if err != nil { - return Policy{}, serrors.WrapStr("reading file", err) + return Policy{}, serrors.Wrap("reading file", err) } if err := p.UnmarshalText(raw); err != nil { - return Policy{}, serrors.WrapStr("parsing file", err, "file", path) + return Policy{}, serrors.Wrap("parsing file", err, "file", path) } return p, nil } diff --git a/gateway/routing/marshal.go b/gateway/routing/marshal.go index 5b59ec3a88..c9d34359ed 100644 --- a/gateway/routing/marshal.go +++ b/gateway/routing/marshal.go @@ -58,7 +58,7 @@ func (p *Policy) UnmarshalText(b []byte) error { for scanner.Scan() { rule, err := parseRule(scanner.Bytes()) if err != nil { - return serrors.WrapStr("parsing rule", err, "line", len(rules)) + return serrors.Wrap("parsing rule", err, "line", len(rules)) } rules = append(rules, rule) } @@ -83,19 +83,19 @@ func parseRule(b []byte) (Rule, error) { action, err := parseAction(columns[0]) if err != nil { - return Rule{}, serrors.WrapStr("parsing 'action'", err, "input", string(columns[0])) + return Rule{}, serrors.Wrap("parsing 'action'", err, "input", string(columns[0])) } fromMatcher, err := parseIAMatcher(columns[1]) if err != nil { - return Rule{}, serrors.WrapStr("parsing 'to'", err, "input", string(columns[1])) + return Rule{}, serrors.Wrap("parsing 'to'", err, "input", string(columns[1])) } toMatcher, err := parseIAMatcher(columns[2]) if err != nil { - return Rule{}, serrors.WrapStr("parsing 'from'", err, "input", string(columns[2])) + return Rule{}, serrors.Wrap("parsing 'from'", err, "input", string(columns[2])) } networkMatcher, err := parseNetworkMatcher(columns[3]) if err != nil { - return Rule{}, serrors.WrapStr("parsing 'network'", err, "input", string(columns[3])) + return Rule{}, serrors.Wrap("parsing 'network'", err, "input", string(columns[3])) } maxColumns := 4 @@ -150,7 +150,7 @@ func parseNetworkMatcher(b []byte) (NetworkMatcher, error) { for _, network := range bytes.Split(b, []byte(",")) { n, err := netip.ParsePrefix(string(network)) if err != nil { - return NetworkMatcher{}, serrors.WrapStr("parsing network", err) + return NetworkMatcher{}, serrors.Wrap("parsing network", err) } networks = append(networks, n) } diff --git a/gateway/xnet/xnet.go b/gateway/xnet/xnet.go index 7c9f64639a..b65fcac018 100644 --- a/gateway/xnet/xnet.go +++ b/gateway/xnet/xnet.go @@ -52,17 +52,18 @@ func connectTun(name string) (netlink.Link, io.ReadWriteCloser, error) { if err != nil { tun.Close() // Should clean up the tun device, but if we can't find it... - return nil, nil, serrors.WrapStr("unable to find new TUN device", err, "name", name) + return nil, nil, serrors.Wrap("unable to find new TUN device", err, "name", name) } err = netlink.LinkSetUp(link) if err != nil { - err = serrors.WrapStr("unable to set new TUN device Up", err, "name", name) + err = serrors.Wrap("unable to set new TUN device Up", err, "name", name) goto Cleanup } err = netlink.LinkSetTxQLen(link, SIGTxQlen) if err != nil { - err = serrors.WrapStr("unable to set Tx queue length on new TUN device", err, + err = serrors.Wrap("unable to set Tx queue length on new TUN device", err, "name", name) + goto Cleanup } return link, tun, nil @@ -182,8 +183,9 @@ func addRoute(rTable int, link netlink.Link, dest *net.IPNet, src net.IP) error route.Src = src } if err := netlink.RouteAdd(route); err != nil { - return serrors.WrapStr("EgressReader: Unable to add SIG route", err, + return serrors.Wrap("EgressReader: Unable to add SIG route", err, "route", route) + } return nil } @@ -199,8 +201,9 @@ func deleteRoute(rTable int, link netlink.Link, dest *net.IPNet, src net.IP) err route.Src = src } if err := netlink.RouteDel(route); err != nil { - return serrors.WrapStr("EgressReader: Unable to delete SIG route", err, + return serrors.Wrap("EgressReader: Unable to delete SIG route", err, "route", route) + } return nil } diff --git a/pkg/addr/addr.go b/pkg/addr/addr.go index 4467f54a42..55bc2170c9 100644 --- a/pkg/addr/addr.go +++ b/pkg/addr/addr.go @@ -93,15 +93,15 @@ func (a *Addr) UnmarshalText(b []byte) error { 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) + return Addr{}, 0, serrors.Wrap("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) + return Addr{}, 0, serrors.Wrap("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 Addr{}, 0, serrors.Wrap("invalid address: port invalid", err, "port", port) } return a, uint16(p), nil } diff --git a/pkg/addr/fmt.go b/pkg/addr/fmt.go index ed9b2d9de1..e305877efd 100644 --- a/pkg/addr/fmt.go +++ b/pkg/addr/fmt.go @@ -31,11 +31,11 @@ func ParseFormattedIA(ia string, opts ...FormatOption) (IA, error) { } isd, err := ParseFormattedISD(parts[0], opts...) if err != nil { - return 0, serrors.WrapStr("parsing ISD part", err, "value", ia) + return 0, serrors.Wrap("parsing ISD part", err, "value", ia) } as, err := ParseFormattedAS(parts[1], opts...) if err != nil { - return 0, serrors.WrapStr("parsing AS part", err, "value", ia) + return 0, serrors.Wrap("parsing AS part", err, "value", ia) } return MustIAFrom(isd, as), nil } diff --git a/pkg/addr/isdas.go b/pkg/addr/isdas.go index d4c42fb09c..08c7e4945b 100644 --- a/pkg/addr/isdas.go +++ b/pkg/addr/isdas.go @@ -49,7 +49,7 @@ type ISD uint16 func ParseISD(s string) (ISD, error) { isd, err := strconv.ParseUint(s, 10, ISDBits) if err != nil { - return 0, serrors.WrapStr("parsing ISD", err) + return 0, serrors.Wrap("parsing ISD", err) } return ISD(isd), nil } @@ -105,7 +105,7 @@ func parseAS(as string, sep string) (AS, error) { parsed <<= asPartBits v, err := strconv.ParseUint(parts[i], asPartBase, asPartBits) if err != nil { - return 0, serrors.WrapStr("parsing AS part", err, "index", i, "value", as) + return 0, serrors.Wrap("parsing AS part", err, "index", i, "value", as) } parsed |= AS(v) } @@ -120,7 +120,7 @@ func parseAS(as string, sep string) (AS, error) { func asParseBGP(s string) (AS, error) { as, err := strconv.ParseUint(s, 10, BGPASBits) if err != nil { - return 0, serrors.WrapStr("parsing BGP AS", err) + return 0, serrors.Wrap("parsing BGP AS", err) } return AS(as), nil } diff --git a/pkg/daemon/apitypes.go b/pkg/daemon/apitypes.go index 4b4564bef8..904a7fab4d 100644 --- a/pkg/daemon/apitypes.go +++ b/pkg/daemon/apitypes.go @@ -45,7 +45,7 @@ type Querier struct { func (q Querier) Query(ctx context.Context, dst addr.IA) ([]snet.Path, error) { paths, err := q.Connector.Paths(ctx, dst, q.IA, PathReqFlags{}) if err != nil { - return paths, serrors.WrapStr("querying paths", err, "local_isd_as", q.IA) + return paths, serrors.Wrap("querying paths", err, "local_isd_as", q.IA) } return paths, nil } diff --git a/pkg/daemon/grpc.go b/pkg/daemon/grpc.go index 0b5ff34736..92e4bb7507 100644 --- a/pkg/daemon/grpc.go +++ b/pkg/daemon/grpc.go @@ -51,12 +51,12 @@ func (s Service) Connect(ctx context.Context) (Connector, error) { a, err := net.ResolveTCPAddr("tcp", s.Address) if err != nil { s.Metrics.incConnects(err) - return nil, serrors.WrapStr("resolving addr", err) + return nil, serrors.Wrap("resolving addr", err) } conn, err := libgrpc.SimpleDialer{}.Dial(ctx, a) if err != nil { s.Metrics.incConnects(err) - return nil, serrors.WrapStr("dialing", err) + return nil, serrors.Wrap("dialing", err) } s.Metrics.incConnects(nil) return grpcConn{conn: conn, metrics: s.Metrics}, nil @@ -97,7 +97,7 @@ func (c grpcConn) Interfaces(ctx context.Context) (map[uint16]netip.AddrPort, er a, err := netip.ParseAddrPort(intf.Address.Address) if err != nil { c.metrics.incInterface(err) - return nil, serrors.WrapStr("parsing reply", err, "raw_uri", intf.Address.Address) + return nil, serrors.Wrap("parsing reply", err, "raw_uri", intf.Address.Address) } result[uint16(ifID)] = a } @@ -255,7 +255,7 @@ func convertPath(p *sdpb.Path, dst addr.IA) (path.Path, error) { } underlayA, err := net.ResolveUDPAddr("udp", p.Interface.Address.Address) if err != nil { - return path.Path{}, serrors.WrapStr("resolving underlay", err) + return path.Path{}, serrors.Wrap("resolving underlay", err) } interfaces := make([]snet.PathInterface, len(p.Interfaces)) for i, pi := range p.Interfaces { @@ -348,11 +348,11 @@ func getASHostKeyFromReply(rep *sdpb.DRKeyASHostResponse, err := rep.EpochBegin.CheckValid() if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("invalid EpochBegin from response", err) + return drkey.ASHostKey{}, serrors.Wrap("invalid EpochBegin from response", err) } err = rep.EpochEnd.CheckValid() if err != nil { - return drkey.ASHostKey{}, serrors.WrapStr("invalid EpochEnd from response", err) + return drkey.ASHostKey{}, serrors.Wrap("invalid EpochEnd from response", err) } epoch := drkey.Epoch{ Validity: cppki.Validity{ @@ -392,11 +392,11 @@ func getHostASKeyFromReply(rep *sdpb.DRKeyHostASResponse, err := rep.EpochBegin.CheckValid() if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("invalid EpochBegin from response", err) + return drkey.HostASKey{}, serrors.Wrap("invalid EpochBegin from response", err) } err = rep.EpochEnd.CheckValid() if err != nil { - return drkey.HostASKey{}, serrors.WrapStr("invalid EpochEnd from response", err) + return drkey.HostASKey{}, serrors.Wrap("invalid EpochEnd from response", err) } epoch := drkey.Epoch{ Validity: cppki.Validity{ @@ -436,11 +436,11 @@ func getHostHostKeyFromReply(rep *sdpb.DRKeyHostHostResponse, err := rep.EpochBegin.CheckValid() if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("invalid EpochBegin from response", err) + return drkey.HostHostKey{}, serrors.Wrap("invalid EpochBegin from response", err) } err = rep.EpochEnd.CheckValid() if err != nil { - return drkey.HostHostKey{}, serrors.WrapStr("invalid EpochEnd from response", err) + return drkey.HostHostKey{}, serrors.Wrap("invalid EpochEnd from response", err) } epoch := drkey.Epoch{ Validity: cppki.Validity{ diff --git a/pkg/drkey/generic/generic.go b/pkg/drkey/generic/generic.go index d690180971..ed5ffd09f3 100644 --- a/pkg/drkey/generic/generic.go +++ b/pkg/drkey/generic/generic.go @@ -36,12 +36,12 @@ func (d Deriver) DeriveASHost( host, err := addr.ParseHost(dstHost) if err != nil { - return drkey.Key{}, serrors.WrapStr("parsing dst host", err) + return drkey.Key{}, serrors.Wrap("parsing dst host", err) } buf := make([]byte, 32) l, err := d.serializeLevel2Input(buf, drkey.AsHost, d.Proto, host) if err != nil { - return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + return drkey.Key{}, serrors.Wrap("serializing drkey level 2 input", err) } outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err @@ -55,12 +55,12 @@ func (d Deriver) DeriveHostAS( host, err := addr.ParseHost(srcHost) if err != nil { - return drkey.Key{}, serrors.WrapStr("parsing src host", err) + return drkey.Key{}, serrors.Wrap("parsing src host", err) } buf := make([]byte, 32) l, err := d.serializeLevel2Input(buf, drkey.HostAS, d.Proto, host) if err != nil { - return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + return drkey.Key{}, serrors.Wrap("serializing drkey level 2 input", err) } outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err @@ -74,12 +74,12 @@ func (d Deriver) DeriveHostHost( host, err := addr.ParseHost(dstHost) if err != nil { - return drkey.Key{}, serrors.WrapStr("deriving input H2H", err) + return drkey.Key{}, serrors.Wrap("deriving input H2H", err) } buf := make([]byte, 32) l, err := drkey.SerializeHostHostInput(buf[:], host) if err != nil { - return drkey.Key{}, serrors.WrapStr("serializing drkey host-host input", err) + return drkey.Key{}, serrors.Wrap("serializing drkey host-host input", err) } outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err @@ -97,7 +97,7 @@ func (d Deriver) serializeLevel2Input( typ, raw, err := slayers.PackAddr(host) if err != nil { - return 0, serrors.WrapStr("packing host address", err) + return 0, serrors.Wrap("packing host address", err) } l := len(raw) diff --git a/pkg/drkey/protocol.go b/pkg/drkey/protocol.go index b9469c0c8b..38598daecc 100644 --- a/pkg/drkey/protocol.go +++ b/pkg/drkey/protocol.go @@ -45,7 +45,7 @@ var ( 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) + return 0, serrors.Wrap("packing host address", err) } l := len(raw) diff --git a/pkg/drkey/specific/specific.go b/pkg/drkey/specific/specific.go index 88a585a28b..7d517e9023 100644 --- a/pkg/drkey/specific/specific.go +++ b/pkg/drkey/specific/specific.go @@ -47,12 +47,12 @@ func (d Deriver) DeriveASHost( host, err := addr.ParseHost(dstHost) if err != nil { - return drkey.Key{}, serrors.WrapStr("parsing dst host", err) + return drkey.Key{}, serrors.Wrap("parsing dst host", err) } buf := make([]byte, 32) l, err := d.serializeLevel2Input(buf, drkey.AsHost, host) if err != nil { - return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + return drkey.Key{}, serrors.Wrap("serializing drkey level 2 input", err) } outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err @@ -62,12 +62,12 @@ func (d Deriver) DeriveASHost( func (p Deriver) DeriveHostAS(srcHost string, key drkey.Key) (drkey.Key, error) { host, err := addr.ParseHost(srcHost) if err != nil { - return drkey.Key{}, serrors.WrapStr("parsing src host", err) + return drkey.Key{}, serrors.Wrap("parsing src host", err) } buf := make([]byte, 32) l, err := p.serializeLevel2Input(buf, drkey.HostAS, host) if err != nil { - return drkey.Key{}, serrors.WrapStr("serializing drkey level 2 input", err) + return drkey.Key{}, serrors.Wrap("serializing drkey level 2 input", err) } outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err @@ -77,12 +77,12 @@ func (p Deriver) DeriveHostAS(srcHost string, key drkey.Key) (drkey.Key, error) func (d Deriver) DeriveHostHost(dstHost string, key drkey.Key) (drkey.Key, error) { host, err := addr.ParseHost(dstHost) if err != nil { - return drkey.Key{}, serrors.WrapStr("deriving input H2H", err) + return drkey.Key{}, serrors.Wrap("deriving input H2H", err) } buf := make([]byte, 32) l, err := drkey.SerializeHostHostInput(buf, host) if err != nil { - return drkey.Key{}, serrors.WrapStr("serializing drkey host-host input", err) + return drkey.Key{}, serrors.Wrap("serializing drkey host-host input", err) } outKey, err := drkey.DeriveKey(buf[:l], key) return outKey, err @@ -99,7 +99,7 @@ func (d Deriver) serializeLevel2Input( typ, raw, err := slayers.PackAddr(host) if err != nil { - return 0, serrors.WrapStr("packing host address", err) + return 0, serrors.Wrap("packing host address", err) } l := len(raw) diff --git a/pkg/experimental/hiddenpath/discovery.go b/pkg/experimental/hiddenpath/discovery.go index f336a152c0..bec3bb5ccf 100644 --- a/pkg/experimental/hiddenpath/discovery.go +++ b/pkg/experimental/hiddenpath/discovery.go @@ -83,10 +83,10 @@ func resolve(ctx context.Context, ia addr.IA, discoverer Discoverer, router snet p, err := router.Route(ctx, ia) if err != nil { - return nil, serrors.WrapStr("looking up path", err) + return nil, serrors.Wrap("looking up path", err) } if p == nil { - return nil, serrors.WrapStr("no path found to remote", err) + return nil, serrors.Wrap("no path found to remote", err) } dsAddr := &snet.SVCAddr{ IA: ia, @@ -99,11 +99,11 @@ func resolve(ctx context.Context, ia addr.IA, discoverer Discoverer, router snet } hps, err := discoverer.Discover(ctx, dsAddr) if err != nil { - return nil, serrors.WrapStr("discovering hidden path server", err) + return nil, serrors.Wrap("discovering hidden path server", err) } a, err := extractAddr(hps) if err != nil { - return nil, serrors.WithCtx(err, "isd_as", ia) + return nil, serrors.Wrap("extracting address", err, "isd_as", ia) } return &snet.UDPAddr{ IA: ia, diff --git a/pkg/experimental/hiddenpath/group.go b/pkg/experimental/hiddenpath/group.go index 7a34eeccd6..e013a47a54 100644 --- a/pkg/experimental/hiddenpath/group.go +++ b/pkg/experimental/hiddenpath/group.go @@ -64,8 +64,9 @@ func ParseGroupID(s string) (GroupID, error) { } suffix, err := strconv.ParseUint(parts[1], 16, 16) if err != nil { - return GroupID{}, serrors.WrapStr("invalid group id suffix", err, + return GroupID{}, serrors.Wrap("invalid group id suffix", err, "suffix", parts[1], "group_id", s) + } return GroupID{ @@ -154,7 +155,7 @@ func (g Groups) Validate() error { func (g Groups) UnmarshalYAML(unmarshal func(interface{}) error) error { yg := ®istrationPolicyInfo{} if err := unmarshal(&yg); err != nil { - return serrors.WrapStr("unmarshaling YAML", err) + return serrors.Wrap("unmarshaling YAML", err) } if len(yg.Groups) == 0 { return nil @@ -184,14 +185,14 @@ func LoadHiddenPathGroups(location string) (Groups, error) { } c, err := config.LoadResource(location) if err != nil { - return nil, serrors.WithCtx(err, "location", location) + return nil, serrors.Wrap("reading", err, "location", location) } defer c.Close() if err := yaml.NewDecoder(c).Decode(&ret); err != nil { - return nil, serrors.WrapStr("parsing", err, "location", location) + return nil, serrors.Wrap("parsing", err, "location", location) } if err := ret.Validate(); err != nil { - return nil, serrors.WrapStr("validating", err, "file", c) + return nil, serrors.Wrap("validating", err, "file", c) } return ret, nil } @@ -224,23 +225,23 @@ func parseGroups(groups map[string]*groupInfo) (Groups, error) { for rawID, rawGroup := range groups { id, err := ParseGroupID(rawID) if err != nil { - return nil, serrors.WrapStr("parsing group ID", err) + return nil, serrors.Wrap("parsing group ID", err) } owner, err := addr.ParseIA(rawGroup.Owner) if err != nil { - return nil, serrors.WrapStr("parsing owner", err, "group_id", id) + return nil, serrors.Wrap("parsing owner", err, "group_id", id) } writers, err := stringsToIASet(rawGroup.Writers) if err != nil { - return nil, serrors.WrapStr("parsing writer", err) + return nil, serrors.Wrap("parsing writer", err) } readers, err := stringsToIASet(rawGroup.Readers) if err != nil { - return nil, serrors.WrapStr("parsing readers", err) + return nil, serrors.Wrap("parsing readers", err) } registries, err := stringsToIASet(rawGroup.Registries) if err != nil { - return nil, serrors.WrapStr("parsing registries", err) + return nil, serrors.Wrap("parsing registries", err) } result[id] = &Group{ ID: id, diff --git a/pkg/experimental/hiddenpath/grpc/discovery.go b/pkg/experimental/hiddenpath/grpc/discovery.go index a06960ac08..2410756bbc 100644 --- a/pkg/experimental/hiddenpath/grpc/discovery.go +++ b/pkg/experimental/hiddenpath/grpc/discovery.go @@ -36,7 +36,7 @@ type Discoverer struct { func (d *Discoverer) Discover(ctx context.Context, dsAddr net.Addr) (hiddenpath.Servers, error) { conn, err := d.Dialer.Dial(ctx, dsAddr) if err != nil { - return hiddenpath.Servers{}, serrors.WrapStr("dialing", err) + return hiddenpath.Servers{}, serrors.Wrap("dialing", err) } defer conn.Close() client := dspb.NewDiscoveryServiceClient(conn) @@ -62,14 +62,14 @@ func (d *Discoverer) Discover(ctx context.Context, dsAddr net.Addr) (hiddenpath. for _, l := range r.Lookup { a, err := parseUDPAddr(l.Address) if err != nil { - return hiddenpath.Servers{}, serrors.WrapStr("parsing address", err, "raw", l.Address) + return hiddenpath.Servers{}, serrors.Wrap("parsing address", err, "raw", l.Address) } reply.Lookup = append(reply.Lookup, a) } for _, l := range r.Registration { a, err := parseUDPAddr(l.Address) if err != nil { - return hiddenpath.Servers{}, serrors.WrapStr("parsing address", err, "raw", l.Address) + return hiddenpath.Servers{}, serrors.Wrap("parsing address", err, "raw", l.Address) } reply.Registration = append(reply.Registration, a) } diff --git a/pkg/experimental/hiddenpath/grpc/requester.go b/pkg/experimental/hiddenpath/grpc/requester.go index 65815c954c..e8d35f720d 100644 --- a/pkg/experimental/hiddenpath/grpc/requester.go +++ b/pkg/experimental/hiddenpath/grpc/requester.go @@ -147,11 +147,11 @@ func (r AuthoritativeRequester) HiddenSegments(ctx context.Context, } rawReq, err := proto.Marshal(pbReq) if err != nil { - return nil, serrors.WrapStr("marshaling request", err) + return nil, serrors.Wrap("marshaling request", err) } signedReq, err := r.Signer.Sign(ctx, rawReq) if err != nil { - return nil, serrors.WrapStr("signing request", err) + return nil, serrors.Wrap("signing request", err) } client := hspb.NewAuthoritativeHiddenSegmentLookupServiceClient(conn) @@ -170,7 +170,7 @@ func unpackSegs(pbSegs map[int32]*hspb.Segments) ([]*seg.Meta, error) { for i, pb := range segments.Segments { ps, err := seg.SegmentFromPB(pb) if err != nil { - return nil, serrors.WrapStr("parsing segments", err, "index", i) + return nil, serrors.Wrap("parsing segments", err, "index", i) } segs = append(segs, &seg.Meta{ Type: seg.Type(segType), diff --git a/pkg/experimental/hiddenpath/registrationpolicy.go b/pkg/experimental/hiddenpath/registrationpolicy.go index 5187f64cc5..d8d9a41d37 100644 --- a/pkg/experimental/hiddenpath/registrationpolicy.go +++ b/pkg/experimental/hiddenpath/registrationpolicy.go @@ -40,7 +40,7 @@ func (p RegistrationPolicy) Validate() error { for ifID, p := range p { for id, group := range p.Groups { if err := group.Validate(); err != nil { - return serrors.WrapStr("validating group", err, "group_id", id, "interface", ifID) + return serrors.Wrap("validating group", err, "group_id", id, "interface", ifID) } } } @@ -71,7 +71,7 @@ func (p RegistrationPolicy) MarshalYAML() (interface{}, error) { func (p RegistrationPolicy) UnmarshalYAML(unmarshal func(interface{}) error) error { rawPolicy := ®istrationPolicyInfo{} if err := unmarshal(&rawPolicy); err != nil { - return serrors.WrapStr("parsing yaml", err) + return serrors.Wrap("parsing yaml", err) } groups, err := parseGroups(rawPolicy.Groups) if err != nil { @@ -96,26 +96,26 @@ func LoadConfiguration(location string) (Groups, RegistrationPolicy, error) { } c, err := config.LoadResource(location) if err != nil { - return nil, nil, serrors.WithCtx(err, "location", location) + return nil, nil, serrors.Wrap("reading", err, "location", location) } defer c.Close() info := registrationPolicyInfo{} if err := yaml.NewDecoder(c).Decode(&info); err != nil { - return nil, nil, serrors.WrapStr("parsing", err, "location", location) + return nil, nil, serrors.Wrap("parsing", err, "location", location) } groups, err := parseGroups(info.Groups) if err != nil { - return nil, nil, serrors.WrapStr("parsing groups", err, "location", location) + return nil, nil, serrors.Wrap("parsing groups", err, "location", location) } if err := groups.Validate(); err != nil { - return nil, nil, serrors.WrapStr("validating groups", err, "location", location) + return nil, nil, serrors.Wrap("validating groups", err, "location", location) } if len(info.Policies) == 0 { return groups, nil, nil } pol, err := parsePolicies(groups, info.Policies) if err != nil { - return nil, nil, serrors.WrapStr("parsing policies", err, "location", location) + return nil, nil, serrors.Wrap("parsing policies", err, "location", location) } return groups, pol, nil } @@ -138,7 +138,7 @@ func parsePolicies(groups Groups, rawPolicies map[uint64][]string) (Registration } id, err := ParseGroupID(groupID) if err != nil { - return nil, serrors.WrapStr("parsing group ID", err) + return nil, serrors.Wrap("parsing group ID", err) } group, ok := groups[id] if !ok { diff --git a/pkg/experimental/hiddenpath/registry.go b/pkg/experimental/hiddenpath/registry.go index 800e8c46b0..6f8e85e19b 100644 --- a/pkg/experimental/hiddenpath/registry.go +++ b/pkg/experimental/hiddenpath/registry.go @@ -72,11 +72,11 @@ func (h RegistryServer) Register(ctx context.Context, reg Registration) error { // verify segments if err := h.Verifier.Verify(ctx, reg.Segments, reg.Peer); err != nil { - return serrors.WrapStr("verifying segments", err) + return serrors.Wrap("verifying segments", err) } // store segments in db if err := h.DB.Put(ctx, reg.Segments, reg.GroupID); err != nil { - return serrors.WrapStr("writing segments", err) + return serrors.Wrap("writing segments", err) } return nil } diff --git a/pkg/grpc/dialer.go b/pkg/grpc/dialer.go index abaf419852..509f61ce27 100644 --- a/pkg/grpc/dialer.go +++ b/pkg/grpc/dialer.go @@ -145,7 +145,7 @@ func (d *QUICDialer) Dial(ctx context.Context, addr net.Addr) (*grpc.ClientConn, addr, err := d.Rewriter.RedirectToQUIC(ctx, addr) if err != nil { - return nil, serrors.WrapStr("resolving SVC address", err) + return nil, serrors.Wrap("resolving SVC address", err) } if _, ok := addr.(*snet.UDPAddr); !ok { return nil, serrors.New("wrong address type after svc resolution", diff --git a/pkg/log/log.go b/pkg/log/log.go index a0ddbcd7ef..6044f152b1 100644 --- a/pkg/log/log.go +++ b/pkg/log/log.go @@ -60,8 +60,9 @@ func Setup(cfg Config, opts ...Option) error { func convertCfg(cfg ConsoleConfig) (zap.Config, error) { var level zapcore.Level if err := level.UnmarshalText([]byte(cfg.Level)); err != nil { - return zap.Config{}, serrors.WrapStr("unable to parse log.console.level", err, + return zap.Config{}, serrors.Wrap("unable to parse log.console.level", err, "level", cfg.Level) + } encoding := "console" if cfg.Format == "json" { @@ -90,8 +91,9 @@ func getStacktraceLvl(cfg ConsoleConfig) (zapcore.LevelEnabler, error) { } var level zapcore.Level if err := level.UnmarshalText([]byte(cfg.StacktraceLevel)); err != nil { - return nil, serrors.WrapStr("unable to parse log.console.stacktrace_level", err, + return nil, serrors.Wrap("unable to parse log.console.stacktrace_level", err, "level", cfg.Level) + } return level, nil } @@ -114,7 +116,7 @@ func setupConsole(cfg ConsoleConfig, opts options) error { logger, err := zCfg.Build(zapOpts...) if err != nil { - return serrors.WrapStr("creating logger", err) + return serrors.Wrap("creating logger", err) } zap.ReplaceGlobals(logger) ConsoleLevel = httpLevel{a: zCfg.Level} diff --git a/pkg/private/processmetrics/processmetrics_linux.go b/pkg/private/processmetrics/processmetrics_linux.go index 2953df24e3..6e10254f45 100644 --- a/pkg/private/processmetrics/processmetrics_linux.go +++ b/pkg/private/processmetrics/processmetrics_linux.go @@ -202,8 +202,9 @@ func Init() error { taskPath := filepath.Join(procfs.DefaultMountPoint, strconv.Itoa(me), "task") taskDir, err := os.Open(taskPath) if err != nil { - return serrors.WrapStr("Opening /proc/pid/task/ failed", err, + return serrors.Wrap("Opening /proc/pid/task/ failed", err, "pid", me) + } c := &procStatCollector{ @@ -214,13 +215,13 @@ func Init() error { err = c.updateStat() if err != nil { // Ditch the broken collector. It won't do anything useful. - return serrors.WrapStr("First update failed", err) + return serrors.Wrap("First update failed", err) } // It works. Register it so prometheus milks it. err = prometheus.Register(c) if err != nil { - return serrors.WrapStr("Registration failed", err) + return serrors.Wrap("Registration failed", err) } return nil diff --git a/pkg/private/serrors/errors.go b/pkg/private/serrors/errors.go index c913183b6c..663d20ed6b 100644 --- a/pkg/private/serrors/errors.go +++ b/pkg/private/serrors/errors.go @@ -166,28 +166,41 @@ func (e basicError) MarshalLogObject(enc zapcore.ObjectEncoder) error { return e.errorInfo.marshalLogObject(enc) } -// WrapStr returns an error that associates the given error, with the given cause (an underlying +// Wrap returns an error that associates the given error, with the given cause (an underlying // error) unless nil, and the given context. // -// A stack dump is added unless cause is a basicError (in which case it is assumed to contain a -// stack dump). +// A stack dump is added unless cause is a basicError or joinedError (in which case it is assumed to +// contain a stack dump). // -// The returned error supports Is. Is(cause)returns true. +// The returned error supports Is. Is(cause) returns true. // -// WrapStr will soon be renamed Wrap, once the name Wrap becomes available. Until then it is ok to -// use wrapStr(). -func WrapStr(msg string, cause error, errCtx ...interface{}) error { +// This is best used when adding context to an error that already has some. The existing error is +// used as the cause; all of its existing context and stack trace are preserved for printing and +// logging. The new context is attached to the new error. +// +// Passing nil as the cause is legal but of little use. In that case, prefer [New]. The only +// difference is the underlying type of the returned interface. +// +// To enrich a sentinel error with context only, do not use +// +// Wrap("dummy message", sentinel, ...) +// +// instead use [Join] +// +// Join(sentinel, nil, ...) +// +// Wrap may be useful to enrich sentinel errors if the main message needs to be different than +// that supplied by the sentinel error. +func Wrap(msg string, cause error, errCtx ...interface{}) error { return basicError{ errorInfo: mkErrorInfo(cause, true, errCtx...), msg: msg, } } -// WrapStrNoStack returns an error that associates the given error, with the given cause -// (an underlying error) unless nil, and the given context. A stack dump is not added. -// if cause is a basicError that contains a stack dump, that stack dump is preserved. The returned -// error supports Is. Is(cause) returns true. -func WrapStrNoStack(msg string, cause error, errCtx ...interface{}) error { +// WrapNoStack behaves like [Wrap], except that no stack dump is added, regardless of cause's +// underlying type. +func WrapNoStack(msg string, cause error, errCtx ...interface{}) error { return basicError{ errorInfo: mkErrorInfo(cause, false, errCtx...), msg: msg, @@ -235,11 +248,18 @@ func (e joinedError) MarshalLogObject(enc zapcore.ObjectEncoder) error { // Join returns an error that associates the given error, with the given cause (an underlying error) // unless nil, and the given context. // -// A stack dump is added unless cause is a basicError (in which case it is assume to contain a stack -// dump). +// A stack dump is added unless cause is a basicError or joinedError (in which case it is assumed to +// contain a stack dump). // // The returned error supports Is. If cause isn't nil, Is(cause) returns true. Is(error) returns // true. +// +// This is best used as an alternative to [Wrap] when deriving an error from a sentinel error. If +// there is an underlying error it may be used as the cause (with the same effect as [Wrap]. When +// creating a new error (not due to an underlying error) nil may be passed as the cause. In that +// case the result is a sentinel error enriched with context. For such a purpose this is better than +// [Wrap], since [Wrap] would retain any irrelevant context possibly attached to the sentinel error +// and store a redundant message string. func Join(err, cause error, errCtx ...interface{}) error { if err == nil && cause == nil { // Pointless. Will not. Also, maintaining backward compatibility with @@ -252,14 +272,8 @@ func Join(err, cause error, errCtx ...interface{}) error { } } -// JoinNoStack returns an error that associates the given error, with the given cause -// (an underlying error) unless nil, and the given context. -// -// A stack dump is not added. If cause is a basicError and contain a stack dump. That stack dump is -// preserved. -// -// The returned error supports Is. If cause isn't nil, Is(cause) returns true. Is(error) returns -// true. +// JoinNoStack behaves like [Join] except that no stack dump is added regardless of cause's +// underlying type. func JoinNoStack(err, cause error, errCtx ...interface{}) error { if err == nil && cause == nil { // Pointless. Will not. @@ -271,27 +285,6 @@ func JoinNoStack(err, cause error, errCtx ...interface{}) error { } } -// Deprecated: WithCtx should never have existed. Depending on intent, use: -// - Join(err, nil, errCtx): If err has no context to preserve. -// - WrapStr("some error with context added", err, errctx): if err is an error with error -// information that needs to be preserved. -// -// This shim does the latter for you for the time being. -// -// WithCtx used to attempt the merger of the given error into the newly created one with -// semantically incorrect results. That feature is gone and the results differ only slightly in the -// formated string output. WithCtx didn't try to add a stack, so this shim doesn't either. -func WithCtx(err error, errCtx ...interface{}) error { - return WrapStrNoStack("error", err, errCtx...) -} - -// Deprecated: Wrap has been renamed Join. Join and the historical Wrap do differ very slightly: -// any stack dump that might have be attached to err is ignored when logging. Like before, no stack -// dump is added to the returned error. -func Wrap(err, cause error, errCtx ...interface{}) error { - return JoinNoStack(err, cause, errCtx...) -} - // List is a slice of errors. type List []error diff --git a/pkg/private/serrors/errors_test.go b/pkg/private/serrors/errors_test.go index 9f0443fc08..36d4647a57 100644 --- a/pkg/private/serrors/errors_test.go +++ b/pkg/private/serrors/errors_test.go @@ -69,10 +69,10 @@ func (e *testToTempErr) Unwrap() error { func TestIsTimeout(t *testing.T) { err := serrors.New("no timeout") assert.False(t, serrors.IsTimeout(err)) - wrappedErr := serrors.WrapStr("timeout", + wrappedErr := serrors.Wrap("timeout", &testToTempErr{msg: "to", timeout: true}) assert.True(t, serrors.IsTimeout(wrappedErr)) - noTimeoutWrappingTimeout := serrors.WrapStr("notimeout", &testToTempErr{ + noTimeoutWrappingTimeout := serrors.Wrap("notimeout", &testToTempErr{ msg: "non timeout wraps timeout", timeout: false, cause: &testToTempErr{msg: "timeout", timeout: true}, @@ -83,10 +83,10 @@ func TestIsTimeout(t *testing.T) { func TestIsTemporary(t *testing.T) { err := serrors.New("not temp") assert.False(t, serrors.IsTemporary(err)) - wrappedErr := serrors.WrapStr("temp", + wrappedErr := serrors.Wrap("temp", &testToTempErr{msg: "to", temporary: true}) assert.True(t, serrors.IsTemporary(wrappedErr)) - noTempWrappingTemp := serrors.WrapStr("notemp", &testToTempErr{ + noTempWrappingTemp := serrors.Wrap("notemp", &testToTempErr{ msg: "non temp wraps temp", temporary: false, cause: &testToTempErr{msg: "temp", temporary: true}, @@ -94,27 +94,27 @@ func TestIsTemporary(t *testing.T) { assert.False(t, serrors.IsTemporary(noTempWrappingTemp)) } -func TestWithCtx(t *testing.T) { +func TestWrapNoStack(t *testing.T) { t.Run("Is", func(t *testing.T) { err := serrors.New("simple err") - errWithCtx := serrors.WithCtx(err, "someCtx", "someValue") + errWithCtx := serrors.WrapNoStack("error", err, "someCtx", "someValue") assert.ErrorIs(t, errWithCtx, err) assert.ErrorIs(t, errWithCtx, errWithCtx) }) t.Run("As", func(t *testing.T) { err := &testErrType{msg: "test err"} - errWithCtx := serrors.WithCtx(err, "someCtx", "someVal") + errWithCtx := serrors.WrapNoStack("error", err, "someCtx", "someVal") var errAs *testErrType require.True(t, errors.As(errWithCtx, &errAs)) assert.Equal(t, err, errAs) }) } -func TestWrap(t *testing.T) { +func TestJoinNostack(t *testing.T) { t.Run("Is", func(t *testing.T) { err := serrors.New("simple err") msg := serrors.New("msg err") - wrappedErr := serrors.Wrap(msg, err, "someCtx", "someValue") + wrappedErr := serrors.JoinNoStack(msg, err, "someCtx", "someValue") assert.ErrorIs(t, wrappedErr, err) assert.ErrorIs(t, wrappedErr, msg) assert.ErrorIs(t, wrappedErr, wrappedErr) @@ -122,7 +122,7 @@ func TestWrap(t *testing.T) { t.Run("As", func(t *testing.T) { err := &testErrType{msg: "test err"} msg := serrors.New("msg err") - wrappedErr := serrors.Wrap(msg, err, "someCtx", "someValue") + wrappedErr := serrors.JoinNoStack(msg, err, "someCtx", "someValue") var errAs *testErrType require.True(t, errors.As(wrappedErr, &errAs)) assert.Equal(t, err, errAs) @@ -134,14 +134,14 @@ func TestWrapStr(t *testing.T) { t.Run("Is", func(t *testing.T) { err := serrors.New("simple err") msg := "msg" - wrappedErr := serrors.WrapStr(msg, err, "someCtx", "someValue") + wrappedErr := serrors.Wrap(msg, err, "someCtx", "someValue") assert.ErrorIs(t, wrappedErr, err) assert.ErrorIs(t, wrappedErr, wrappedErr) }) t.Run("As", func(t *testing.T) { err := &testErrType{msg: "test err"} msg := "msg" - wrappedErr := serrors.WrapStr(msg, err, "someCtx", "someValue") + wrappedErr := serrors.Wrap(msg, err, "someCtx", "someValue") var errAs *testErrType require.True(t, errors.As(wrappedErr, &errAs)) assert.Equal(t, err, errAs) @@ -192,7 +192,7 @@ func TestEncoding(t *testing.T) { goldenFileBase: "testdata/new-with-context", }, "wrapped string": { - err: serrors.WrapStr( + err: serrors.Wrap( "msg error", serrors.New("msg cause"), "k0", "v0", @@ -201,7 +201,7 @@ func TestEncoding(t *testing.T) { goldenFileBase: "testdata/wrapped-string", }, "wrapped with context": { - err: serrors.WrapStr( + err: serrors.Wrap( "msg error", serrors.New("msg cause", "cause_ctx_key", "cause_ctx_val"), "k0", "v0", @@ -209,20 +209,20 @@ func TestEncoding(t *testing.T) { ), goldenFileBase: "testdata/wrapped-with-string", }, - "wrapped error": { - err: serrors.Wrap( + "joined error no stack": { + err: serrors.JoinNoStack( serrors.New("msg error"), serrors.New("msg cause"), "k0", "v0", "k1", 1, ), - goldenFileBase: "testdata/wrapped-error", + goldenFileBase: "testdata/joined-error", }, "error with context": { - // WithCtx is deprecated. The shim does it the new way: sets err as the cause of a new - // error. The string output isn't exactly the same. Which almost nothing ever notices... - // except this test. - err: serrors.WithCtx(serrors.New("simple err"), "someCtx", "someValue"), + // First arg: a msg for the new error. Second arg a cause. Ctx of cause is preserved. + // When err is just Sentinel error (as in this test), JoinNoStack would be better. + err: serrors.WrapNoStack("error", serrors.New("simple err"), "someCtx", "someValue"), + goldenFileBase: "testdata/error-with-context", }, "error list": { @@ -290,7 +290,7 @@ func TestJoinNil(t *testing.T) { func TestAtMostOneStacktrace(t *testing.T) { err := errors.New("core") for i := range [20]int{} { - err = serrors.WrapStr("wrap", err, "level", i) + err = serrors.Wrap("wrap", err, "level", i) } var b bytes.Buffer @@ -329,40 +329,31 @@ func ExampleNew() { // false } -func ExampleWithCtx() { - // It is not possible to augment the context of a basicError. - // WithCtx turns that into an error with a cause. - // ErrBadL4 is an error defined at package scope. - var ErrBadL4 = serrors.New("Unsupported L4 protocol") - addedCtx := serrors.WithCtx(ErrBadL4, "type", "SCTP") - - fmt.Println(addedCtx) - // Output: - // error {type=SCTP}: Unsupported L4 protocol -} - -func ExampleWrapStr() { - // ErrNoSpace is an error defined at package scope. - var ErrNoSpace = serrors.New("no space") - wrappedErr := serrors.WrapStr("wrap with more context", ErrNoSpace, "ctx", 1) +func ExampleWrap() { + // ErrNoSpace is an error defined at package scope. It should be is an error from lower layers, + // with some context already attached. + var ErrNoSpace = serrors.New("no space", "dev", "sd0") + wrappedErr := serrors.Wrap("wrap with more context", ErrNoSpace, "ctx", 1) fmt.Println(errors.Is(wrappedErr, ErrNoSpace)) fmt.Printf("\n%v", wrappedErr) // Output: // true // - // wrap with more context {ctx=1}: no space + // wrap with more context {ctx=1}: no space {dev=sd0} } -func ExampleWrap() { - // ErrNoSpace is an error defined at package scope. - var ErrNoSpace = serrors.New("no space") - // ErrDB is an error defined at package scope. - var ErrDB = serrors.New("db") - wrapped := serrors.Wrap(ErrDB, ErrNoSpace, "ctx", 1) +func ExampleJoin() { + // ErrNoProgress is a sentinel error defined at package scope. cause is an error from a lower + // layer, based on ErrNoSpace, with an more specific message. + var cause = fmt.Errorf("sd0 unresponsive: %w", io.ErrNoProgress) + // ErrDB is a sentinel error defined at package scope in the upper layer. + var ErrDB = errors.New("db") + wrapped := serrors.Join(ErrDB, cause, "ctx", 1) // Now we can identify specific errors: - fmt.Println(errors.Is(wrapped, ErrNoSpace)) + fmt.Println(errors.Is(wrapped, io.ErrNoProgress)) + fmt.Println(errors.Is(wrapped, cause)) // But we can also identify the broader error class ErrDB: fmt.Println(errors.Is(wrapped, ErrDB)) @@ -370,8 +361,31 @@ func ExampleWrap() { // Output: // true // true + // true // - // db {ctx=1}: no space + // db {ctx=1}: sd0 unresponsive: multiple Read calls return no data or error +} + +func ExampleWrapNoStack() { + // ErrBadL4 is a sentinel defined at package scope. + var ErrBadL4 = errors.New("Unsupported L4 protocol") + addedCtx := serrors.WrapNoStack("parsing packet", ErrBadL4, "type", "SCTP") + + fmt.Println(addedCtx) + // Output: + // parsing packet {type=SCTP}: Unsupported L4 protocol +} + +func ExampleJoinNoStack() { + // BrokenPacket is a sentinel error defined at package scope. + var brokenPacket = serrors.New("invalid packet") + // ErrBadL4 is a sentinel error defined at package scope. + var ErrBadL4 = serrors.New("Unsupported L4 protocol") + addedCtx := serrors.JoinNoStack(brokenPacket, ErrBadL4, "type", "SCTP") + + fmt.Println(addedCtx) + // Output: + // invalid packet {type=SCTP}: Unsupported L4 protocol } // sanitizeLog sanitizes the log output so that stack traces look the same on @@ -395,7 +409,7 @@ func TestUncomparable(t *testing.T) { t.Run("Is", func(t *testing.T) { // We make two wrappers of uncomparable error objects. We could also create custom error // types for the same result, but this is closer to our use cases. - errObject := serrors.WrapStr("simple err", nil, "dummy", "context") + errObject := serrors.Wrap("simple err", nil, "dummy", "context") wrapperA := serrors.Join(errObject, nil, "dummy", "context") wrapperB := serrors.Join(errObject, nil, "dummy", "context") assert.NotErrorIs(t, wrapperA, wrapperB) diff --git a/pkg/private/serrors/testdata/error-with-context.log b/pkg/private/serrors/testdata/error-with-context.log index 7548ec61c3..ec0ad5cf97 100644 --- a/pkg/private/serrors/testdata/error-with-context.log +++ b/pkg/private/serrors/testdata/error-with-context.log @@ -1 +1 @@ -{"err":{"cause":{"msg":"simple err","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:225","testing.tRunner gosdk"]},"msg":"error","someCtx":"someValue"},"level":"info","msg":"Failed to do thing"} \ No newline at end of file +{"err":{"cause":{"msg":"simple err","stacktrace":["pkg/private/serrors/go_default_test_test.TestEncoding pkg/private/serrors/errors_test.go:224","testing.tRunner gosdk"]},"msg":"error","someCtx":"someValue"},"level":"info","msg":"Failed to do thing"} \ No newline at end of file diff --git a/pkg/private/serrors/testdata/wrapped-error.err b/pkg/private/serrors/testdata/joined-error.err similarity index 100% rename from pkg/private/serrors/testdata/wrapped-error.err rename to pkg/private/serrors/testdata/joined-error.err diff --git a/pkg/private/serrors/testdata/wrapped-error.log b/pkg/private/serrors/testdata/joined-error.log similarity index 100% rename from pkg/private/serrors/testdata/wrapped-error.log rename to pkg/private/serrors/testdata/joined-error.log diff --git a/pkg/private/xtest/graph/graph.go b/pkg/private/xtest/graph/graph.go index ee3020f4fd..a79a6063e4 100644 --- a/pkg/private/xtest/graph/graph.go +++ b/pkg/private/xtest/graph/graph.go @@ -329,7 +329,7 @@ func (g *Graph) beacon(ifIDs []uint16, addStaticInfo bool) *seg.PathSegment { asEntry.Extensions.StaticInfo = generateStaticInfo(g, currIA, inIF, outIF) } if err := segment.AddASEntry(context.Background(), asEntry, g.signers[currIA]); err != nil { - panic(serrors.WrapStr("adding AS entry", err)) + panic(serrors.Wrap("adding AS entry", err)) } inIF = remoteOutIF currIA = g.parents[remoteOutIF] diff --git a/pkg/private/xtest/graphupdater/updater.go b/pkg/private/xtest/graphupdater/updater.go index 0584ba3689..75b15e0cef 100644 --- a/pkg/private/xtest/graphupdater/updater.go +++ b/pkg/private/xtest/graphupdater/updater.go @@ -38,12 +38,12 @@ type topo struct { func loadTopo(topoFile string) (*topo, error) { buffer, err := os.ReadFile(topoFile) if err != nil { - return nil, serrors.WrapStr("Unable to read from file", err, "name", topoFile) + return nil, serrors.Wrap("Unable to read from file", err, "name", topoFile) } var t topo err = yaml.Unmarshal(buffer, &t) if err != nil { - return nil, serrors.WrapStr("Unable to parse YAML data", err) + return nil, serrors.Wrap("Unable to parse YAML data", err) } return &t, nil } @@ -51,7 +51,7 @@ func loadTopo(topoFile string) (*topo, error) { func LoadGraph(topoFile string) (*Graph, error) { t, err := loadTopo(topoFile) if err != nil { - return nil, serrors.WrapStr("Failed to load Topo", err) + return nil, serrors.Wrap("Failed to load Topo", err) } return newGraph(t.Links, graph.StaticIfaceIdMapping), nil } @@ -65,11 +65,11 @@ func WriteGraphToFile(topoFile, destFile string) error { var buf bytes.Buffer _, err = g.Write(&buf) if err != nil { - return serrors.WrapStr("Failed to write graph to byte buffer", err) + return serrors.Wrap("Failed to write graph to byte buffer", err) } fmtCode, err := format.Source(buf.Bytes()) if err != nil { - return serrors.WrapStr("Failed to fmt code", err) + return serrors.Wrap("Failed to fmt code", err) } return os.WriteFile(destFile, fmtCode, os.ModePerm) } diff --git a/pkg/scrypto/cppki/ca.go b/pkg/scrypto/cppki/ca.go index 460d963f7b..c7bbcbdb86 100644 --- a/pkg/scrypto/cppki/ca.go +++ b/pkg/scrypto/cppki/ca.go @@ -65,7 +65,7 @@ func (ca CAPolicy) CreateChain(csr *x509.CertificateRequest) ([]*x509.Certificat // Choose random serial number. serial := make([]byte, 20) if _, err := rand.Read(serial); err != nil { - return nil, serrors.WrapStr("creating random serial number", err) + return nil, serrors.Wrap("creating random serial number", err) } // ExtraNames are used for marshaling @@ -73,7 +73,7 @@ func (ca CAPolicy) CreateChain(csr *x509.CertificateRequest) ([]*x509.Certificat subject.ExtraNames = subject.Names skid, err := SubjectKeyID(csr.PublicKey) if err != nil { - return nil, serrors.WrapStr("computing subject key ID", err) + return nil, serrors.Wrap("computing subject key ID", err) } // x509 stdlib selects the appropriate signature algorithm based on the curve. @@ -100,15 +100,15 @@ func (ca CAPolicy) CreateChain(csr *x509.CertificateRequest) ([]*x509.Certificat } raw, err := x509.CreateCertificate(rand.Reader, tmpl, ca.Certificate, csr.PublicKey, ca.Signer) if err != nil { - return nil, serrors.WrapStr("creating AS certificate", err) + return nil, serrors.Wrap("creating AS certificate", err) } as, err := x509.ParseCertificate(raw) if err != nil { - return nil, serrors.WrapStr("parse created AS certificate", err) + return nil, serrors.Wrap("parse created AS certificate", err) } chain := []*x509.Certificate{as, ca.Certificate} if err := ValidateChain(chain); err != nil { - return nil, serrors.WrapStr("created invalid AS certificate", err) + return nil, serrors.Wrap("created invalid AS certificate", err) } return chain, nil } diff --git a/pkg/scrypto/cppki/certs.go b/pkg/scrypto/cppki/certs.go index 74919cb06c..f60122884b 100644 --- a/pkg/scrypto/cppki/certs.go +++ b/pkg/scrypto/cppki/certs.go @@ -133,7 +133,7 @@ func ParsePEMCerts(raw []byte) ([]*x509.Certificate, error) { } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { - return nil, serrors.WrapStr("error parsing certificate", err) + return nil, serrors.Wrap("error parsing certificate", err) } certs = append(certs, cert) } @@ -158,7 +158,7 @@ func VerifyChain(certs []*x509.Certificate, opts VerifyOptions) error { for _, trc := range opts.TRC { if err := verifyChain(certs, trc, opts.CurrentTime); err != nil { errs = append(errs, - serrors.WrapStr("verifying chain", err, + serrors.Wrap("verifying chain", err, "trc_base", trc.ID.Base, "trc_serial", trc.ID.Serial, ), @@ -172,7 +172,7 @@ func VerifyChain(certs []*x509.Certificate, opts VerifyOptions) error { func verifyChain(certs []*x509.Certificate, trc *TRC, now time.Time) error { if err := ValidateChain(certs); err != nil { - return serrors.WrapStr("chain validation failed", err) + return serrors.Wrap("chain validation failed", err) } if trc == nil || trc.IsZero() { return serrors.New("TRC required for chain verification") @@ -181,7 +181,7 @@ func verifyChain(certs []*x509.Certificate, trc *TRC, now time.Time) error { intPool.AddCert(certs[1]) rootPool, err := trc.RootPool() if err != nil { - return serrors.WrapStr("failed to extract root certs", err, "trc", trc.ID) + return serrors.Wrap("failed to extract root certs", err, "trc", trc.ID) } _, err = certs[0].Verify(x509.VerifyOptions{ Intermediates: intPool, @@ -201,7 +201,7 @@ func ValidateChain(certs []*x509.Certificate) error { first, err := ValidateCert(certs[0]) if err != nil { - return serrors.WrapStr("validating first certificate", err) + return serrors.Wrap("validating first certificate", err) } if first != AS { return serrors.New("first certificate of invalid type", "expected", AS, "actual", first) @@ -210,7 +210,7 @@ func ValidateChain(certs []*x509.Certificate) error { second, err := ValidateCert(certs[1]) if err != nil { - return serrors.WrapStr("validating second certificate", err) + return serrors.Wrap("validating second certificate", err) } if second != CA { return serrors.New("second certificate of invalid type", "expected", CA, "actual", second) @@ -246,7 +246,7 @@ func ValidateCert(c *x509.Certificate) (CertType, error) { case AS: return ct, validateAS(c) default: - return Invalid, serrors.WithCtx(ErrInvalidCertType, "cert_type", ct) + return Invalid, serrors.JoinNoStack(ErrInvalidCertType, nil, "cert_type", ct) } } @@ -505,10 +505,10 @@ func containsOID(oids []asn1.ObjectIdentifier, o asn1.ObjectIdentifier) bool { func subjectAndIssuerIASet(c *x509.Certificate) error { var errs serrors.List if _, err := ExtractIA(c.Issuer); err != nil { - errs = append(errs, serrors.WrapStr("extracting issuer ISD-AS", err)) + errs = append(errs, serrors.Wrap("extracting issuer ISD-AS", err)) } if _, err := ExtractIA(c.Subject); err != nil { - errs = append(errs, serrors.WrapStr("extracting subject ISD-AS", err)) + errs = append(errs, serrors.Wrap("extracting subject ISD-AS", err)) } return errs.ToError() } @@ -540,7 +540,7 @@ func findIA(dn pkix.Name) (*addr.IA, error) { } ia, err := addr.ParseIA(rawIA) if err != nil { - return nil, serrors.WrapStr("invalid ISD-AS value", err) + return nil, serrors.Wrap("invalid ISD-AS value", err) } if ia.IsWildcard() { return nil, serrors.New("wildcard ISD-AS not allowed", "isd_as", ia) diff --git a/pkg/scrypto/cppki/id.go b/pkg/scrypto/cppki/id.go index a4234c4c81..b5398b34b5 100644 --- a/pkg/scrypto/cppki/id.go +++ b/pkg/scrypto/cppki/id.go @@ -83,7 +83,7 @@ func (id TRCID) Validate() error { return ErrWildcardISD } if id.Base > id.Serial { - return serrors.WithCtx(ErrSerialBeforeBase, "serial", id.Serial, "base", id.Base) + return serrors.JoinNoStack(ErrSerialBeforeBase, nil, "serial", id.Serial, "base", id.Base) } // Serial != 0 is implied by this, and the check above. if id.Base == 0 { diff --git a/pkg/scrypto/cppki/signed_trc.go b/pkg/scrypto/cppki/signed_trc.go index 637e35569d..612d578200 100644 --- a/pkg/scrypto/cppki/signed_trc.go +++ b/pkg/scrypto/cppki/signed_trc.go @@ -38,26 +38,27 @@ type SignedTRCs []SignedTRC func DecodeSignedTRC(raw []byte) (SignedTRC, error) { ci, err := protocol.ParseContentInfo(raw) if err != nil { - return SignedTRC{}, serrors.WrapStr("error parsing ContentInfo", err) + return SignedTRC{}, serrors.Wrap("error parsing ContentInfo", err) } sd, err := ci.SignedDataContent() if err != nil { - return SignedTRC{}, serrors.WrapStr("error parsing SignedData", err) + return SignedTRC{}, serrors.Wrap("error parsing SignedData", err) } if sd.Version != 1 { return SignedTRC{}, serrors.New("unsupported SignedData version", "version", 1) } if !sd.EncapContentInfo.IsTypeData() { - return SignedTRC{}, serrors.WrapStr("unsupported EncapContentInfo type", err, + return SignedTRC{}, serrors.Wrap("unsupported EncapContentInfo type", err, "type", sd.EncapContentInfo.EContentType) + } praw, err := sd.EncapContentInfo.EContentValue() if err != nil { - return SignedTRC{}, serrors.WrapStr("error reading raw payload", err) + return SignedTRC{}, serrors.Wrap("error reading raw payload", err) } trc, err := DecodeTRC(praw) if err != nil { - return SignedTRC{}, serrors.WrapStr("error parsing TRC payload", err) + return SignedTRC{}, serrors.Wrap("error parsing TRC payload", err) } return SignedTRC{Raw: raw, TRC: trc, SignerInfos: sd.SignerInfos}, nil } @@ -113,7 +114,7 @@ func (s *SignedTRC) verifyBase() error { return err } if err := s.verifyAll(detectNewVoters(classified{}, certs)); err != nil { - return serrors.WrapStr("verifying signatures for new voters", err) + return serrors.Wrap("verifying signatures for new voters", err) } return nil @@ -125,13 +126,13 @@ func (s *SignedTRC) verifyUpdate(predecessor *TRC) error { return err } if err := s.verifyAll(update.NewVoters); err != nil { - return serrors.WrapStr("verifying signatures by new voters", err, "type", update.Type) + return serrors.Wrap("verifying signatures by new voters", err, "type", update.Type) } if err := s.verifyAll(update.RootAcknowledgments); err != nil { - return serrors.WrapStr("verifying root acknowledgments", err, "type", update.Type) + return serrors.Wrap("verifying root acknowledgments", err, "type", update.Type) } if err := s.verifyAll(update.Votes); err != nil { - return serrors.WrapStr("verifying votes", err, "type", update.Type) + return serrors.Wrap("verifying votes", err, "type", update.Type) } return nil } diff --git a/pkg/scrypto/cppki/trc.go b/pkg/scrypto/cppki/trc.go index d59fbd64f0..a2398bdeb0 100644 --- a/pkg/scrypto/cppki/trc.go +++ b/pkg/scrypto/cppki/trc.go @@ -105,40 +105,42 @@ type TRC struct { // update restrictions. func (trc *TRC) Validate() error { if trc.Version != 1 { - return serrors.WithCtx(ErrInvalidTRCVersion, "expected", 1, "actual", trc.Version) + return serrors.JoinNoStack(ErrInvalidTRCVersion, nil, "expected", 1, "actual", trc.Version) } if err := trc.ID.Validate(); err != nil { - return serrors.Wrap(ErrInvalidID, err) + return serrors.JoinNoStack(ErrInvalidID, err) } if err := trc.Validity.Validate(); err != nil { return err } if trc.ID.IsBase() && trc.GracePeriod != 0 { - return serrors.WithCtx(ErrGracePeriodNonZero, "grace_period", trc.GracePeriod) + return serrors.JoinNoStack(ErrGracePeriodNonZero, nil, "grace_period", trc.GracePeriod) } if trc.ID.IsBase() && len(trc.Votes) != 0 { - return serrors.WithCtx(ErrVotesOnBaseTRC, "votes", len(trc.Votes)) + return serrors.JoinNoStack(ErrVotesOnBaseTRC, nil, "votes", len(trc.Votes)) } if trc.Quorum == 0 || trc.Quorum > 255 { - return serrors.WithCtx(ErrInvalidQuorumSize, "voting_quorum", trc.Quorum) + return serrors.JoinNoStack(ErrInvalidQuorumSize, nil, "voting_quorum", trc.Quorum) } if err := validateASSequence(trc.CoreASes); err != nil { - return serrors.WithCtx(err, "field", "coreASes") + return serrors.WrapNoStack("error", err, "field", "coreASes") } if err := validateASSequence(trc.AuthoritativeASes); err != nil { - return serrors.WithCtx(err, "field", "authoritativeASes") + return serrors.WrapNoStack("error", err, "field", "authoritativeASes") } cl, err := classifyCerts(trc.Certificates) if err != nil { return err } if len(cl.Sensitive) < trc.Quorum { - return serrors.WithCtx(ErrNotEnoughVoters, + return serrors.JoinNoStack(ErrNotEnoughVoters, nil, "sensitive_voters", len(cl.Sensitive), "quorum", trc.Quorum) + } if len(cl.Regular) < trc.Quorum { - return serrors.WithCtx(ErrNotEnoughVoters, + return serrors.JoinNoStack(ErrNotEnoughVoters, nil, "regular_voters", len(cl.Regular), "quorum", trc.Quorum) + } // Check all certificates for this ISD. for i, cert := range trc.Certificates { @@ -147,10 +149,11 @@ func (trc *TRC) Validate() error { return err } if ia != nil && ia.ISD() != trc.ID.ISD { - return serrors.WithCtx(ErrCertForOtherISD, "subject", cert.Subject, "index", i) + return serrors.JoinNoStack(ErrCertForOtherISD, nil, "subject", cert.Subject, "index", i) } if !(Validity{NotBefore: cert.NotBefore, NotAfter: cert.NotAfter}).Covers(trc.Validity) { - return serrors.WithCtx(ErrTRCValidityNotCovered, "subject", cert.Subject, "index", i) + return serrors.JoinNoStack(ErrTRCValidityNotCovered, nil, + "subject", cert.Subject, "index", i) } } // Check that issuer-SN pair is unique. @@ -161,7 +164,7 @@ func (trc *TRC) Validate() error { continue } if equalName(a.Issuer, b.Issuer) { - return serrors.WithCtx(ErrDuplicate, "indices", []int{i, j}) + return serrors.JoinNoStack(ErrDuplicate, nil, "indices", []int{i, j}) } } } @@ -271,11 +274,11 @@ func (trc *TRC) ValidateUpdate(predecessor *TRC) (Update, error) { } predCerts, err := classifyCerts(predecessor.Certificates) if err != nil { - return Update{}, serrors.WrapStr("classifying certificates in predecessor", err) + return Update{}, serrors.Wrap("classifying certificates in predecessor", err) } thisCerts, err := classifyCerts(trc.Certificates) if err != nil { - return Update{}, serrors.WrapStr("classifying certificates", err) + return Update{}, serrors.Wrap("classifying certificates", err) } // All votes in a regular update must be cast with a regular voting @@ -284,7 +287,7 @@ func (trc *TRC) ValidateUpdate(predecessor *TRC) (Update, error) { if _, ok := predCerts.Regular[trc.Votes[0]]; !ok { votes, err := trc.validateSensitive(predCerts) if err != nil { - return Update{}, serrors.WrapStr("validating sensitive update", err) + return Update{}, serrors.Wrap("validating sensitive update", err) } return Update{ Type: SensitiveUpdate, @@ -294,7 +297,7 @@ func (trc *TRC) ValidateUpdate(predecessor *TRC) (Update, error) { } votes, acks, err := trc.validateRegular(predecessor, predCerts, thisCerts) if err != nil { - return Update{}, serrors.WrapStr("validating regular update", err) + return Update{}, serrors.Wrap("validating regular update", err) } return Update{ Type: RegularUpdate, @@ -323,10 +326,10 @@ func (trc *TRC) validateRegular(predecessor *TRC, predCerts, thisCerts classifie return nil, nil, serrors.New("quorum changed", "predecessor", p, "this", n) } if err := equalASes(predecessor.CoreASes, trc.CoreASes); err != nil { - return nil, nil, serrors.WrapStr("core ASes changed", err) + return nil, nil, serrors.Wrap("core ASes changed", err) } if err := equalASes(predecessor.AuthoritativeASes, trc.AuthoritativeASes); err != nil { - return nil, nil, serrors.WrapStr("authoritative ASes changed", err) + return nil, nil, serrors.Wrap("authoritative ASes changed", err) } // Check all sensitive voting certificates are unchanged. @@ -432,7 +435,7 @@ func classifyCerts(certs []*x509.Certificate) (classified, error) { for i, cert := range certs { ct, err := ValidateCert(cert) if err != nil { - return classified{}, serrors.WithCtx(ErrUnclassifiedCertificate, "index", i) + return classified{}, serrors.JoinNoStack(ErrUnclassifiedCertificate, nil, "index", i) } switch ct { case Sensitive: @@ -442,7 +445,8 @@ func classifyCerts(certs []*x509.Certificate) (classified, error) { case Root: c.Root[i] = cert default: - return classified{}, serrors.WithCtx(ErrInvalidCertType, "cert_type", ct, "index", i) + return classified{}, serrors.JoinNoStack(ErrInvalidCertType, nil, + "cert_type", ct, "index", i) } } return c, nil @@ -501,7 +505,7 @@ func validateASSequence(ases []addr.AS) error { } for j := i + 1; j < len(ases); j++ { if as == ases[j] { - return serrors.WithCtx(ErrDuplicateAS, "as", as) + return serrors.JoinNoStack(ErrDuplicateAS, nil, "as", as) } } } @@ -518,7 +522,7 @@ func uniqueSubject(certs map[int]*x509.Certificate) error { for j := i + 1; j < len(l); j++ { b := l[j] if equalName(a.Subject, b.Subject) { - return serrors.WithCtx(ErrDuplicate, "indices", []int{idx[i], idx[j]}) + return serrors.JoinNoStack(ErrDuplicate, nil, "indices", []int{idx[i], idx[j]}) } } } diff --git a/pkg/scrypto/cppki/trc_asn1.go b/pkg/scrypto/cppki/trc_asn1.go index 517d720dbd..da8556dae4 100644 --- a/pkg/scrypto/cppki/trc_asn1.go +++ b/pkg/scrypto/cppki/trc_asn1.go @@ -67,23 +67,23 @@ func DecodeTRC(raw []byte) (TRC, error) { } certs, err := decodeCertificates(a.Certificates) if err != nil { - return TRC{}, serrors.WrapStr("error parsing certificates", err) + return TRC{}, serrors.Wrap("error parsing certificates", err) } cores, err := decodeASes(a.CoreASes) if err != nil { - return TRC{}, serrors.WrapStr("error parsing core ASes", err) + return TRC{}, serrors.Wrap("error parsing core ASes", err) } auths, err := decodeASes(a.AuthoritativeASes) if err != nil { - return TRC{}, serrors.WrapStr("error parsing authoritative ASes", err) + return TRC{}, serrors.Wrap("error parsing authoritative ASes", err) } id, err := decodeID(a.ID) if err != nil { - return TRC{}, serrors.WrapStr("error decoding ID", err) + return TRC{}, serrors.Wrap("error decoding ID", err) } validity, err := decodeValidity(a.Validity) if err != nil { - return TRC{}, serrors.WrapStr("invalid validity", err) + return TRC{}, serrors.Wrap("invalid validity", err) } pld := TRC{ Raw: raw, @@ -178,7 +178,7 @@ func decodeCertificates(rawCerts []asn1.RawValue) ([]*x509.Certificate, error) { for i, raw := range rawCerts { cert, err := x509.ParseCertificate(raw.FullBytes) if err != nil { - return nil, serrors.WrapStr("error decoding certificate", err, "index", i) + return nil, serrors.Wrap("error decoding certificate", err, "index", i) } certs = append(certs, cert) } @@ -202,10 +202,10 @@ func decodeASes(rawASes []string) ([]addr.AS, error) { for _, rawAs := range rawASes { as, err := addr.ParseAS(rawAs) if err != nil { - return nil, serrors.WrapStr("error parsing AS", err, "input", rawAs) + return nil, serrors.Wrap("error parsing AS", err, "input", rawAs) } if as == 0 { - return nil, serrors.WrapStr("wildcard AS", err) + return nil, serrors.Wrap("wildcard AS", err) } ases = append(ases, as) } diff --git a/pkg/scrypto/mac.go b/pkg/scrypto/mac.go index 4c4ce16bc2..589ca5cb22 100644 --- a/pkg/scrypto/mac.go +++ b/pkg/scrypto/mac.go @@ -38,11 +38,11 @@ var ( func InitMac(key []byte) (hash.Hash, error) { block, err := aes.NewCipher(key) if err != nil { - return nil, serrors.Wrap(ErrCipherFailure, err) + return nil, serrors.JoinNoStack(ErrCipherFailure, err) } mac, err := cmac.New(block) if err != nil { - return nil, serrors.Wrap(ErrMacFailure, err) + return nil, serrors.JoinNoStack(ErrMacFailure, err) } return mac, nil } diff --git a/pkg/scrypto/signed/msg.go b/pkg/scrypto/signed/msg.go index 387b3d20a1..0336d70efb 100644 --- a/pkg/scrypto/signed/msg.go +++ b/pkg/scrypto/signed/msg.go @@ -71,7 +71,7 @@ func Sign(hdr Header, body []byte, signer crypto.Signer, var err error ts, err = ptypes.TimestampProto(hdr.Timestamp) if err != nil { - return nil, serrors.WrapStr("converting timestamp", err) + return nil, serrors.Wrap("converting timestamp", err) } } @@ -84,7 +84,7 @@ func Sign(hdr Header, body []byte, signer crypto.Signer, } rawHdr, err := proto.Marshal(inputHdr) if err != nil { - return nil, serrors.WrapStr("packing header", err) + return nil, serrors.Wrap("packing header", err) } hdrAndBody := &cryptopb.HeaderAndBodyInternal{ Header: rawHdr, @@ -92,7 +92,7 @@ func Sign(hdr Header, body []byte, signer crypto.Signer, } rawHdrAndBody, err := proto.Marshal(hdrAndBody) if err != nil { - return nil, serrors.WrapStr("packing signature input", err) + return nil, serrors.Wrap("packing signature input", err) } input, algo := computeSignatureInput(hdr.SignatureAlgorithm, rawHdrAndBody, associatedData...) signature, err := signer.Sign(rand.Reader, input, algo) @@ -114,7 +114,7 @@ func Verify(signed *cryptopb.SignedMessage, key crypto.PublicKey, } hdr, body, err := extractHeaderAndBody(signed) if err != nil { - return nil, serrors.WrapStr("extracting header", err) + return nil, serrors.Wrap("extracting header", err) } if l := associatedDataLen(associatedData...); l != hdr.AssociatedDataLength { return nil, serrors.New("header specifies a different associated data length", diff --git a/pkg/segment/as.go b/pkg/segment/as.go index 4a18190b7e..7d03a24b90 100644 --- a/pkg/segment/as.go +++ b/pkg/segment/as.go @@ -68,7 +68,7 @@ func ASEntryFromPB(pb *cppb.ASEntry) (ASEntry, error) { } hopEntry, err := hopEntryFromPB(entry.HopEntry) if err != nil { - return ASEntry{}, serrors.WrapStr("parsing hop entry", err) + return ASEntry{}, serrors.Wrap("parsing hop entry", err) } var peerEntries []PeerEntry @@ -81,7 +81,7 @@ func ASEntryFromPB(pb *cppb.ASEntry) (ASEntry, error) { } peerEntry, err := peerEntryFromPB(peer) if err != nil { - return ASEntry{}, serrors.WrapStr("parsing peer entry", err, "index", i) + return ASEntry{}, serrors.Wrap("parsing peer entry", err, "index", i) } peerEntries = append(peerEntries, peerEntry) } diff --git a/pkg/segment/hop.go b/pkg/segment/hop.go index da2423e51f..ec6b528c12 100644 --- a/pkg/segment/hop.go +++ b/pkg/segment/hop.go @@ -44,7 +44,7 @@ func hopEntryFromPB(pb *cppb.HopEntry) (HopEntry, error) { } hop, err := hopFieldFromPB(pb.HopField) if err != nil { - return HopEntry{}, serrors.WrapStr("parsing hop field", err) + return HopEntry{}, serrors.Wrap("parsing hop field", err) } return HopEntry{ HopField: hop, @@ -83,7 +83,7 @@ func peerEntryFromPB(pb *cppb.PeerEntry) (PeerEntry, error) { } hop, err := hopFieldFromPB(pb.HopField) if err != nil { - return PeerEntry{}, serrors.WrapStr("parsing hop field", err) + return PeerEntry{}, serrors.Wrap("parsing hop field", err) } return PeerEntry{ HopField: hop, diff --git a/pkg/segment/seg.go b/pkg/segment/seg.go index a873b55b6d..9f8c6ec0b4 100644 --- a/pkg/segment/seg.go +++ b/pkg/segment/seg.go @@ -111,13 +111,13 @@ func BeaconFromPB(pb *cppb.PathSegment) (*PathSegment, error) { func segmentFromPB(pb *cppb.PathSegment) (*PathSegment, error) { info, err := infoFromRaw(pb.SegmentInfo) if err != nil { - return nil, serrors.WrapStr("parsing segment info", err) + return nil, serrors.Wrap("parsing segment info", err) } asEntries := make([]ASEntry, 0, len(pb.AsEntries)) for i, entry := range pb.AsEntries { as, err := ASEntryFromPB(entry) if err != nil { - return nil, serrors.WrapStr("parsing AS entry", err, "index", i) + return nil, serrors.Wrap("parsing AS entry", err, "index", i) } asEntries = append(asEntries, as) } @@ -293,11 +293,11 @@ func (ps *PathSegment) AddASEntry(ctx context.Context, asEntry ASEntry, signer S } rawASEntry, err := proto.Marshal(asEntryPB) if err != nil { - return serrors.WrapStr("packing AS entry", err) + return serrors.Wrap("packing AS entry", err) } signedMsg, err := signer.Sign(ctx, rawASEntry, ps.associatedData(len(ps.ASEntries))...) if err != nil { - return serrors.WrapStr("signing AS entry", err) + return serrors.Wrap("signing AS entry", err) } asEntry.Signed = signedMsg ps.ASEntries = append(ps.ASEntries, asEntry) @@ -308,7 +308,7 @@ func (ps *PathSegment) AddASEntry(ctx context.Context, asEntry ASEntry, signer S func (ps *PathSegment) Verify(ctx context.Context, verifier Verifier) error { for i := range ps.ASEntries { if err := ps.VerifyASEntry(ctx, verifier, i); err != nil { - return serrors.WrapStr("verifying AS entry", err, "idx", i) + return serrors.Wrap("verifying AS entry", err, "idx", i) } } return nil diff --git a/pkg/slayers/path/onehop/onehop.go b/pkg/slayers/path/onehop/onehop.go index 08c6998409..6f9e34078f 100644 --- a/pkg/slayers/path/onehop/onehop.go +++ b/pkg/slayers/path/onehop/onehop.go @@ -125,11 +125,11 @@ func (o *Path) ToSCIONDecoded() (*scion.Decoded, error) { func (o *Path) Reverse() (path.Path, error) { sp, err := o.ToSCIONDecoded() if err != nil { - return nil, serrors.WrapStr("converting to scion path", err) + return nil, serrors.Wrap("converting to scion path", err) } // increment the path, since we are at the receiver side. if err := sp.IncPath(); err != nil { - return nil, serrors.WrapStr("incrementing path", err) + return nil, serrors.Wrap("incrementing path", err) } return sp.Reverse() } diff --git a/pkg/snet/addrutil/addrutil.go b/pkg/snet/addrutil/addrutil.go index aa6e65c270..246ab37494 100644 --- a/pkg/snet/addrutil/addrutil.go +++ b/pkg/snet/addrutil/addrutil.go @@ -81,7 +81,7 @@ func (p Pather) GetPath(svc addr.SVC, ps *seg.PathSegment) (*snet.SVCAddr, error } path, err := snetpath.NewSCIONFromDecoded(dec) if err != nil { - return nil, serrors.WrapStr("serializing path", err) + return nil, serrors.Wrap("serializing path", err) } ifID := dec.HopFields[0].ConsIngress nextHop := p.NextHopper.UnderlayNextHop(ifID) diff --git a/pkg/snet/packet.go b/pkg/snet/packet.go index 31f7592398..c36c84778e 100644 --- a/pkg/snet/packet.go +++ b/pkg/snet/packet.go @@ -392,11 +392,11 @@ func (p *Packet) Decode() error { } dstAddr, err := scionLayer.DstAddr() if err != nil { - return serrors.WrapStr("extracting destination address", err) + return serrors.Wrap("extracting destination address", err) } srcAddr, err := scionLayer.SrcAddr() if err != nil { - return serrors.WrapStr("extracting source address", err) + return serrors.Wrap("extracting source address", err) } p.Destination = SCIONAddress{IA: scionLayer.DstIA, Host: dstAddr} p.Source = SCIONAddress{IA: scionLayer.SrcIA, Host: srcAddr} @@ -407,7 +407,7 @@ func (p *Packet) Decode() error { if l := scionLayer.Path.Len(); l != 0 { rpath.Raw = make([]byte, l) if err := scionLayer.Path.SerializeTo(rpath.Raw); err != nil { - return serrors.WrapStr("extracting path", err) + return serrors.Wrap("extracting path", err) } } p.Path = rpath @@ -566,10 +566,10 @@ func (p *Packet) Serialize() error { scionLayer.DstIA = p.Destination.IA scionLayer.SrcIA = p.Source.IA if err := scionLayer.SetDstAddr(p.Destination.Host); err != nil { - return serrors.WrapStr("setting destination address", err) + return serrors.Wrap("setting destination address", err) } if err := scionLayer.SetSrcAddr(p.Source.Host); err != nil { - return serrors.WrapStr("setting source address", err) + return serrors.Wrap("setting source address", err) } // XXX(roosd): Currently, this does not take the extension headers @@ -579,7 +579,7 @@ func (p *Packet) Serialize() error { // At this point all the fields in the SCION header apart from the path // and path type must be set already. if err := p.Path.SetPath(&scionLayer); err != nil { - return serrors.WrapStr("setting path", err) + return serrors.Wrap("setting path", err) } packetLayers = append(packetLayers, &scionLayer) diff --git a/pkg/snet/packet_conn.go b/pkg/snet/packet_conn.go index ef2a159f03..f8fd378929 100644 --- a/pkg/snet/packet_conn.go +++ b/pkg/snet/packet_conn.go @@ -140,13 +140,13 @@ func (c *SCIONPacketConn) Close() error { func (c *SCIONPacketConn) WriteTo(pkt *Packet, ov *net.UDPAddr) error { if err := pkt.Serialize(); err != nil { - return serrors.WrapStr("serialize SCION packet", err) + return serrors.Wrap("serialize SCION packet", err) } // Send message n, err := c.Conn.WriteTo(pkt.Bytes, ov) if err != nil { - return serrors.WrapStr("Reliable socket write error", err) + return serrors.Wrap("Reliable socket write error", err) } metrics.CounterAdd(c.Metrics.WriteBytes, float64(n)) metrics.CounterInc(c.Metrics.WritePackets) @@ -198,7 +198,7 @@ func (c *SCIONPacketConn) readFrom(pkt *Packet) (*net.UDPAddr, error) { n, remoteAddr, err := c.Conn.ReadFrom(pkt.Bytes) if err != nil { metrics.CounterInc(c.Metrics.UnderlayConnectionErrors) - return nil, serrors.WrapStr("reading underlay connection", err) + return nil, serrors.Wrap("reading underlay connection", err) } metrics.CounterAdd(c.Metrics.ReadBytes, float64(n)) metrics.CounterInc(c.Metrics.ReadPackets) @@ -206,7 +206,7 @@ func (c *SCIONPacketConn) readFrom(pkt *Packet) (*net.UDPAddr, error) { pkt.Bytes = pkt.Bytes[:n] if err := pkt.Decode(); err != nil { metrics.CounterInc(c.Metrics.ParseErrors) - return nil, serrors.WrapStr("decoding packet", err) + return nil, serrors.Wrap("decoding packet", err) } udpRemoteAddr := remoteAddr.(*net.UDPAddr) @@ -218,7 +218,7 @@ func (c *SCIONPacketConn) readFrom(pkt *Packet) (*net.UDPAddr, error) { // *loopback:30041* `SCIONPacketConn.lastHop()` should yield the right next hop address. lastHop, err = c.lastHop(pkt) if err != nil { - return nil, serrors.WrapStr("extracting last hop based on packet path", err) + return nil, serrors.Wrap("extracting last hop based on packet path", err) } } return lastHop, nil diff --git a/pkg/snet/packet_test.go b/pkg/snet/packet_test.go index 17c8bcd368..2f6820faab 100644 --- a/pkg/snet/packet_test.go +++ b/pkg/snet/packet_test.go @@ -240,7 +240,7 @@ func convertRawPath(r snet.RawPath) (snet.DataplanePath, error) { case onehop.PathType: p := onehop.Path{} if err := p.DecodeFromBytes(r.Raw); err != nil { - return nil, serrors.WrapStr("decoding ohp", err) + return nil, serrors.Wrap("decoding ohp", err) } return snetpath.OneHop{ Info: p.Info, diff --git a/pkg/snet/path/scion.go b/pkg/snet/path/scion.go index a146e4a7ee..7533e5a8ac 100644 --- a/pkg/snet/path/scion.go +++ b/pkg/snet/path/scion.go @@ -30,7 +30,7 @@ type SCION struct { func NewSCIONFromDecoded(d scion.Decoded) (SCION, error) { buf := make([]byte, d.Len()) if err := d.SerializeTo(buf); err != nil { - return SCION{}, serrors.WrapStr("serializing decoded SCION path", err) + return SCION{}, serrors.Wrap("serializing decoded SCION path", err) } return SCION{Raw: buf}, nil } diff --git a/pkg/snet/reader.go b/pkg/snet/reader.go index 06de4f5a38..3769918220 100644 --- a/pkg/snet/reader.go +++ b/pkg/snet/reader.go @@ -80,7 +80,7 @@ func (c *scionConnReader) read(b []byte) (int, *UDPAddr, error) { } replyPath, err := c.replyPather.ReplyPath(rpath) if err != nil { - return 0, nil, serrors.WrapStr("creating reply path", err) + return 0, nil, serrors.Wrap("creating reply path", err) } udp, ok := pkt.Payload.(UDPPayload) diff --git a/pkg/snet/reply_pather.go b/pkg/snet/reply_pather.go index 62e8e53d78..4f28223a0e 100644 --- a/pkg/snet/reply_pather.go +++ b/pkg/snet/reply_pather.go @@ -28,10 +28,10 @@ type DefaultReplyPather struct{} func (DefaultReplyPather) ReplyPath(rpath RawPath) (DataplanePath, error) { p, err := path.NewPath(rpath.PathType) if err != nil { - return nil, serrors.WrapStr("creating path", err, "type", rpath.PathType) + return nil, serrors.Wrap("creating path", err, "type", rpath.PathType) } if err := p.DecodeFromBytes(rpath.Raw); err != nil { - return nil, serrors.WrapStr("decoding path", err) + return nil, serrors.Wrap("decoding path", err) } // By default, reversing an EPIC path means getting a reversed SCION path. @@ -41,7 +41,7 @@ func (DefaultReplyPather) ReplyPath(rpath RawPath) (DataplanePath, error) { reversed, err := p.Reverse() if err != nil { - return nil, serrors.WrapStr("reversing path", err) + return nil, serrors.Wrap("reversing path", err) } return RawReplyPath{ Path: reversed, diff --git a/pkg/snet/snet.go b/pkg/snet/snet.go index 2abe8d61f2..cc4c13d503 100644 --- a/pkg/snet/snet.go +++ b/pkg/snet/snet.go @@ -213,6 +213,7 @@ func listenUDPRange(addr *net.UDPAddr, start, end uint16) (*net.UDPConn, error) } return nil, err } - return nil, serrors.WrapStr("binding to port range", syscall.EADDRINUSE, + return nil, serrors.Wrap("binding to port range", syscall.EADDRINUSE, "start", restrictedStart, "end", end) + } diff --git a/pkg/snet/squic/net.go b/pkg/snet/squic/net.go index 1994646392..a0ceaff412 100644 --- a/pkg/snet/squic/net.go +++ b/pkg/snet/squic/net.go @@ -395,23 +395,23 @@ func (d ConnDialer) Dial(ctx context.Context, dst net.Addr) (net.Conn, error) { } var transportErr *quic.TransportError if !errors.As(err, &transportErr) || transportErr.ErrorCode != quic.ConnectionRefused { - return nil, serrors.WrapStr("dialing QUIC/SCION", err) + return nil, serrors.Wrap("dialing QUIC/SCION", err) } jitter := time.Duration(mrand.Int63n(int64(5 * time.Millisecond))) select { case <-time.After(sleep + jitter): case <-ctx.Done(): - return nil, serrors.WrapStr("timed out connecting to busy server", err) + return nil, serrors.Wrap("timed out connecting to busy server", err) } } if err := ctx.Err(); err != nil { - return nil, serrors.WrapStr("dialing QUIC/SCION, after loop", err) + return nil, serrors.Wrap("dialing QUIC/SCION, after loop", err) } stream, err := session.OpenStreamSync(ctx) if err != nil { _ = session.CloseWithError(OpenStreamError, "") - return nil, serrors.WrapStr("opening stream", err) + return nil, serrors.Wrap("opening stream", err) } return &acceptedConn{ stream: stream, diff --git a/pkg/snet/udpaddr.go b/pkg/snet/udpaddr.go index 50a13cb8ce..5987cf1acd 100644 --- a/pkg/snet/udpaddr.go +++ b/pkg/snet/udpaddr.go @@ -91,21 +91,21 @@ func parseUDPAddrLegacy(s string) (*UDPAddr, error) { } ia, err := addr.ParseIA(rawIA) if err != nil { - return nil, serrors.WrapStr("invalid address: IA not parsable", err, "ia", ia) + return nil, serrors.Wrap("invalid address: IA not parsable", err, "ia", ia) } if ipOnly(rawHost) { addr, err := net.ResolveIPAddr("ip", strings.Trim(rawHost, "[]")) if err != nil { - return nil, serrors.WrapStr("invalid address: IP not resolvable", err) + return nil, serrors.Wrap("invalid address: IP not resolvable", err) } return &UDPAddr{IA: ia, Host: &net.UDPAddr{IP: addr.IP, Port: 0, Zone: addr.Zone}}, nil } udp, err := net.ResolveUDPAddr("udp", rawHost) if err != nil { - return nil, serrors.WrapStr("invalid address: host not parsable", err, "host", rawHost) + return nil, serrors.Wrap("invalid address: host not parsable", err, "host", rawHost) } if udp.IP == nil { - return nil, serrors.WrapStr("invalid address: ip not specified", err, "host", rawHost) + return nil, serrors.Wrap("invalid address: ip not specified", err, "host", rawHost) } return &UDPAddr{IA: ia, Host: udp}, nil } diff --git a/pkg/spao/mac.go b/pkg/spao/mac.go index 6ef8687f98..d5664f0400 100644 --- a/pkg/spao/mac.go +++ b/pkg/spao/mac.go @@ -94,11 +94,11 @@ func ComputeAuthCMAC( func initCMAC(key []byte) (hash.Hash, error) { block, err := aes.NewCipher(key) if err != nil { - return nil, serrors.WrapStr("unable to initialize AES cipher", err) + return nil, serrors.Wrap("unable to initialize AES cipher", err) } mac, err := cmac.New(block) if err != nil { - return nil, serrors.WrapStr("unable to initialize Mac", err) + return nil, serrors.Wrap("unable to initialize Mac", err) } return mac, nil } @@ -162,7 +162,7 @@ func serializeAuthenticatedData( func zeroOutMutablePath(orig path.Path, buf []byte) error { err := orig.SerializeTo(buf) if err != nil { - return serrors.WrapStr("serializing path for resetting fields", err) + return serrors.Wrap("serializing path for resetting fields", err) } switch p := orig.(type) { case empty.Path: diff --git a/private/app/appnet/addr.go b/private/app/appnet/addr.go index f659fbd410..8b75f44c08 100644 --- a/private/app/appnet/addr.go +++ b/private/app/appnet/addr.go @@ -66,7 +66,7 @@ func (r AddressRewriter) RedirectToQUIC(ctx context.Context, path, err := fa.GetPath() if err != nil { - return nil, serrors.WrapStr("bad path", err) + return nil, serrors.Wrap("bad path", err) } // During One-Hop Path operation, use SVC resolution to also bootstrap the path. @@ -116,7 +116,7 @@ func (r AddressRewriter) buildFullAddress(ctx context.Context, if len(p.Metadata().Interfaces) == 0 { //when local AS ov, err := r.SVCRouter.GetUnderlay(s.SVC) if err != nil { - return nil, serrors.WrapStr("Unable to resolve underlay", err) + return nil, serrors.Wrap("Unable to resolve underlay", err) } ret.NextHop = ov ret.Path = path.Empty{} diff --git a/private/app/appnet/infraenv.go b/private/app/appnet/infraenv.go index 7d86d39937..5531fa8291 100644 --- a/private/app/appnet/infraenv.go +++ b/private/app/appnet/infraenv.go @@ -111,7 +111,7 @@ func (nc *NetworkConfig) QUICStack() (*QUICStack, error) { listener, err := quic.Listen(server, serverTLSConfig, nil) if err != nil { - return nil, serrors.WrapStr("listening QUIC/SCION", err) + return nil, serrors.Wrap("listening QUIC/SCION", err) } insecureClientTLSConfig := &tls.Config{ @@ -152,7 +152,7 @@ func GenerateTLSConfig() (*tls.Config, error) { serialLimit := new(big.Int).Lsh(big.NewInt(1), 128) serial, err := rand.Int(rand.Reader, serialLimit) if err != nil { - return nil, serrors.WrapStr("creating random serial number", err) + return nil, serrors.Wrap("creating random serial number", err) } template := x509.Certificate{ @@ -217,7 +217,7 @@ func (nc *NetworkConfig) initQUICSockets() (net.PacketConn, net.PacketConn, erro svcResolutionReply, err := reply.Marshal() if err != nil { - return nil, nil, serrors.WrapStr("building SVC resolution reply", err) + return nil, nil, serrors.Wrap("building SVC resolution reply", err) } serverNet := &snet.SCIONNetwork{ @@ -230,7 +230,7 @@ func (nc *NetworkConfig) initQUICSockets() (net.PacketConn, net.PacketConn, erro } pconn, err := serverNet.OpenRaw(context.Background(), nc.Public) if err != nil { - return nil, nil, serrors.WrapStr("creating server raw PacketConn", err) + return nil, nil, serrors.Wrap("creating server raw PacketConn", err) } resolvedPacketConn := &svc.ResolverPacketConn{ PacketConn: pconn, @@ -244,7 +244,7 @@ func (nc *NetworkConfig) initQUICSockets() (net.PacketConn, net.PacketConn, erro } server, err := snet.NewCookedConn(resolvedPacketConn, nc.Topology) if err != nil { - return nil, nil, serrors.WrapStr("creating server connection", err) + return nil, nil, serrors.Wrap("creating server connection", err) } clientNet := &snet.SCIONNetwork{ @@ -264,7 +264,7 @@ func (nc *NetworkConfig) initQUICSockets() (net.PacketConn, net.PacketConn, erro } client, err := clientNet.Listen(context.Background(), "udp", clientAddr) if err != nil { - return nil, nil, serrors.WrapStr("creating client connection", err) + return nil, nil, serrors.Wrap("creating client connection", err) } return client, server, nil } @@ -295,7 +295,7 @@ func NewRouter(localIA addr.IA, sd env.Daemon) (snet.Router, error) { select { case <-ticker.C: case <-timer.C: - return nil, serrors.WrapStr("Timed out during initial daemon connect", err) + return nil, serrors.Wrap("Timed out during initial daemon connect", err) } } return router, nil diff --git a/private/app/env/env.go b/private/app/env/env.go index 8b3a743ab1..6037f3bf62 100644 --- a/private/app/env/env.go +++ b/private/app/env/env.go @@ -38,7 +38,7 @@ func (s *SCION) Validate() error { } for ia, as := range s.ASes { if err := as.Validate(); err != nil { - return serrors.WrapStr("validating AS", err, "isd-as", ia) + return serrors.Wrap("validating AS", err, "isd-as", ia) } } return nil diff --git a/private/app/flag/env.go b/private/app/flag/env.go index 9f5820fe00..fb863ebbc7 100644 --- a/private/app/flag/env.go +++ b/private/app/flag/env.go @@ -115,10 +115,10 @@ func (e *SCIONEnvironment) LoadExternalVars() error { defer e.mtx.Unlock() if err := e.loadFile(); err != nil { - return serrors.WrapStr("loading environment file", err) + return serrors.Wrap("loading environment file", err) } if err := e.loadEnv(); err != nil { - return serrors.WrapStr("loading environment variables", err) + return serrors.Wrap("loading environment variables", err) } return nil } @@ -137,10 +137,10 @@ func (e *SCIONEnvironment) loadFile() error { return nil } if err != nil { - return serrors.WrapStr("loading file", err) + return serrors.Wrap("loading file", err) } if err := json.Unmarshal(raw, &e.file); err != nil { - return serrors.WrapStr("parsing file", err) + return serrors.Wrap("parsing file", err) } return nil } @@ -156,7 +156,7 @@ func (e *SCIONEnvironment) loadEnv() error { if l, ok := os.LookupEnv("SCION_LOCAL_ADDR"); ok { a, err := netip.ParseAddr(l) if err != nil { - return serrors.WrapStr("parsing SCION_LOCAL_ADDR", err) + return serrors.Wrap("parsing SCION_LOCAL_ADDR", err) } e.localEnv = &a } diff --git a/private/app/launcher/launcher.go b/private/app/launcher/launcher.go index 6e9fd85e21..e1d7bf3923 100644 --- a/private/app/launcher/launcher.go +++ b/private/app/launcher/launcher.go @@ -163,13 +163,15 @@ func (a *Application) executeCommand(ctx context.Context, shortName string) erro a.config.SetConfigType("toml") a.config.SetConfigFile(a.config.GetString(cfgConfigFile)) if err := a.config.ReadInConfig(); err != nil { - return serrors.WrapStr("loading generic server config from file", err, + return serrors.Wrap("loading generic server config from file", err, "file", a.config.GetString(cfgConfigFile)) + } if err := libconfig.LoadFile(a.config.GetString(cfgConfigFile), a.TOMLConfig); err != nil { - return serrors.WrapStr("loading config from file", err, + return serrors.Wrap("loading config from file", err, "file", a.config.GetString(cfgConfigFile)) + } a.TOMLConfig.InitDefaults() @@ -187,13 +189,13 @@ func (a *Application) executeCommand(ctx context.Context, shortName string) erro }) if err := log.Setup(a.getLogging(), opt); err != nil { - return serrors.WrapStr("initialize logging", err) + return serrors.Wrap("initialize logging", err) } defer log.Flush() if a.RequiredIPs != nil { ips, err := a.RequiredIPs() if err != nil { - return serrors.WrapStr("loading required IPs", err) + return serrors.Wrap("loading required IPs", err) } WaitForNetworkReady(ctx, ips) } @@ -206,7 +208,7 @@ func (a *Application) executeCommand(ctx context.Context, shortName string) erro exportBuildInfo() prom.ExportElementID(a.config.GetString(cfgGeneralID)) if err := a.TOMLConfig.Validate(); err != nil { - return serrors.WrapStr("validate config", err) + return serrors.Wrap("validate config", err) } if a.Main == nil { diff --git a/private/app/path/path.go b/private/app/path/path.go index 3b34749a43..4edd9276ec 100644 --- a/private/app/path/path.go +++ b/private/app/path/path.go @@ -81,7 +81,7 @@ func Choose( o := applyOption(opts) paths, err := fetchPaths(ctx, conn, remote, o.refresh, o.seq) if err != nil { - return nil, serrors.WrapStr("fetching paths", err) + return nil, serrors.Wrap("fetching paths", err) } if o.epic { // Only use paths that support EPIC and intra-AS (empty) paths. @@ -104,7 +104,7 @@ func Choose( if o.probeCfg != nil { paths, err = filterUnhealthy(ctx, paths, remote, conn, o.probeCfg, o.epic) if err != nil { - return nil, serrors.WrapStr("probing paths", err) + return nil, serrors.Wrap("probing paths", err) } if len(paths) == 0 { return nil, serrors.New("no healthy paths available") @@ -147,7 +147,7 @@ func filterUnhealthy( Topology: sd, }.GetStatuses(subCtx, nonEmptyPaths, pathprobe.WithEPIC(epic)) if err != nil { - return nil, serrors.WrapStr("probing paths", err) + return nil, serrors.Wrap("probing paths", err) } // Filter all paths that aren't healthy. var healthyPaths []snet.Path @@ -174,7 +174,7 @@ func fetchPaths( allPaths, err := conn.Paths(ctx, remote, 0, daemon.PathReqFlags{Refresh: refresh}) if err != nil { - return nil, serrors.WrapStr("retrieving paths", err) + return nil, serrors.Wrap("retrieving paths", err) } paths, err := Filter(seq, allPaths) diff --git a/private/app/path/pathprobe/paths.go b/private/app/path/pathprobe/paths.go index 62df6c737a..757ac49cf8 100644 --- a/private/app/path/pathprobe/paths.go +++ b/private/app/path/pathprobe/paths.go @@ -198,11 +198,11 @@ func (p Prober) GetStatuses(ctx context.Context, paths []snet.Path, conn, err := sn.OpenRaw(ctx, &net.UDPAddr{IP: localIP.AsSlice()}) if err != nil { - return serrors.WrapStr("creating packet conn", err, "local", localIP) + return serrors.Wrap("creating packet conn", err, "local", localIP) } defer conn.Close() if err := conn.SetDeadline(deadline); err != nil { - return serrors.WrapStr("setting deadline", err) + return serrors.Wrap("setting deadline", err) } // Send probe for each path. @@ -214,7 +214,7 @@ func (p Prober) GetStatuses(ctx context.Context, paths []snet.Path, scionAlertPath, err := setAlertFlag(originalPath) if err != nil { - return serrors.WrapStr("setting alert flag", err) + return serrors.Wrap("setting alert flag", err) } var alertPath snet.DataplanePath if o.epic { @@ -266,7 +266,7 @@ func (p Prober) GetStatuses(ctx context.Context, paths []snet.Path, if errors.Is(err, os.ErrDeadlineExceeded) { break } - return serrors.WrapStr("waiting for probe reply", err, "local", localIP) + return serrors.Wrap("waiting for probe reply", err, "local", localIP) } } return nil @@ -288,7 +288,7 @@ func (p Prober) resolveLocalIP(target *net.UDPAddr) (net.IP, error) { } localIP, err := addrutil.ResolveLocal(target.IP) if err != nil { - return nil, serrors.WrapStr("resolving local IP", err) + return nil, serrors.Wrap("resolving local IP", err) } return localIP, nil } @@ -311,7 +311,7 @@ func (h *scmpHandler) Handle(pkt *snet.Packet) error { } replyPath, err := snet.DefaultReplyPather{}.ReplyPath(path) if err != nil { - return serrors.WrapStr("creating reply path", err) + return serrors.Wrap("creating reply path", err) } rawReplyPath, ok := replyPath.(snet.RawReplyPath) if !ok { @@ -321,7 +321,7 @@ func (h *scmpHandler) Handle(pkt *snet.Packet) error { Raw: make([]byte, rawReplyPath.Path.Len()), } if err := rawReplyPath.Path.SerializeTo(scionReplyPath.Raw); err != nil { - return serrors.WrapStr("serialization failed", err) + return serrors.Wrap("serialization failed", err) } status, err := h.toStatus(pkt) if err != nil { @@ -367,7 +367,7 @@ func (h *scmpHandler) toStatus(pkt *snet.Packet) (Status, error) { func setAlertFlag(original snetpath.SCION) (snetpath.SCION, error) { var decoded scion.Decoded if err := decoded.DecodeFromBytes(original.Raw); err != nil { - return snetpath.SCION{}, serrors.WrapStr("decoding path", err) + return snetpath.SCION{}, serrors.Wrap("decoding path", err) } if len(decoded.InfoFields) > 0 { info := decoded.InfoFields[len(decoded.InfoFields)-1] diff --git a/private/ca/renewal/ca_signer_gen.go b/private/ca/renewal/ca_signer_gen.go index 55f3cb30de..60aaff92b3 100644 --- a/private/ca/renewal/ca_signer_gen.go +++ b/private/ca/renewal/ca_signer_gen.go @@ -188,7 +188,7 @@ func (l LoadingPolicyGen) Generate(ctx context.Context) (cppki.CAPolicy, error) certs, err := l.CertProvider.CACerts(ctx) if err != nil { l.incCASigner("err_certs") - return cppki.CAPolicy{}, serrors.WrapStr("loading CA certificates", err) + return cppki.CAPolicy{}, serrors.Wrap("loading CA certificates", err) } if len(certs) == 0 { l.incCASigner("err_certs") @@ -243,22 +243,22 @@ type CACertLoader struct { // an active TRC. func (l CACertLoader) CACerts(ctx context.Context) ([]*x509.Certificate, error) { if _, err := os.Stat(l.Dir); err != nil { - return nil, serrors.WithCtx(err, "dir", l.Dir) + return nil, serrors.Wrap("stating directory", err, "dir", l.Dir) } files, err := filepath.Glob(fmt.Sprintf("%s/*.crt", l.Dir)) if err != nil { - return nil, serrors.WithCtx(err, "dir", l.Dir) + return nil, serrors.Wrap("searching for certificates", err, "dir", l.Dir) } trcs, err := activeTRCs(ctx, l.DB, l.IA.ISD()) if err != nil { - return nil, serrors.WrapStr("looking for active TRCs", err, "isd", l.IA.ISD()) + return nil, serrors.Wrap("looking for active TRCs", err, "isd", l.IA.ISD()) } rootPool := x509.NewCertPool() for _, trc := range trcs { certs, err := trc.TRC.RootCerts() if err != nil { - return nil, serrors.WrapStr("extracting root certs", err, "trc", trc.TRC.ID) + return nil, serrors.Wrap("extracting root certs", err, "trc", trc.TRC.ID) } for _, cert := range certs { rootPool.AddCert(cert) diff --git a/private/ca/renewal/grpc/delegating_handler.go b/private/ca/renewal/grpc/delegating_handler.go index 80e1e989a0..d0e1102e46 100644 --- a/private/ca/renewal/grpc/delegating_handler.go +++ b/private/ca/renewal/grpc/delegating_handler.go @@ -161,15 +161,15 @@ func (h *DelegatingHandler) parseChain(rep api.RenewalResponse) ([]*x509.Certifi func (h *DelegatingHandler) parseChainJSON(rep api.CertificateChain) ([]*x509.Certificate, error) { as, err := x509.ParseCertificate(rep.AsCertificate) if err != nil { - return nil, serrors.WrapStr("parsing AS certificate", err) + return nil, serrors.Wrap("parsing AS certificate", err) } ca, err := x509.ParseCertificate(rep.CaCertificate) if err != nil { - return nil, serrors.WrapStr("parsing CA certificate", err) + return nil, serrors.Wrap("parsing CA certificate", err) } chain := []*x509.Certificate{as, ca} if err := cppki.ValidateChain(chain); err != nil { - return nil, serrors.WrapStr("validating certificate chain", err) + return nil, serrors.Wrap("validating certificate chain", err) } return chain, nil } diff --git a/private/ca/renewal/grpc/renewal.go b/private/ca/renewal/grpc/renewal.go index 4ef96b3a0a..6172496477 100644 --- a/private/ca/renewal/grpc/renewal.go +++ b/private/ca/renewal/grpc/renewal.go @@ -104,11 +104,11 @@ func (s RenewalServer) ChainRenewal(ctx context.Context, func extractChain(raw []byte) ([]*x509.Certificate, error) { ci, err := protocol.ParseContentInfo(raw) if err != nil { - return nil, serrors.WrapStr("parsing ContentInfo", err) + return nil, serrors.Wrap("parsing ContentInfo", err) } sd, err := ci.SignedDataContent() if err != nil { - return nil, serrors.WrapStr("parsing SignedData", err) + return nil, serrors.Wrap("parsing SignedData", err) } return renewal.ExtractChain(sd) } diff --git a/private/ca/renewal/request.go b/private/ca/renewal/request.go index 95ed2cf939..35b7d8ee38 100644 --- a/private/ca/renewal/request.go +++ b/private/ca/renewal/request.go @@ -61,16 +61,16 @@ func (r RequestVerifier) VerifyCMSSignedRenewalRequest(ctx context.Context, ci, err := protocol.ParseContentInfo(req) if err != nil { - return nil, serrors.WrapStr("parsing ContentInfo", err) + return nil, serrors.Wrap("parsing ContentInfo", err) } sd, err := ci.SignedDataContent() if err != nil { - return nil, serrors.WrapStr("parsing SignedData", err) + return nil, serrors.Wrap("parsing SignedData", err) } chain, err := ExtractChain(sd) if err != nil { - return nil, serrors.WrapStr("extracting signing certificate chain", err) + return nil, serrors.Wrap("extracting signing certificate chain", err) } if err := r.VerifySignature(ctx, sd, chain); err != nil { @@ -79,12 +79,12 @@ func (r RequestVerifier) VerifyCMSSignedRenewalRequest(ctx context.Context, pld, err := sd.EncapContentInfo.EContentValue() if err != nil { - return nil, serrors.WrapStr("reading payload", err) + return nil, serrors.Wrap("reading payload", err) } csr, err := x509.ParseCertificateRequest(pld) if err != nil { - return nil, serrors.WrapStr("parsing CSR", err) + return nil, serrors.Wrap("parsing CSR", err) } return r.processCSR(csr, chain[0]) @@ -108,14 +108,14 @@ func (r RequestVerifier) VerifySignature( si := sd.SignerInfos[0] signer, err := si.FindCertificate(chain) if err != nil { - return serrors.WrapStr("selecting client certificate", err) + return serrors.Wrap("selecting client certificate", err) } if signer != chain[0] { return serrors.New("not signed with AS certificate", "common_name", signer.Subject.CommonName) } if err := r.verifyClientChain(ctx, chain); err != nil { - return serrors.WrapStr("verifying client chain", err) + return serrors.Wrap("verifying client chain", err) } if !sd.EncapContentInfo.IsTypeData() { @@ -124,11 +124,11 @@ func (r RequestVerifier) VerifySignature( } pld, err := sd.EncapContentInfo.EContentValue() if err != nil { - return serrors.WrapStr("reading payload", err) + return serrors.Wrap("reading payload", err) } if err := verifySignerInfo(pld, chain[0], si); err != nil { - return serrors.WrapStr("verifying signer info", err) + return serrors.Wrap("verifying signer info", err) } return nil @@ -146,7 +146,7 @@ func (r RequestVerifier) verifyClientChain(ctx context.Context, chain []*x509.Ce } trc, err := r.TRCFetcher.SignedTRC(ctx, tid) if err != nil { - return serrors.WrapStr("loading TRC to verify client chain", err) + return serrors.Wrap("loading TRC to verify client chain", err) } if trc.IsZero() { return serrors.New("TRC not found", "isd", ia.ISD()) @@ -160,12 +160,12 @@ func (r RequestVerifier) verifyClientChain(ctx context.Context, chain []*x509.Ce // If the the previous TRC is in grace period the CA certificate of the chain might // have been issued with a previous Root. Try verifying with the TRC in grace period. if now.After(trc.TRC.GracePeriodEnd()) { - return serrors.WrapStr("verifying client chain", err) + return serrors.Wrap("verifying client chain", err) } graceID := trc.TRC.ID graceID.Serial-- if err := r.verifyWithGraceTRC(ctx, now, graceID, chain); err != nil { - return serrors.WrapStr("verifying client chain with TRC in grace period "+ + return serrors.Wrap("verifying client chain with TRC in grace period "+ "after verification failure with latest TRC", err, "trc_id", trc.TRC.ID, "grace_trc_id", graceID, @@ -185,7 +185,7 @@ func (r RequestVerifier) verifyWithGraceTRC( trc, err := r.TRCFetcher.SignedTRC(ctx, id) if err != nil { - return serrors.WrapStr("loading TRC in grace period", err) + return serrors.Wrap("loading TRC in grace period", err) } if trc.IsZero() { return serrors.New("TRC in grace period not found") @@ -198,7 +198,7 @@ func (r RequestVerifier) verifyWithGraceTRC( } verifyOptions := cppki.VerifyOptions{TRC: []*cppki.TRC{&trc.TRC}} if err := cppki.VerifyChain(chain, verifyOptions); err != nil { - return serrors.WrapStr("verifying client chain", err) + return serrors.Wrap("verifying client chain", err) } return nil } @@ -230,18 +230,18 @@ func (r RequestVerifier) processCSR(csr *x509.CertificateRequest, csrIA, err := cppki.ExtractIA(csr.Subject) if err != nil { - return nil, serrors.WrapStr("extracting ISD-AS from CSR", err) + return nil, serrors.Wrap("extracting ISD-AS from CSR", err) } chainIA, err := cppki.ExtractIA(cert.Subject) if err != nil { - return nil, serrors.WrapStr("extracting ISD-AS from certificate chain", err) + return nil, serrors.Wrap("extracting ISD-AS from certificate chain", err) } if !csrIA.Equal(chainIA) { return nil, serrors.New("signing subject is different from CSR subject", "csr_isd_as", csrIA, "chain_isd_as", chainIA) } if err := csr.CheckSignature(); err != nil { - return nil, serrors.WrapStr("invalid CSR signature", err) + return nil, serrors.Wrap("invalid CSR signature", err) } return csr, nil } @@ -256,18 +256,18 @@ func ExtractChain(sd *protocol.SignedData) ([]*x509.Certificate, error) { } } if err != nil { - return nil, serrors.WrapStr("parsing certificate chain", err) + return nil, serrors.Wrap("parsing certificate chain", err) } certType, err := cppki.ValidateCert(certs[0]) if err != nil { - return nil, serrors.WrapStr("checking certificate type", err) + return nil, serrors.Wrap("checking certificate type", err) } if certType == cppki.CA { certs[0], certs[1] = certs[1], certs[0] } if err := cppki.ValidateChain(certs); err != nil { - return nil, serrors.WrapStr("validating chain", err) + return nil, serrors.Wrap("validating chain", err) } return certs, nil } diff --git a/private/config/config.go b/private/config/config.go index 212ecc6ae2..166bbdce4d 100644 --- a/private/config/config.go +++ b/private/config/config.go @@ -147,7 +147,7 @@ func (s StringSampler) ConfigName() string { func ValidateAll(validators ...Validator) error { for _, v := range validators { if err := v.Validate(); err != nil { - return serrors.WrapStr("Unable to validate", err, "type", fmt.Sprintf("%T", v)) + return serrors.Wrap("Unable to validate", err, "type", fmt.Sprintf("%T", v)) } } return nil @@ -228,14 +228,14 @@ func LoadResource(location string) (io.ReadCloser, error) { if strings.HasPrefix(location, "http://") || strings.HasPrefix(location, "https://") { response, err := http.Get(location) if err != nil { - return nil, serrors.WrapStr("fetching config over HTTP", err) + return nil, serrors.Wrap("fetching config over HTTP", err) } return response.Body, nil } rc, err := os.Open(location) if err != nil { - return nil, serrors.WrapStr("loading config from disk", err) + return nil, serrors.Wrap("loading config from disk", err) } return rc, nil } diff --git a/private/env/docker.go b/private/env/docker.go index e9a3256781..cdb7637009 100644 --- a/private/env/docker.go +++ b/private/env/docker.go @@ -26,7 +26,7 @@ import ( func RunsInDocker() (bool, error) { f, err := os.Open("/proc/self/cgroup") if err != nil { - return false, serrors.WrapStr("Failed to open /proc/self/cgroup", err) + return false, serrors.Wrap("Failed to open /proc/self/cgroup", err) } defer f.Close() scanner := bufio.NewScanner(f) diff --git a/private/env/env.go b/private/env/env.go index fdba5dc47f..f5aa34c16f 100644 --- a/private/env/env.go +++ b/private/env/env.go @@ -208,7 +208,7 @@ func (cfg *Metrics) ServePrometheus(ctx context.Context) error { }() err := server.ListenAndServe() if err != nil && !errors.Is(err, http.ErrServerClosed) { - return serrors.WrapStr("serving prometheus metrics", err) + return serrors.Wrap("serving prometheus metrics", err) } return nil } diff --git a/private/keyconf/keyconf.go b/private/keyconf/keyconf.go index 5acccbf2fd..32b91ae614 100644 --- a/private/keyconf/keyconf.go +++ b/private/keyconf/keyconf.go @@ -43,16 +43,16 @@ const ( func loadKey(file string, algo string) ([]byte, error) { b, err := os.ReadFile(file) if err != nil { - return nil, serrors.Wrap(ErrOpen, err) + return nil, serrors.JoinNoStack(ErrOpen, err) } dbuf := make([]byte, base64.StdEncoding.DecodedLen(len(b))) n, err := base64.StdEncoding.Decode(dbuf, b) if err != nil { - return nil, serrors.Wrap(ErrParse, err) + return nil, serrors.JoinNoStack(ErrParse, err) } dbuf = dbuf[:n] if strings.ToLower(algo) != RawKey { - return nil, serrors.WithCtx(ErrUnknown, "algo", algo) + return nil, serrors.JoinNoStack(ErrUnknown, nil, "algo", algo) } return dbuf, nil } diff --git a/private/mgmtapi/cppki/api/api.go b/private/mgmtapi/cppki/api/api.go index 3e0c13a8e8..fa514a0edb 100644 --- a/private/mgmtapi/cppki/api/api.go +++ b/private/mgmtapi/cppki/api/api.go @@ -58,7 +58,7 @@ func (s *Server) GetCertificates( if ia, err := addr.ParseIA(*params.IsdAs); err == nil { q.IA = ia } else { - errs = append(errs, serrors.WithCtx(err, "parameter", "isd_as")) + errs = append(errs, serrors.Wrap("parsing isd_as", err, "parameter", "isd_as")) } } if params.ValidAt != nil { diff --git a/private/mgmtapi/cppki/api/testdata/certificates-malformed.json b/private/mgmtapi/cppki/api/testdata/certificates-malformed.json index 1bdf82a991..7029a43241 100644 --- a/private/mgmtapi/cppki/api/testdata/certificates-malformed.json +++ b/private/mgmtapi/cppki/api/testdata/certificates-malformed.json @@ -1,5 +1,5 @@ { - "detail": "[ error {parameter=isd_as}: invalid ISD-AS {value=garbage} ]", + "detail": "[ parsing isd_as {parameter=isd_as}: invalid ISD-AS {value=garbage} ]", "status": 400, "title": "malformed query parameters", "type": "/problems/bad-request" diff --git a/private/mgmtapi/jwtauth/jwt.go b/private/mgmtapi/jwtauth/jwt.go index 50c045d574..7bfc9f9c10 100644 --- a/private/mgmtapi/jwtauth/jwt.go +++ b/private/mgmtapi/jwtauth/jwt.go @@ -86,7 +86,7 @@ type httpTransport struct { func (t *httpTransport) RoundTrip(req *http.Request) (*http.Response, error) { token, err := t.TokenSource.Token() if err != nil { - return nil, serrors.WrapStr("computing bearer token", err) + return nil, serrors.Wrap("computing bearer token", err) } req.Header.Set("Authorization", "Bearer "+token.String()) @@ -129,7 +129,7 @@ func (s *JWTTokenSource) Token() (*Token, error) { } key, err := s.Generator() if err != nil { - return nil, serrors.WrapStr("generating key", err) + return nil, serrors.Wrap("generating key", err) } if len(key) < 256/8 { return nil, serrors.New("refusing to sign, key must be at least 256 bits long", @@ -158,7 +158,7 @@ func (s *JWTTokenSource) Token() (*Token, error) { b, err := jwt.Sign(token, jwa.HS256, key) if err != nil { - return nil, serrors.WrapStr("signing token", err) + return nil, serrors.Wrap("signing token", err) } return &Token{ @@ -260,5 +260,5 @@ type KeyFunc func() ([]byte, error) func jwtSetError(claim string, err error) error { s := fmt.Sprintf("setting %v claim", claim) - return serrors.WrapStr(s, err) + return serrors.Wrap(s, err) } diff --git a/private/mgmtapi/segments/api/api.go b/private/mgmtapi/segments/api/api.go index 7a1b48f793..addd73f1cc 100644 --- a/private/mgmtapi/segments/api/api.go +++ b/private/mgmtapi/segments/api/api.go @@ -50,14 +50,14 @@ func (s *Server) GetSegments(w http.ResponseWriter, r *http.Request, params GetS if ia, err := addr.ParseIA(*params.StartIsdAs); err == nil { q.StartsAt = []addr.IA{ia} } else { - errs = append(errs, serrors.WrapStr("invalid start ISD_AS", err)) + errs = append(errs, serrors.Wrap("invalid start ISD_AS", err)) } } if params.EndIsdAs != nil { if ia, err := addr.ParseIA(*params.EndIsdAs); err == nil { q.EndsAt = []addr.IA{ia} } else { - errs = append(errs, serrors.WrapStr("invalid end ISD_AS", err)) + errs = append(errs, serrors.Wrap("invalid end ISD_AS", err)) } } if err := errs.ToError(); err != nil { diff --git a/private/mgmtapi/segments/api/api_test.go b/private/mgmtapi/segments/api/api_test.go index 052ad2b8ba..9020001da6 100644 --- a/private/mgmtapi/segments/api/api_test.go +++ b/private/mgmtapi/segments/api/api_test.go @@ -183,7 +183,7 @@ func TestAPI(t *testing.T) { } rawHdr, err := proto.Marshal(inputHdr) if err != nil { - return nil, serrors.WrapStr("packing header", err) + return nil, serrors.Wrap("packing header", err) } hdrAndBody := &cryptopb.HeaderAndBodyInternal{ Header: rawHdr, @@ -191,7 +191,7 @@ func TestAPI(t *testing.T) { } rawHdrAndBody, err := proto.Marshal(hdrAndBody) if err != nil { - return nil, serrors.WrapStr("packing signature input", err) + return nil, serrors.Wrap("packing signature input", err) } return &cryptopb.SignedMessage{ HeaderAndBody: rawHdrAndBody, diff --git a/private/path/pathpol/hop_pred.go b/private/path/pathpol/hop_pred.go index d1159b071c..28980c8296 100644 --- a/private/path/pathpol/hop_pred.go +++ b/private/path/pathpol/hop_pred.go @@ -49,7 +49,7 @@ func HopPredicateFromString(str string) (*HopPredicate, error) { dashParts := strings.Split(str, "-") isd, err := addr.ParseISD(dashParts[0]) if err != nil { - return &HopPredicate{}, serrors.WrapStr("Failed to parse ISD", err, "value", str) + return &HopPredicate{}, serrors.Wrap("Failed to parse ISD", err, "value", str) } if len(dashParts) == 1 { return &HopPredicate{ISD: isd, IfIDs: ifIDs}, nil @@ -58,7 +58,7 @@ func HopPredicateFromString(str string) (*HopPredicate, error) { hashParts := strings.Split(dashParts[1], "#") as, err := addr.ParseAS(hashParts[0]) if err != nil { - return &HopPredicate{}, serrors.WrapStr("Failed to parse AS", err, "value", str) + return &HopPredicate{}, serrors.Wrap("Failed to parse AS", err, "value", str) } if len(hashParts) == 1 { return &HopPredicate{ISD: isd, AS: as, IfIDs: ifIDs}, nil @@ -66,12 +66,12 @@ func HopPredicateFromString(str string) (*HopPredicate, error) { // Parse IfIDs if present commaParts := strings.Split(hashParts[1], ",") if ifIDs[0], err = parseIfID(commaParts[0]); err != nil { - return &HopPredicate{}, serrors.WrapStr("Failed to parse ifIDs", err, "value", str) + return &HopPredicate{}, serrors.Wrap("Failed to parse ifIDs", err, "value", str) } if len(commaParts) == 2 { ifID, err := parseIfID(commaParts[1]) if err != nil { - return &HopPredicate{}, serrors.WrapStr("Failed to parse ifIDs", err, "value", str) + return &HopPredicate{}, serrors.Wrap("Failed to parse ifIDs", err, "value", str) } ifIDs = append(ifIDs, ifID) } diff --git a/private/path/pathpol/sequence.go b/private/path/pathpol/sequence.go index 011bb2e088..ab178d87b4 100644 --- a/private/path/pathpol/sequence.go +++ b/private/path/pathpol/sequence.go @@ -70,8 +70,9 @@ func NewSequence(s string) (*Sequence, error) { re, err := regexp.Compile(restr) if err != nil { // This should never happen. Sequence parser should produce a valid regexp. - return nil, serrors.WrapStr("Error while parsing sequence regexp", err, + return nil, serrors.Wrap("Error while parsing sequence regexp", err, "regexp", restr) + } return &Sequence{re: re, srcstr: s, restr: restr}, nil } diff --git a/private/segment/segfetcher/fetcher.go b/private/segment/segfetcher/fetcher.go index 00c9526dbf..66ca014356 100644 --- a/private/segment/segfetcher/fetcher.go +++ b/private/segment/segfetcher/fetcher.go @@ -69,7 +69,7 @@ func (f *Fetcher) Fetch(ctx context.Context, reqs Requests, refresh bool) (Segme // Load local and cached segments from DB loadedSegs, fetchReqs, err := f.Resolver.Resolve(ctx, reqs, refresh) if err != nil { - return Segments{}, serrors.Wrap(errDB, err) + return Segments{}, serrors.JoinNoStack(errDB, err) } if len(fetchReqs) == 0 { return loadedSegs, nil @@ -77,7 +77,7 @@ func (f *Fetcher) Fetch(ctx context.Context, reqs Requests, refresh bool) (Segme // Forward and cache any requests that were not local / cached fetchedSegs, err := f.Request(ctx, fetchReqs) if err != nil { - err = serrors.Wrap(errFetch, err) + err = serrors.JoinNoStack(errFetch, err) } return append(loadedSegs, fetchedSegs...), err } @@ -113,7 +113,7 @@ func (f *Fetcher) waitOnProcessed(ctx context.Context, r := f.ReplyHandler.Handle(ctx, replyToRecs(reply.Segments), reply.Peer) if err := r.Err(); err != nil { f.Metrics.SegRequests(labels.WithResult(metrics.ErrProcess)).Inc() - return segs, serrors.WrapStr("processing reply", err) + return segs, serrors.Wrap("processing reply", err) } if len(r.VerificationErrors()) > 0 { log.FromCtx(ctx).Info("Errors during verification of segments/revocations", diff --git a/private/segment/segfetcher/grpc/requester.go b/private/segment/segfetcher/grpc/requester.go index 8ba9af0899..6f079478c6 100644 --- a/private/segment/segfetcher/grpc/requester.go +++ b/private/segment/segfetcher/grpc/requester.go @@ -77,7 +77,7 @@ func (f *Requester) Segments(ctx context.Context, req segfetcher.Request, ps, err := seg.SegmentFromPB(pb) if err != nil { return segfetcher.SegmentsReply{}, - serrors.WrapStr("parsing segments", err, "index", i) + serrors.Wrap("parsing segments", err, "index", i) } segs = append(segs, &seg.Meta{ Type: seg.Type(segType), diff --git a/private/segment/segfetcher/pather.go b/private/segment/segfetcher/pather.go index 4f045ac81a..8d8ce965ec 100644 --- a/private/segment/segfetcher/pather.go +++ b/private/segment/segfetcher/pather.go @@ -60,7 +60,7 @@ func (p *Pather) GetPaths(ctx context.Context, dst addr.IA, logger := log.FromCtx(ctx) if dst.ISD() == 0 { - return nil, serrors.WithCtx(ErrBadDst, "dst", dst) + return nil, serrors.JoinNoStack(ErrBadDst, nil, "dst", dst) } src := p.IA if dst.Equal(src) { diff --git a/private/segment/seghandler/seghandler.go b/private/segment/seghandler/seghandler.go index 4cf007295b..4ef3b25851 100644 --- a/private/segment/seghandler/seghandler.go +++ b/private/segment/seghandler/seghandler.go @@ -65,9 +65,9 @@ func (h *Handler) verifyAndStore(ctx context.Context, result.stats.verificationErrs(result.verifyErrs) switch { case err != nil: - result.err = serrors.Wrap(ErrDB, err) + result.err = serrors.JoinNoStack(ErrDB, err) case result.stats.SegVerifyErrors() == units: - result.err = serrors.Wrap(ErrVerification, result.verifyErrs.ToError()) + result.err = serrors.JoinNoStack(ErrVerification, result.verifyErrs.ToError()) } return result } diff --git a/private/segment/seghandler/seghandler_test.go b/private/segment/seghandler/seghandler_test.go index 6dc90bf382..93d976bf9a 100644 --- a/private/segment/seghandler/seghandler_test.go +++ b/private/segment/seghandler/seghandler_test.go @@ -73,9 +73,9 @@ func TestHandleAllVerificationsFail(t *testing.T) { verified := make(chan segverifier.UnitResult, 3) verifyErrs := []error{ - serrors.WrapStr("test err 1", segverifier.ErrSegment), - serrors.WrapStr("test err 2", segverifier.ErrSegment), - serrors.WrapStr("test err 3", segverifier.ErrSegment), + serrors.Wrap("test err 1", segverifier.ErrSegment), + serrors.Wrap("test err 2", segverifier.ErrSegment), + serrors.Wrap("test err 3", segverifier.ErrSegment), } storage := mock_seghandler.NewMockStorage(ctrl) diff --git a/private/segment/segverifier/segverifier.go b/private/segment/segverifier/segverifier.go index af8184f07e..e91502ab17 100644 --- a/private/segment/segverifier/segverifier.go +++ b/private/segment/segverifier/segverifier.go @@ -158,7 +158,8 @@ func VerifySegment(ctx context.Context, verifier infra.Verifier, server net.Addr } verifier := verifier.WithServer(server).WithIA(asEntry.Local).WithValidity(validity) if err := segment.VerifyASEntry(ctx, verifier, i); err != nil { - return serrors.Wrap(ErrSegment, err, "seg", segment.String(), "as", asEntry.Local) + return serrors.JoinNoStack(ErrSegment, err, + "seg", segment, "as", asEntry.Local) } } return nil diff --git a/private/service/statuspages.go b/private/service/statuspages.go index 12526494fe..98cd5f9d60 100644 --- a/private/service/statuspages.go +++ b/private/service/statuspages.go @@ -99,7 +99,7 @@ func (s StatusPages) Register(serveMux *http.ServeMux, elemId string) error { }) var mainBuf bytes.Buffer if err := t.Execute(&mainBuf, mainData{ElemId: elemId, Pages: pages}); err != nil { - return serrors.WrapStr("executing template", err) + return serrors.Wrap("executing template", err) } serveMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprint(w, mainBuf.String()) diff --git a/private/storage/beacon/sqlite/db.go b/private/storage/beacon/sqlite/db.go index 1ede0786d4..dc92b5a7a9 100644 --- a/private/storage/beacon/sqlite/db.go +++ b/private/storage/beacon/sqlite/db.go @@ -208,7 +208,7 @@ func (e *executor) GetBeacons( stmt, args := e.buildQuery(params) rows, err := e.db.QueryContext(ctx, stmt, args...) if err != nil { - return nil, serrors.WrapStr("looking up beacons", err, "query", stmt) + return nil, serrors.Wrap("looking up beacons", err, "query", stmt) } defer rows.Close() var res []storagebeacon.Beacon @@ -220,11 +220,11 @@ func (e *executor) GetBeacons( var InIfID uint16 err = rows.Scan(&RowID, &lastUpdated, &usage, &rawBeacon, &InIfID) if err != nil { - return nil, serrors.WrapStr("reading row", err) + return nil, serrors.Wrap("reading row", err) } seg, err := beacon.UnpackBeacon(rawBeacon) if err != nil { - return nil, serrors.WrapStr("parsing beacon", err) + return nil, serrors.Wrap("parsing beacon", err) } res = append(res, storagebeacon.Beacon{ Beacon: beacon.Beacon{ diff --git a/private/storage/db/errors.go b/private/storage/db/errors.go index 9f235e8346..1e027a1dd4 100644 --- a/private/storage/db/errors.go +++ b/private/storage/db/errors.go @@ -33,26 +33,26 @@ var ( ) func NewTxError(msg common.ErrMsg, err error, logCtx ...interface{}) error { - return serrors.Wrap(ErrTx, err, + return serrors.JoinNoStack(ErrTx, err, append([]interface{}{"detailMsg", msg}, logCtx...)...) } func NewInputDataError(msg common.ErrMsg, err error, logCtx ...interface{}) error { - return serrors.Wrap(ErrInvalidInputData, err, + return serrors.JoinNoStack(ErrInvalidInputData, err, append([]interface{}{"detailMsg", msg}, logCtx...)...) } func NewDataError(msg common.ErrMsg, err error, logCtx ...interface{}) error { - return serrors.Wrap(ErrDataInvalid, err, + return serrors.JoinNoStack(ErrDataInvalid, err, append([]interface{}{"detailMsg", msg}, logCtx...)...) } func NewReadError(msg common.ErrMsg, err error, logCtx ...interface{}) error { - return serrors.Wrap(ErrReadFailed, err, + return serrors.JoinNoStack(ErrReadFailed, err, append([]interface{}{"detailMsg", msg}, logCtx...)...) } func NewWriteError(msg common.ErrMsg, err error, logCtx ...interface{}) error { - return serrors.Wrap(ErrWriteFailed, err, + return serrors.JoinNoStack(ErrWriteFailed, err, append([]interface{}{"detailMsg", msg}, logCtx...)...) } diff --git a/private/storage/db/sqlite.go b/private/storage/db/sqlite.go index 5e0dde3f54..4c5bf694a4 100644 --- a/private/storage/db/sqlite.go +++ b/private/storage/db/sqlite.go @@ -48,8 +48,9 @@ func NewSqlite(path string, schema string, schemaVersion int) (*sql.DB, error) { var existingVersion int err = db.QueryRow("PRAGMA user_version;").Scan(&existingVersion) if err != nil { - return nil, serrors.WrapStr("Failed to check schema version", err, + return nil, serrors.Wrap("Failed to check schema version", err, "path", path) + } if existingVersion == 0 { if err = setup(db, schema, schemaVersion, path); err != nil { @@ -66,7 +67,7 @@ func open(path string) (*sql.DB, error) { var err error u, err := url.Parse(path) if err != nil { - return nil, serrors.WrapStr("invalid connection path", err, "path", path) + return nil, serrors.Wrap("invalid connection path", err, "path", path) } // Add foreign_key parameter to path to enable foreign key support. @@ -76,7 +77,7 @@ func open(path string) (*sql.DB, error) { path = u.String() db, err := sql.Open(driverName(), path) if err != nil { - return nil, serrors.WrapStr("Couldn't open SQLite database", err, "path", path) + return nil, serrors.Wrap("Couldn't open SQLite database", err, "path", path) } // On future errors, close the sql database before exiting defer func() { @@ -86,19 +87,22 @@ func open(path string) (*sql.DB, error) { }() // Make sure DB is reachable if err = db.Ping(); err != nil { - return nil, serrors.WrapStr("Initial DB ping failed, connection broken?", err, + return nil, serrors.Wrap("Initial DB ping failed, connection broken?", err, "path", path) + } // Ensure foreign keys are supported and enabled. var enabled bool err = db.QueryRow("PRAGMA foreign_keys;").Scan(&enabled) if err == sql.ErrNoRows { - return nil, serrors.WrapStr("Foreign keys not supported", err, + return nil, serrors.Wrap("Foreign keys not supported", err, "path", path) + } if err != nil { - return nil, serrors.WrapStr("Failed to check for foreign key support", err, + return nil, serrors.Wrap("Failed to check for foreign key support", err, "path", path) + } if !enabled { db.Close() @@ -111,12 +115,12 @@ func open(path string) (*sql.DB, error) { func setup(db *sql.DB, schema string, schemaVersion int, path string) error { _, err := db.Exec(schema) if err != nil { - return serrors.WrapStr("Failed to set up SQLite database", err, "path", path) + return serrors.Wrap("Failed to set up SQLite database", err, "path", path) } // Write schema version to database. _, err = db.Exec(fmt.Sprintf("PRAGMA user_version = %d", schemaVersion)) if err != nil { - return serrors.WrapStr("Failed to write schema version", err, "path", path) + return serrors.Wrap("Failed to write schema version", err, "path", path) } return nil } diff --git a/private/storage/path/sqlite/sqlite.go b/private/storage/path/sqlite/sqlite.go index 9c5094ed7e..7426d194bb 100644 --- a/private/storage/path/sqlite/sqlite.go +++ b/private/storage/path/sqlite/sqlite.go @@ -87,7 +87,7 @@ func (b *Backend) BeginTransaction(ctx context.Context, defer b.Unlock() tx, err := b.db.BeginTx(ctx, opts) if err != nil { - return nil, serrors.WrapStr("Failed to create transaction", err) + return nil, serrors.Wrap("Failed to create transaction", err) } return &transaction{ executor: &executor{ @@ -197,7 +197,7 @@ func get(ctx context.Context, tx *sql.Tx, segID []byte) (*segMeta, error) { return nil, nil } if err != nil { - return nil, serrors.WrapStr("Failed to lookup segment", err) + return nil, serrors.Wrap("Failed to lookup segment", err) } meta.LastUpdated = time.Unix(0, lastUpdated) meta.Seg, err = pathdb.UnpackSegment(rawSeg) @@ -253,7 +253,7 @@ func updateSeg(ctx context.Context, tx *sql.Tx, meta *segMeta) error { _, err = tx.ExecContext(ctx, stmtStr, fullID, meta.LastUpdated.UnixNano(), meta.Seg.Info.Timestamp, packedSeg, exp, meta.RowID) if err != nil { - return serrors.WrapStr("Failed to update segment", err) + return serrors.Wrap("Failed to update segment", err) } return nil } @@ -264,7 +264,7 @@ func insertType(ctx context.Context, tx *sql.Tx, segRowID int64, _, err := tx.ExecContext(ctx, "INSERT INTO SegTypes (SegRowID, Type) VALUES (?, ?)", segRowID, segType) if err != nil { - return serrors.WrapStr("Failed to insert type", err) + return serrors.Wrap("Failed to insert type", err) } return nil } @@ -278,7 +278,7 @@ func insertHPGroupID(ctx context.Context, tx *sql.Tx, segRowID int64, "INSERT INTO HPGroupIDs (SegRowID, GroupID) VALUES (?, ?)", segRowID, int64(hpGroupID)) if err != nil { - return serrors.WrapStr("Failed to insert hpGroupID", err) + return serrors.Wrap("Failed to insert hpGroupID", err) } return nil } @@ -302,11 +302,11 @@ func insertFull(ctx context.Context, tx *sql.Tx, pseg *seg.PathSegment, types [] res, err := tx.ExecContext(ctx, inst, segID, fullID, time.Now().UnixNano(), pseg.Info.Timestamp.UnixNano(), packedSeg, exp, st.ISD(), st.AS(), end.ISD(), end.AS()) if err != nil { - return serrors.WrapStr("Failed to insert path segment", err) + return serrors.Wrap("Failed to insert path segment", err) } segRowID, err := res.LastInsertId() if err != nil { - return serrors.WrapStr("Failed to retrieve segRowID of inserted segment", err) + return serrors.Wrap("Failed to retrieve segRowID of inserted segment", err) } // Insert all interfaces. if err = insertInterfaces(ctx, tx, pseg.ASEntries, segRowID); err != nil { @@ -336,7 +336,7 @@ func insertInterfaces(ctx context.Context, tx *sql.Tx, ases []seg.ASEntry, segRo stmtStr := `INSERT INTO IntfToSeg (IsdID, AsID, IntfID, SegRowID) VALUES (?, ?, ?, ?)` stmt, err := tx.PrepareContext(ctx, stmtStr) if err != nil { - return serrors.WrapStr("Failed to prepare insert into IntfToSeg", err) + return serrors.Wrap("Failed to prepare insert into IntfToSeg", err) } defer stmt.Close() for _, as := range ases { @@ -346,13 +346,13 @@ func insertInterfaces(ctx context.Context, tx *sql.Tx, ases []seg.ASEntry, segRo if hof.ConsIngress != 0 { _, err = stmt.ExecContext(ctx, ia.ISD(), ia.AS(), hof.ConsIngress, segRowID) if err != nil { - return serrors.WrapStr("inserting Ingress into IntfToSeg", err) + return serrors.Wrap("inserting Ingress into IntfToSeg", err) } } if hof.ConsEgress != 0 { _, err := stmt.ExecContext(ctx, ia.ISD(), ia.AS(), hof.ConsEgress, segRowID) if err != nil { - return serrors.WrapStr("inserting Egress into IntfToSeg", err) + return serrors.Wrap("inserting Egress into IntfToSeg", err) } } // Only insert the Egress interface for the regular hop entry in an AS entry. @@ -362,7 +362,7 @@ func insertInterfaces(ctx context.Context, tx *sql.Tx, ases []seg.ASEntry, segRo if hof.ConsIngress != 0 { _, err = stmt.ExecContext(ctx, ia.ISD(), ia.AS(), hof.ConsIngress, segRowID) if err != nil { - return serrors.WrapStr("insert peering Ingress into IntfToSeg", err, "index", i) + return serrors.Wrap("insert peering Ingress into IntfToSeg", err, "index", i) } } } @@ -405,7 +405,7 @@ func (e *executor) Get(ctx context.Context, params *query.Params) (query.Results stmt, args := e.buildQuery(params) rows, err := e.db.QueryContext(ctx, stmt, args...) if err != nil { - return nil, serrors.WrapStr("Error looking up path segment", err, "q", stmt) + return nil, serrors.Wrap("Error looking up path segment", err, "q", stmt) } defer rows.Close() var res []*query.Result @@ -418,11 +418,11 @@ func (e *executor) Get(ctx context.Context, params *query.Params) (query.Results if err = rows.Scan( &segRowID, &rawSeg, &lastUpdated, &segTypes, &hpGroupIDs); err != nil { - return nil, serrors.WrapStr("Error reading DB response", err) + return nil, serrors.Wrap("Error reading DB response", err) } parsed, err := pathdb.UnpackSegment(rawSeg) if err != nil { - return nil, serrors.WrapStr("unmarshalling segment", err) + return nil, serrors.Wrap("unmarshalling segment", err) } for _, t := range segTypes { res = append(res, &query.Result{ @@ -562,7 +562,7 @@ func (e *executor) InsertNextQuery(ctx context.Context, src, dst addr.IA, return err }) if err != nil { - return false, serrors.WrapStr("Failed to execute statement", err) + return false, serrors.Wrap("Failed to execute statement", err) } n, err := r.RowsAffected() return n > 0, err diff --git a/private/storage/trust/sqlite/db.go b/private/storage/trust/sqlite/db.go index 1e743b91f1..1cb02582dc 100644 --- a/private/storage/trust/sqlite/db.go +++ b/private/storage/trust/sqlite/db.go @@ -100,11 +100,11 @@ func (e *executor) SignedTRC(ctx context.Context, id cppki.TRCID) (cppki.SignedT return cppki.SignedTRC{}, nil } if err != nil { - return cppki.SignedTRC{}, serrors.Wrap(db.ErrReadFailed, err) + return cppki.SignedTRC{}, serrors.JoinNoStack(db.ErrReadFailed, err) } trc, err := cppki.DecodeSignedTRC(rawTRC) if err != nil { - return cppki.SignedTRC{}, serrors.Wrap(db.ErrDataInvalid, err) + return cppki.SignedTRC{}, serrors.JoinNoStack(db.ErrDataInvalid, err) } return trc, nil } @@ -128,11 +128,11 @@ func (e *executor) InsertTRC(ctx context.Context, trc cppki.SignedTRC) (bool, er trc.Raw, ) if err != nil { - return serrors.Wrap(db.ErrWriteFailed, err) + return serrors.JoinNoStack(db.ErrWriteFailed, err) } ar, err := r.RowsAffected() if err != nil { - return serrors.Wrap(db.ErrWriteFailed, err) + return serrors.JoinNoStack(db.ErrWriteFailed, err) } inserted = ar > 0 return nil @@ -177,25 +177,25 @@ func (e *executor) Chains(ctx context.Context, sqlQuery = append(sqlQuery, strings.Join(filters, " AND ")) rows, err := e.db.QueryContext(ctx, strings.Join(sqlQuery, "\n"), args...) if err != nil { - return nil, serrors.Wrap(db.ErrReadFailed, err) + return nil, serrors.JoinNoStack(db.ErrReadFailed, err) } defer rows.Close() var chains [][]*x509.Certificate for rows.Next() { if err := rows.Err(); err != nil { - return nil, serrors.Wrap(db.ErrReadFailed, err) + return nil, serrors.JoinNoStack(db.ErrReadFailed, err) } var rawAS, rawCA []byte if err := rows.Scan(&rawAS, &rawCA); err != nil { - return nil, serrors.Wrap(db.ErrReadFailed, err) + return nil, serrors.JoinNoStack(db.ErrReadFailed, err) } as, err := x509.ParseCertificate(rawAS) if err != nil { - return nil, serrors.Wrap(db.ErrDataInvalid, err) + return nil, serrors.JoinNoStack(db.ErrDataInvalid, err) } ca, err := x509.ParseCertificate(rawCA) if err != nil { - return nil, serrors.Wrap(db.ErrDataInvalid, err) + return nil, serrors.JoinNoStack(db.ErrDataInvalid, err) } chains = append(chains, []*x509.Certificate{as, ca}) } @@ -212,15 +212,15 @@ func (e *executor) Chain(ctx context.Context, var chain []*x509.Certificate var rawAS, rawCA []byte if err := r.Scan(&rawAS, &rawCA); err != nil { - return nil, serrors.Wrap(db.ErrReadFailed, err) + return nil, serrors.JoinNoStack(db.ErrReadFailed, err) } as, err := x509.ParseCertificate(rawAS) if err != nil { - return nil, serrors.Wrap(db.ErrDataInvalid, err) + return nil, serrors.JoinNoStack(db.ErrDataInvalid, err) } ca, err := x509.ParseCertificate(rawCA) if err != nil { - return nil, serrors.Wrap(db.ErrDataInvalid, err) + return nil, serrors.JoinNoStack(db.ErrDataInvalid, err) } chain = []*x509.Certificate{as, ca} return chain, nil @@ -231,13 +231,16 @@ func (e *executor) InsertChain(ctx context.Context, chain []*x509.Certificate) ( defer e.Unlock() if len(chain) != 2 { - return false, serrors.WithCtx(db.ErrInvalidInputData, "msg", "invalid chain length", + return false, serrors.JoinNoStack(db.ErrInvalidInputData, nil, + "msg", "invalid chain length", "expected", 2, "actual", len(chain)) + } ia, err := cppki.ExtractIA(chain[0].Subject) if err != nil { - return false, serrors.Wrap(db.ErrInvalidInputData, err, + return false, serrors.JoinNoStack(db.ErrInvalidInputData, err, "msg", "invalid AS cert, invalid ISD-AS") + } query := `INSERT INTO chains (isd_id, as_id, key_id, not_before, not_after, chain_fingerprint, as_cert, ca_cert) @@ -249,11 +252,11 @@ func (e *executor) InsertChain(ctx context.Context, chain []*x509.Certificate) ( chain[0].NotBefore.UTC(), chain[0].NotAfter.UTC(), truststorage.ChainID(chain), chain[0].Raw, chain[1].Raw) if err != nil { - return serrors.Wrap(db.ErrWriteFailed, err) + return serrors.JoinNoStack(db.ErrWriteFailed, err) } ar, err := r.RowsAffected() if err != nil { - return serrors.Wrap(db.ErrWriteFailed, err) + return serrors.JoinNoStack(db.ErrWriteFailed, err) } inserted = ar > 0 return nil @@ -302,7 +305,7 @@ func (e *executor) SignedTRCs(ctx context.Context, } rows, err := e.db.QueryContext(ctx, sqlQuery, args...) if err != nil { - return nil, serrors.Wrap(db.ErrReadFailed, err) + return nil, serrors.JoinNoStack(db.ErrReadFailed, err) } defer rows.Close() var res cppki.SignedTRCs @@ -314,7 +317,7 @@ func (e *executor) SignedTRCs(ctx context.Context, } curRes, err := cppki.DecodeSignedTRC(rawTRC) if err != nil { - return nil, serrors.Wrap(db.ErrDataInvalid, err) + return nil, serrors.JoinNoStack(db.ErrDataInvalid, err) } res = append(res, curRes) } diff --git a/private/svc/resolver.go b/private/svc/resolver.go index 8e32a3e910..e4af3741f9 100644 --- a/private/svc/resolver.go +++ b/private/svc/resolver.go @@ -86,7 +86,7 @@ func (r *Resolver) LookupSVC(ctx context.Context, p snet.Path, svc addr.SVC) (*R conn, err := r.Network.OpenRaw(ctx, u) if err != nil { ext.Error.Set(span, true) - return nil, serrors.Wrap(errRegistration, err) + return nil, serrors.JoinNoStack(errRegistration, err) } cancelF := ctxconn.CloseConnOnDone(ctx, conn) defer func() { @@ -161,7 +161,7 @@ func (roundTripper) RoundTrip(ctx context.Context, c snet.PacketConn, pkt *snet. return nil, ctx.Err() default: } - return nil, serrors.Wrap(errWrite, err) + return nil, serrors.JoinNoStack(errWrite, err) } var replyPacket snet.Packet @@ -172,16 +172,17 @@ func (roundTripper) RoundTrip(ctx context.Context, c snet.PacketConn, pkt *snet. return nil, ctx.Err() default: } - return nil, serrors.Wrap(errRead, err) + return nil, serrors.JoinNoStack(errRead, err) } udp, ok := replyPacket.Payload.(snet.UDPPayload) if !ok { - return nil, serrors.WithCtx(errUnsupportedPld, + return nil, serrors.JoinNoStack(errUnsupportedPld, nil, "type", common.TypeOf(replyPacket.Payload)) + } var reply Reply if err := reply.Unmarshal(udp.Payload); err != nil { - return nil, serrors.Wrap(errDecode, err) + return nil, serrors.JoinNoStack(errDecode, err) } rpath, ok := replyPacket.Path.(snet.RawPath) @@ -190,7 +191,7 @@ func (roundTripper) RoundTrip(ctx context.Context, c snet.PacketConn, pkt *snet. } replyPath, err := snet.DefaultReplyPather{}.ReplyPath(rpath) if err != nil { - return nil, serrors.WrapStr("creating reply path", err) + return nil, serrors.Wrap("creating reply path", err) } reply.ReturnPath = &path{ dataplane: replyPath, diff --git a/private/svc/svc.go b/private/svc/svc.go index c757538fe6..b6cc57810b 100644 --- a/private/svc/svc.go +++ b/private/svc/svc.go @@ -149,7 +149,7 @@ func (h *BaseHandler) reversePath(path snet.DataplanePath) (snet.DataplanePath, } replyPath, err := snet.DefaultReplyPather{}.ReplyPath(rpath) if err != nil { - return nil, serrors.WrapStr("creating reply path", err) + return nil, serrors.Wrap("creating reply path", err) } return replyPath, nil } diff --git a/private/topology/interface.go b/private/topology/interface.go index eb8d9879a2..ca61eb1597 100644 --- a/private/topology/interface.go +++ b/private/topology/interface.go @@ -246,7 +246,7 @@ func (t *topologyS) Multicast(svc addr.SVC) ([]*net.UDPAddr, error) { for _, name := range names { topoAddr, err := t.Topology.GetTopoAddr(name, st) if err != nil { - return nil, serrors.Wrap(addr.ErrUnsupportedSVCAddress, err, "svc", svc) + return nil, serrors.JoinNoStack(addr.ErrUnsupportedSVCAddress, err, "svc", svc) } addrs = append(addrs, &net.UDPAddr{ IP: topoAddr.SCIONAddress.IP, @@ -264,12 +264,13 @@ func (t *topologyS) UnderlayAnycast(svc addr.SVC) (*net.UDPAddr, error) { if supportedSVC(svc) { return nil, serrors.New("no instances found for service", "svc", svc) } - return nil, serrors.WithCtx(addr.ErrUnsupportedSVCAddress, "svc", svc) + return nil, serrors.JoinNoStack(addr.ErrUnsupportedSVCAddress, nil, "svc", svc) } underlay, err := t.underlayByName(svc, name) if err != nil { - return nil, serrors.WrapStr("BUG! Selected random service name, but service info not found", + return nil, serrors.Wrap("BUG! Selected random service name, but service info not found", err, "service_names", names, "selected_name", name) + } // FIXME(scrye): This should return net.Addr return underlay, nil @@ -287,7 +288,7 @@ func (t *topologyS) UnderlayMulticast(svc addr.SVC) ([]*net.UDPAddr, error) { } topoAddrs, err := t.Topology.getAllTopoAddrs(st) if err != nil { - return nil, serrors.Wrap(addr.ErrUnsupportedSVCAddress, err, "svc", svc) + return nil, serrors.JoinNoStack(addr.ErrUnsupportedSVCAddress, err, "svc", svc) } if len(topoAddrs) == 0 { @@ -319,7 +320,7 @@ func (t *topologyS) underlayByName(svc addr.SVC, name string) (*net.UDPAddr, err } topoAddr, err := t.Topology.GetTopoAddr(name, st) if err != nil { - return nil, serrors.Wrap(addr.ErrUnsupportedSVCAddress, err, "svc", svc) + return nil, serrors.JoinNoStack(addr.ErrUnsupportedSVCAddress, err, "svc", svc) } underlayAddr := topoAddr.UnderlayAddr() if underlayAddr == nil { @@ -335,7 +336,7 @@ func toServiceType(svc addr.SVC) (ServiceType, error) { case addr.SvcCS: return Control, nil default: - return 0, serrors.WithCtx(addr.ErrUnsupportedSVCAddress, "svc", svc) + return 0, serrors.JoinNoStack(addr.ErrUnsupportedSVCAddress, nil, "svc", svc) } } diff --git a/private/topology/json/json.go b/private/topology/json/json.go index 5c4ebc273b..f620d51e83 100644 --- a/private/topology/json/json.go +++ b/private/topology/json/json.go @@ -149,7 +149,7 @@ func (i BRInfo) String() string { func Load(b []byte) (*Topology, error) { rt := &Topology{} if err := json.Unmarshal(b, rt); err != nil { - return nil, serrors.WrapStr("unable to parse topology from JSON", err) + return nil, serrors.Wrap("unable to parse topology from JSON", err) } return rt, nil } @@ -158,7 +158,7 @@ func Load(b []byte) (*Topology, error) { func LoadFromFile(path string) (*Topology, error) { b, err := os.ReadFile(path) if err != nil { - return nil, serrors.WrapStr("unable to open topology", err, "path", path) + return nil, serrors.Wrap("unable to open topology", err, "path", path) } return Load(b) } diff --git a/private/topology/raw.go b/private/topology/raw.go index b4353b1b1e..2f9f2b8987 100644 --- a/private/topology/raw.go +++ b/private/topology/raw.go @@ -55,12 +55,12 @@ func rawBRIntfLocalAddr(u *jsontopo.Underlay) (netip.AddrPort, error) { func resolveAddrPortOrPort(s string) (netip.AddrPort, error) { rh, rp, err := net.SplitHostPort(s) if err != nil { - return netip.AddrPort{}, serrors.WrapStr("failed to split host port", err) + return netip.AddrPort{}, serrors.Wrap("failed to split host port", err) } if rh == "" { port, err := strconv.ParseUint(rp, 10, 16) if err != nil { - return netip.AddrPort{}, serrors.WrapStr("failed to parse port", err) + return netip.AddrPort{}, serrors.Wrap("failed to parse port", err) } return netip.AddrPortFrom(netip.Addr{}, uint16(port)), nil } diff --git a/private/topology/reload.go b/private/topology/reload.go index 37a2cf4251..e5ff58c2fc 100644 --- a/private/topology/reload.go +++ b/private/topology/reload.go @@ -286,7 +286,7 @@ func (l *Loader) reload() error { newTopo, err := l.load() if err != nil { metrics.CounterInc(l.cfg.Metrics.ReadErrors) - return serrors.WrapStr("loading topology", err) + return serrors.Wrap("loading topology", err) } l.mtx.Lock() @@ -299,7 +299,7 @@ func (l *Loader) reload() error { if err := l.validate(newTopo.Writable(), old); err != nil { metrics.CounterInc(l.cfg.Metrics.ValidationErrors) - return serrors.WrapStr("validating update", err) + return serrors.Wrap("validating update", err) } l.topo = newTopo metrics.CounterInc(l.cfg.Metrics.Updates) diff --git a/private/topology/topology.go b/private/topology/topology.go index f7646112bd..ef1234a602 100644 --- a/private/topology/topology.go +++ b/private/topology/topology.go @@ -180,7 +180,7 @@ func RWTopologyFromJSONBytes(b []byte) (*RWTopology, error) { } ct, err := RWTopologyFromJSONTopology(rt) if err != nil { - return nil, serrors.WrapStr("unable to convert raw topology to topology", err) + return nil, serrors.Wrap("unable to convert raw topology to topology", err) } return ct, nil } @@ -262,7 +262,7 @@ func (t *RWTopology) populateBR(raw *jsontopo.Topology) error { } intAddr, err := resolveAddrPort(rawBr.InternalAddr) if err != nil { - return serrors.WrapStr("unable to extract underlay internal data-plane address", err) + return serrors.Wrap("unable to extract underlay internal data-plane address", err) } brInfo := BRInfo{ Name: name, @@ -310,12 +310,14 @@ func (t *RWTopology) populateBR(raw *jsontopo.Topology) error { continue } if ifinfo.Local, err = rawBRIntfLocalAddr(&rawIntf.Underlay); err != nil { - return serrors.WrapStr("unable to extract "+ + return serrors.Wrap("unable to extract "+ "underlay external data-plane local address", err) + } if ifinfo.Remote, err = resolveAddrPort(rawIntf.Underlay.Remote); err != nil { - return serrors.WrapStr("unable to extract "+ + return serrors.Wrap("unable to extract "+ "underlay external data-plane remote address", err) + } brInfo.IFs[ifID] = &ifinfo t.IFInfoMap[ifID] = ifinfo @@ -332,23 +334,23 @@ func (t *RWTopology) populateServices(raw *jsontopo.Topology) error { var err error t.CS, err = svcMapFromRaw(raw.ControlService) if err != nil { - return serrors.WrapStr("unable to extract CS address", err) + return serrors.Wrap("unable to extract CS address", err) } t.SIG, err = gatewayMapFromRaw(raw.SIG) if err != nil { - return serrors.WrapStr("unable to extract SIG address", err) + return serrors.Wrap("unable to extract SIG address", err) } t.DS, err = svcMapFromRaw(raw.DiscoveryService) if err != nil { - return serrors.WrapStr("unable to extract DS address", err) + return serrors.Wrap("unable to extract DS address", err) } t.HiddenSegmentLookup, err = svcMapFromRaw(raw.HiddenSegmentLookup) if err != nil { - return serrors.WrapStr("unable to extract hidden segment lookup address", err) + return serrors.Wrap("unable to extract hidden segment lookup address", err) } t.HiddenSegmentRegistration, err = svcMapFromRaw(raw.HiddenSegmentReg) if err != nil { - return serrors.WrapStr("unable to extract hidden segment registration address", err) + return serrors.Wrap("unable to extract hidden segment registration address", err) } return nil } @@ -512,8 +514,9 @@ func svcMapFromRaw(ras map[string]*jsontopo.ServerInfo) (IDAddrMap, error) { for name, svc := range ras { a, err := resolveAddrPort(svc.Addr) if err != nil { - return nil, serrors.WrapStr("could not parse address", err, + return nil, serrors.Wrap("could not parse address", err, "address", svc.Addr, "process_name", name) + } svcTopoAddr := &TopoAddr{ SCIONAddress: net.UDPAddrFromAddrPort(a), @@ -529,13 +532,15 @@ func gatewayMapFromRaw(ras map[string]*jsontopo.GatewayInfo) (map[string]Gateway for name, svc := range ras { c, err := resolveAddrPort(svc.CtrlAddr) if err != nil { - return nil, serrors.WrapStr("could not parse control address", err, + return nil, serrors.Wrap("could not parse control address", err, "address", svc.CtrlAddr, "process_name", name) + } d, err := resolveAddrPort(svc.DataAddr) if err != nil { - return nil, serrors.WrapStr("could not parse data address", err, + return nil, serrors.Wrap("could not parse data address", err, "address", svc.DataAddr, "process_name", name) + } // backward compatibility: if no probe address is specified just use the // default (ctrl address & port 30856): @@ -543,8 +548,9 @@ func gatewayMapFromRaw(ras map[string]*jsontopo.GatewayInfo) (map[string]Gateway if svc.ProbeAddr != "" { probeAddr, err = resolveAddrPort(svc.ProbeAddr) if err != nil { - return nil, serrors.WrapStr("could not parse probe address", err, + return nil, serrors.Wrap("could not parse probe address", err, "address", svc.ProbeAddr, "process_name", name) + } } diff --git a/private/trust/db_inspector.go b/private/trust/db_inspector.go index f2f50a42de..ed523d31d6 100644 --- a/private/trust/db_inspector.go +++ b/private/trust/db_inspector.go @@ -78,7 +78,7 @@ func (i DBInspector) trcAttrs(ctx context.Context, isd addr.ISD) (map[addr.IA]At Serial: scrypto.LatestVer, }) if err != nil { - return nil, serrors.WrapStr("failed to load TRC from DB", err) + return nil, serrors.Wrap("failed to load TRC from DB", err) } if sTRC.IsZero() { return nil, serrors.New("TRC not found") @@ -104,13 +104,13 @@ func (i DBInspector) trcAttrs(ctx context.Context, isd addr.ISD) (map[addr.IA]At func rootIAs(trc cppki.TRC) ([]addr.IA, error) { roots, err := trc.RootCerts() if err != nil { - return nil, serrors.WrapStr("failed to extract root certs", err) + return nil, serrors.Wrap("failed to extract root certs", err) } rootIAs := make([]addr.IA, 0, len(roots)) for _, c := range roots { ia, err := cppki.ExtractIA(c.Subject) if err != nil { - return nil, serrors.WrapStr("failed to extract IA from root cert", err) + return nil, serrors.Wrap("failed to extract IA from root cert", err) } rootIAs = append(rootIAs, ia) } diff --git a/private/trust/fetching_provider.go b/private/trust/fetching_provider.go index 9df9e52871..ff891d8187 100644 --- a/private/trust/fetching_provider.go +++ b/private/trust/fetching_provider.go @@ -96,7 +96,7 @@ func (p FetchingProvider) GetChains(ctx context.Context, query ChainQuery, logger.Info("Failed to get chain from database", "query", query, "err", err) setProviderMetric(span, l.WithResult(metrics.ErrDB), err) - return nil, serrors.WrapStr("fetching chains from database", err) + return nil, serrors.Wrap("fetching chains from database", err) } if o.allowInactive && len(chains) > 0 { @@ -109,7 +109,7 @@ func (p FetchingProvider) GetChains(ctx context.Context, query ChainQuery, logger.Info("Failed to get TRC for chain verification", "isd", query.IA.ISD(), "err", err) setProviderMetric(span, l.WithResult(result), err) - return nil, serrors.WrapStr("fetching active TRCs from database", err) + return nil, serrors.Wrap("fetching active TRCs from database", err) } chains = filterVerifiableChains(chains, trcs) @@ -122,17 +122,17 @@ func (p FetchingProvider) GetChains(ctx context.Context, query ChainQuery, // recursion is allowed. if err := p.Recurser.AllowRecursion(o.client); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrNotAllowed), err) - return nil, serrors.WrapStr("checking whether recursion is allowed", err) + return nil, serrors.Wrap("checking whether recursion is allowed", err) } if o.server == nil { if o.server, err = p.Router.ChooseServer(ctx, query.IA.ISD()); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrInternal), err) - return nil, serrors.WrapStr("choosing server", err) + return nil, serrors.Wrap("choosing server", err) } } if chains, err = p.Fetcher.Chains(ctx, query, o.server); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrInternal), err) - return nil, serrors.WrapStr("fetching chains from remote", err, "server", o.server) + return nil, serrors.Wrap("fetching chains from remote", err, "server", o.server) } // For simplicity, we ignore non-verifiable chains. @@ -142,7 +142,7 @@ func (p FetchingProvider) GetChains(ctx context.Context, query ChainQuery, for _, chain := range chains { if _, err := p.DB.InsertChain(ctx, chain); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrInternal), err) - return nil, serrors.WrapStr("inserting chain into database", err) + return nil, serrors.Wrap("inserting chain into database", err) } } } @@ -203,12 +203,12 @@ func (p FetchingProvider) NotifyTRC(ctx context.Context, id cppki.TRCID, opts .. } if err := p.Recurser.AllowRecursion(o.client); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrNotAllowed), err) - return serrors.WrapStr("recursion not allowed", err) + return serrors.Wrap("recursion not allowed", err) } if o.server == nil { if o.server, err = p.Router.ChooseServer(ctx, id.ISD); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrInternal), err) - return serrors.WrapStr("choosing server", err) + return serrors.Wrap("choosing server", err) } } // In general, we expect only one TRC update missing, thus sequential @@ -218,15 +218,15 @@ func (p FetchingProvider) NotifyTRC(ctx context.Context, id cppki.TRCID, opts .. fetched, err := p.Fetcher.TRC(ctx, toFetch, o.server) if err != nil { setProviderMetric(span, l.WithResult(metrics.ErrInternal), err) - return serrors.WrapStr("resolving TRC update", err, "id", toFetch) + return serrors.Wrap("resolving TRC update", err, "id", toFetch) } if err := fetched.Verify(&trc.TRC); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrVerify), err) - return serrors.WrapStr("verifying TRC update", err, "id", toFetch) + return serrors.Wrap("verifying TRC update", err, "id", toFetch) } if _, err := p.DB.InsertTRC(ctx, fetched); err != nil { setProviderMetric(span, l.WithResult(metrics.ErrInternal), err) - return serrors.WrapStr("inserting TRC update", err, "id", toFetch) + return serrors.Wrap("inserting TRC update", err, "id", toFetch) } trc = fetched } diff --git a/private/trust/grpc/fetcher.go b/private/trust/grpc/fetcher.go index f5c04cc149..b716ef0992 100644 --- a/private/trust/grpc/fetcher.go +++ b/private/trust/grpc/fetcher.go @@ -72,14 +72,14 @@ func (f Fetcher) Chains(ctx context.Context, query trust.ChainQuery, conn, err := f.Dialer.Dial(ctx, server) if err != nil { f.updateMetric(span, labels.WithResult(trustmetrics.ErrTransmit), err) - return nil, serrors.WrapStr("dialing", err) + return nil, serrors.Wrap("dialing", err) } defer conn.Close() client := cppb.NewTrustMaterialServiceClient(conn) rep, err := client.Chains(ctx, chainQueryToReq(query), grpc.RetryProfile...) if err != nil { f.updateMetric(span, labels.WithResult(trustmetrics.ErrTransmit), err) - return nil, serrors.WrapStr("receiving chains", err) + return nil, serrors.Wrap("receiving chains", err) } chains, res, err := repToChains(rep.Chains) @@ -94,7 +94,7 @@ func (f Fetcher) Chains(ctx context.Context, query trust.ChainQuery, if err := checkChainsMatchQuery(query, chains); err != nil { f.updateMetric(span, labels.WithResult(trustmetrics.ErrMismatch), err) - return nil, serrors.WrapStr("chains do not match query", err) + return nil, serrors.Wrap("chains do not match query", err) } f.updateMetric(span, labels.WithResult(trustmetrics.Success), nil) return chains, nil @@ -118,20 +118,20 @@ func (f Fetcher) TRC(ctx context.Context, id cppki.TRCID, conn, err := f.Dialer.Dial(ctx, server) if err != nil { f.updateMetric(span, labels.WithResult(trustmetrics.ErrTransmit), err) - return cppki.SignedTRC{}, serrors.WrapStr("dialing", err) + return cppki.SignedTRC{}, serrors.Wrap("dialing", err) } defer conn.Close() client := cppb.NewTrustMaterialServiceClient(conn) rep, err := client.TRC(ctx, idToReq(id), grpc.RetryProfile...) if err != nil { f.updateMetric(span, labels.WithResult(trustmetrics.ErrTransmit), err) - return cppki.SignedTRC{}, serrors.WrapStr("receiving TRC", err) + return cppki.SignedTRC{}, serrors.Wrap("receiving TRC", err) } trc, err := cppki.DecodeSignedTRC(rep.Trc) // nolint - name from protobuf if err != nil { f.updateMetric(span, labels.WithResult(trustmetrics.ErrParse), err) - return cppki.SignedTRC{}, serrors.WrapStr("parse TRC reply", err) + return cppki.SignedTRC{}, serrors.Wrap("parse TRC reply", err) } logger.Debug("[trust:Resolver] Received TRC from remote", "id", id) if trc.TRC.ID != id { @@ -179,7 +179,7 @@ func checkChainsMatchQuery(query trust.ChainQuery, chains [][]*x509.Certificate) for i, chain := range chains { ia, err := cppki.ExtractIA(chain[0].Subject) if err != nil { - return serrors.WrapStr("extracting ISD-AS", err, "index", i) + return serrors.Wrap("extracting ISD-AS", err, "index", i) } if !query.IA.Equal(ia) { return serrors.New("ISD-AS mismatch", diff --git a/private/trust/grpc/proto.go b/private/trust/grpc/proto.go index 442735aeca..00aee5adb8 100644 --- a/private/trust/grpc/proto.go +++ b/private/trust/grpc/proto.go @@ -41,10 +41,10 @@ func repToChains(pbChains []*cppb.Chain) ([][]*x509.Certificate, string, error) var err error chain := make([]*x509.Certificate, 2) if chain[0], err = x509.ParseCertificate(c.AsCert); err != nil { - return nil, trustmetrics.ErrParse, serrors.WrapStr("parsing AS certificate", err) + return nil, trustmetrics.ErrParse, serrors.Wrap("parsing AS certificate", err) } if chain[1], err = x509.ParseCertificate(c.CaCert); err != nil { - return nil, trustmetrics.ErrParse, serrors.WrapStr("parsing CA certificate", err) + return nil, trustmetrics.ErrParse, serrors.Wrap("parsing CA certificate", err) } if err := cppki.ValidateChain(chain); err != nil { return nil, trustmetrics.ErrValidate, err diff --git a/private/trust/recurser.go b/private/trust/recurser.go index 7d484b5160..0b253dd2b8 100644 --- a/private/trust/recurser.go +++ b/private/trust/recurser.go @@ -51,7 +51,7 @@ func (r ASLocalRecurser) AllowRecursion(peer net.Addr) error { switch a := peer.(type) { case *snet.UDPAddr: if !r.IA.Equal(a.IA) { - return serrors.WrapStr("client outside local AS", ErrRecursionNotAllowed, + return serrors.Wrap("client outside local AS", ErrRecursionNotAllowed, "addr", peer) } return nil @@ -59,7 +59,7 @@ func (r ASLocalRecurser) AllowRecursion(peer net.Addr) error { // local host is allowed return nil default: - return serrors.WrapStr("unable to determine AS of peer", ErrRecursionNotAllowed, + return serrors.Wrap("unable to determine AS of peer", ErrRecursionNotAllowed, "addr", peer, "type", common.TypeOf(peer)) } } @@ -70,7 +70,7 @@ type LocalOnlyRecurser struct{} // AllowRecursion returns an error if the address is not nil. func (r LocalOnlyRecurser) AllowRecursion(peer net.Addr) error { if peer != nil { - return serrors.WrapStr("client not host-local", ErrRecursionNotAllowed, "addr", peer) + return serrors.Wrap("client not host-local", ErrRecursionNotAllowed, "addr", peer) } return nil } diff --git a/private/trust/router.go b/private/trust/router.go index 025db4fc63..3928137695 100644 --- a/private/trust/router.go +++ b/private/trust/router.go @@ -64,13 +64,13 @@ type AuthRouter struct { func (r AuthRouter) ChooseServer(ctx context.Context, subjectISD addr.ISD) (net.Addr, error) { dstISD, err := r.dstISD(ctx, subjectISD) if err != nil { - return nil, serrors.WrapStr("unable to determine dest ISD to query", err) + return nil, serrors.Wrap("unable to determine dest ISD to query", err) } logger := log.FromCtx(ctx) logger.Debug("Getting paths to any authoritative server", "isd", dstISD) path, err := r.Router.Route(ctx, addr.MustIAFrom(dstISD, 0)) if err != nil || path == nil { - return nil, serrors.WrapStr("unable to find path to any core AS", err, "isd", dstISD) + return nil, serrors.Wrap("unable to find path to any core AS", err, "isd", dstISD) } ret := &snet.SVCAddr{ IA: path.Destination(), @@ -88,7 +88,7 @@ func (r AuthRouter) dstISD(ctx context.Context, destination addr.ISD) (addr.ISD, logger := log.FromCtx(ctx) sTRC, err := r.DB.SignedTRC(ctx, cppki.TRCID{ISD: destination}) if err != nil { - return 0, serrors.WrapStr("error querying DB for TRC", err) + return 0, serrors.Wrap("error querying DB for TRC", err) } if sTRC.IsZero() { logger.Info("Direct to ISD-local authoritative servers", diff --git a/private/trust/signer.go b/private/trust/signer.go index 71c5ba4631..03a1bb1dde 100644 --- a/private/trust/signer.go +++ b/private/trust/signer.go @@ -74,7 +74,7 @@ func (s Signer) Sign( rawID, err := proto.Marshal(id) if err != nil { metrics.Signer.Sign(l.WithResult(metrics.ErrInternal)).Inc() - return nil, serrors.WrapStr("packing verification_key_id", err) + return nil, serrors.Wrap("packing verification_key_id", err) } hdr := signed.Header{ SignatureAlgorithm: s.Algorithm, diff --git a/private/trust/signer_gen.go b/private/trust/signer_gen.go index 66afaddc2c..af5477fae1 100644 --- a/private/trust/signer_gen.go +++ b/private/trust/signer_gen.go @@ -63,7 +63,7 @@ func (s SignerGen) Generate(ctx context.Context) ([]Signer, error) { trcs, res, err := activeTRCs(ctx, s.DB, s.IA.ISD()) if err != nil { metrics.Signer.Generate(l.WithResult(res)).Inc() - return nil, serrors.WrapStr("loading TRC", err) + return nil, serrors.Wrap("loading TRC", err) } var bests []Signer diff --git a/private/trust/store.go b/private/trust/store.go index 7feb1ae271..1eaea6f017 100644 --- a/private/trust/store.go +++ b/private/trust/store.go @@ -47,12 +47,12 @@ type LoadResult struct { // files that are not valid chains are ignored. func LoadChains(ctx context.Context, dir string, db DB) (LoadResult, error) { if _, err := os.Stat(dir); err != nil { - return LoadResult{}, serrors.WithCtx(err, "dir", dir) + return LoadResult{}, serrors.Wrap("stating directory", err, "dir", dir) } files, err := filepath.Glob(fmt.Sprintf("%s/*.pem", dir)) if err != nil { - return LoadResult{}, serrors.WithCtx(err, "dir", dir) + return LoadResult{}, serrors.Wrap("searching for certificates", err, "dir", dir) } res := LoadResult{Ignored: map[string]error{}} @@ -83,8 +83,9 @@ func LoadChains(ctx context.Context, dir string, db DB) (LoadResult, error) { continue } if err != nil { - return res, serrors.WrapStr("loading TRC(s) to verify certificate chain", err, + return res, serrors.Wrap("loading TRC(s) to verify certificate chain", err, "file", f) + } var verifyErrors serrors.List for _, trc := range trcs { @@ -99,10 +100,10 @@ func LoadChains(ctx context.Context, dir string, db DB) (LoadResult, error) { } inserted, err := db.InsertChain(ctx, chain) if err != nil { - return res, serrors.WrapStr("inserting certificate chain", err, "file", f) + return res, serrors.Wrap("inserting certificate chain", err, "file", f) } if !inserted { - res.Ignored[f] = serrors.Wrap(ErrAlreadyExists, err) + res.Ignored[f] = serrors.JoinNoStack(ErrAlreadyExists, err) continue } res.Loaded = append(res.Loaded, f) @@ -115,12 +116,12 @@ func LoadChains(ctx context.Context, dir string, db DB) (LoadResult, error) { // in the future are ignored. func LoadTRCs(ctx context.Context, dir string, db DB) (LoadResult, error) { if _, err := os.Stat(dir); err != nil { - return LoadResult{}, serrors.WithCtx(err, "dir", dir) + return LoadResult{}, serrors.WrapNoStack("stating directory", err, "dir", dir) } files, err := filepath.Glob(fmt.Sprintf("%s/*.trc", dir)) if err != nil { - return LoadResult{}, serrors.WithCtx(err, "dir", dir) + return LoadResult{}, serrors.WrapNoStack("searching for TRCs", err, "dir", dir) } res := LoadResult{Ignored: map[string]error{}} @@ -128,7 +129,7 @@ func LoadTRCs(ctx context.Context, dir string, db DB) (LoadResult, error) { for _, f := range files { raw, err := os.ReadFile(f) if err != nil { - return res, serrors.WithCtx(err, "file", f) + return res, serrors.WrapNoStack("reading TRC", err, "file", f) } block, _ := pem.Decode(raw) if block != nil && block.Type == "TRC" { @@ -136,7 +137,7 @@ func LoadTRCs(ctx context.Context, dir string, db DB) (LoadResult, error) { } trc, err := cppki.DecodeSignedTRC(raw) if err != nil { - return res, serrors.WithCtx(err, "file", f) + return res, serrors.WrapNoStack("parsing TRC", err, "file", f) } if time.Now().Before(trc.TRC.Validity.NotBefore) { res.Ignored[f] = serrors.New("TRC in the future", "validity", trc.TRC.Validity) @@ -144,10 +145,10 @@ func LoadTRCs(ctx context.Context, dir string, db DB) (LoadResult, error) { } inserted, err := db.InsertTRC(ctx, trc) if err != nil { - return res, serrors.WithCtx(err, "file", f) + return res, serrors.WrapNoStack("adding TRC to DB", err, "file", f) } if !inserted { - res.Ignored[f] = serrors.Wrap(ErrAlreadyExists, err) + res.Ignored[f] = serrors.JoinNoStack(ErrAlreadyExists, err) continue } res.Loaded = append(res.Loaded, f) diff --git a/private/trust/tls_verifier.go b/private/trust/tls_verifier.go index 241e9edc36..3ba77ef2c6 100644 --- a/private/trust/tls_verifier.go +++ b/private/trust/tls_verifier.go @@ -79,11 +79,11 @@ func (v *TLSCryptoVerifier) VerifyConnection(cs tls.ConnectionState) error { serverNameIA := strings.Split(cs.ServerName, ",")[0] serverIA, err := addr.ParseIA(serverNameIA) if err != nil { - return serrors.WrapStr("extracting IA from server name", err, "connState", cs) + return serrors.Wrap("extracting IA from server name", err, "connState", cs) } certIA, err := cppki.ExtractIA(cs.PeerCertificates[0].Subject) if err != nil { - return serrors.WrapStr("extracting IA from peer cert", err) + return serrors.Wrap("extracting IA from peer cert", err) } if !serverIA.Equal(certIA) { return serrors.New("extracted IA from cert and server IA do not match", @@ -103,7 +103,7 @@ func (v *TLSCryptoVerifier) verifyRawPeerCertificate( for i, asn1Data := range rawCerts { cert, err := x509.ParseCertificate(asn1Data) if err != nil { - return serrors.WrapStr("parsing peer certificate", err) + return serrors.Wrap("parsing peer certificate", err) } chain[i] = cert } @@ -126,16 +126,16 @@ func (v *TLSCryptoVerifier) verifyParsedPeerCertificate( } ia, err := cppki.ExtractIA(chain[0].Subject) if err != nil { - return 0, serrors.WrapStr("extracting ISD-AS from peer certificate", err) + return 0, serrors.Wrap("extracting ISD-AS from peer certificate", err) } ctx, cancel := context.WithTimeout(context.Background(), v.Timeout) defer cancel() trcs, _, err := activeTRCs(ctx, v.DB, ia.ISD()) if err != nil { - return 0, serrors.WrapStr("loading TRCs", err) + return 0, serrors.Wrap("loading TRCs", err) } if err := verifyChain(chain, trcs); err != nil { - return 0, serrors.WrapStr("verifying chains", err) + return 0, serrors.Wrap("verifying chains", err) } return ia, nil } diff --git a/private/trust/verifier.go b/private/trust/verifier.go index 5ea498676a..5ee8c4bb08 100644 --- a/private/trust/verifier.go +++ b/private/trust/verifier.go @@ -74,11 +74,11 @@ func (v Verifier) Verify(ctx context.Context, signedMsg *cryptopb.SignedMessage, var keyID cppb.VerificationKeyID if err := proto.Unmarshal(hdr.VerificationKeyID, &keyID); err != nil { metrics.Verifier.Verify(l.WithResult(metrics.ErrValidate)).Inc() - return nil, serrors.WrapStr("parsing verification key ID", err) + return nil, serrors.Wrap("parsing verification key ID", err) } if len(keyID.SubjectKeyId) == 0 { metrics.Verifier.Verify(l.WithResult(metrics.ErrValidate)).Inc() - return nil, serrors.WrapStr("subject key ID must be set", err) + return nil, serrors.Wrap("subject key ID must be set", err) } ia := addr.IA(keyID.IsdAs) if !v.BoundIA.IsZero() && !v.BoundIA.Equal(ia) { @@ -99,7 +99,7 @@ func (v Verifier) Verify(ctx context.Context, signedMsg *cryptopb.SignedMessage, } if err := v.notifyTRC(ctx, id); err != nil { metrics.Verifier.Verify(l.WithResult(metrics.ErrInternal)).Inc() - return nil, serrors.WrapStr("reporting TRC", err, "id", id) + return nil, serrors.Wrap("reporting TRC", err, "id", id) } query := ChainQuery{ IA: ia, @@ -109,7 +109,7 @@ func (v Verifier) Verify(ctx context.Context, signedMsg *cryptopb.SignedMessage, chains, err := v.getChains(ctx, query) if err != nil { metrics.Verifier.Verify(l.WithResult(metrics.ErrInternal)).Inc() - return nil, serrors.WrapStr("getting chains", err, + return nil, serrors.Wrap("getting chains", err, "query.isd_as", query.IA, "query.subject_key_id", fmt.Sprintf("%x", query.SubjectKeyID), "query.validity", query.Validity.String(), diff --git a/private/underlay/conn/conn.go b/private/underlay/conn/conn.go index 3c3f0e4a27..8eb912ef16 100644 --- a/private/underlay/conn/conn.go +++ b/private/underlay/conn/conn.go @@ -172,8 +172,9 @@ func (cc *connUDPBase) initConnUDP( } if !raddr.IsValid() { if c, err = net.ListenUDP(network, net.UDPAddrFromAddrPort(laddr)); err != nil { - return serrors.WrapStr("Error listening on socket", err, + return serrors.Wrap("Error listening on socket", err, "network", network, "listen", laddr) + } } else { if c, err = net.DialUDP( @@ -181,7 +182,7 @@ func (cc *connUDPBase) initConnUDP( net.UDPAddrFromAddrPort(laddr), net.UDPAddrFromAddrPort(raddr), ); err != nil { - return serrors.WrapStr("Error setting up connection", err, + return serrors.Wrap("Error setting up connection", err, "network", network, "listen", laddr, "remote", raddr) } } @@ -190,21 +191,21 @@ func (cc *connUDPBase) initConnUDP( if cfg.SendBufferSize != 0 { before, err := sockctrl.GetsockoptInt(c, syscall.SOL_SOCKET, syscall.SO_SNDBUF) if err != nil { - return serrors.WrapStr("Error getting SO_SNDBUF socket option (before)", err, + return serrors.Wrap("Error getting SO_SNDBUF socket option (before)", err, "listen", laddr, "remote", raddr, ) } target := cfg.SendBufferSize if err = c.SetWriteBuffer(target); err != nil { - return serrors.WrapStr("Error setting send buffer size", err, + return serrors.Wrap("Error setting send buffer size", err, "listen", laddr, "remote", raddr, ) } after, err := sockctrl.GetsockoptInt(c, syscall.SOL_SOCKET, syscall.SO_SNDBUF) if err != nil { - return serrors.WrapStr("Error getting SO_SNDBUF socket option (after)", err, + return serrors.Wrap("Error getting SO_SNDBUF socket option (after)", err, "listen", laddr, "remote", raddr, ) @@ -224,21 +225,21 @@ func (cc *connUDPBase) initConnUDP( if cfg.ReceiveBufferSize != 0 { before, err := sockctrl.GetsockoptInt(c, syscall.SOL_SOCKET, syscall.SO_RCVBUF) if err != nil { - return serrors.WrapStr("Error getting SO_RCVBUF socket option (before)", err, + return serrors.Wrap("Error getting SO_RCVBUF socket option (before)", err, "listen", laddr, "remote", raddr, ) } target := cfg.ReceiveBufferSize if err = c.SetReadBuffer(target); err != nil { - return serrors.WrapStr("Error setting recv buffer size", err, + return serrors.Wrap("Error setting recv buffer size", err, "listen", laddr, "remote", raddr, ) } after, err := sockctrl.GetsockoptInt(c, syscall.SOL_SOCKET, syscall.SO_RCVBUF) if err != nil { - return serrors.WrapStr("Error getting SO_RCVBUF socket option (after)", err, + return serrors.Wrap("Error getting SO_RCVBUF socket option (after)", err, "listen", laddr, "remote", raddr, ) diff --git a/private/underlay/sockctrl/sockctrl.go b/private/underlay/sockctrl/sockctrl.go index e2a036e65e..2faeef054a 100644 --- a/private/underlay/sockctrl/sockctrl.go +++ b/private/underlay/sockctrl/sockctrl.go @@ -28,17 +28,17 @@ import ( func SockControl(c *net.UDPConn, f func(int) error) error { rawConn, err := c.SyscallConn() if err != nil { - return serrors.WrapStr("sockctrl: error accessing raw connection", err) + return serrors.Wrap("sockctrl: error accessing raw connection", err) } var ctrlErr error err = rawConn.Control(func(fd uintptr) { ctrlErr = f(int(fd)) }) if err != nil { - return serrors.WrapStr("sockctrl: RawConn.Control error", err) + return serrors.Wrap("sockctrl: RawConn.Control error", err) } if ctrlErr != nil { - return serrors.WrapStr("sockctrl: control function error", ctrlErr) + return serrors.Wrap("sockctrl: control function error", ctrlErr) } return nil } diff --git a/router/bfd/session.go b/router/bfd/session.go index d5a06d4f80..dd991fce46 100644 --- a/router/bfd/session.go +++ b/router/bfd/session.go @@ -313,14 +313,14 @@ func (s *Session) validateParameters() error { } desiredMinTxInterval, err := durationToBFDInterval(s.DesiredMinTxInterval) if err != nil { - return serrors.WrapStr("bad desired minimum transmission interval", err) + return serrors.Wrap("bad desired minimum transmission interval", err) } if desiredMinTxInterval == 0 { return serrors.New("desired minimum transmission interval must be > 0") } requiredMinRxInterval, err := durationToBFDInterval(s.RequiredMinRxInterval) if err != nil { - return serrors.WrapStr("bad required minimum receive interval", err) + return serrors.Wrap("bad required minimum receive interval", err) } if requiredMinRxInterval == 0 { return serrors.New("required minimum receive interval must be > 0") diff --git a/router/cmd/router/main.go b/router/cmd/router/main.go index 6a43e58796..af8b2fd0fe 100644 --- a/router/cmd/router/main.go +++ b/router/cmd/router/main.go @@ -73,7 +73,7 @@ func realMain(ctx context.Context) error { DP: dp, } if err := iaCtx.Configure(); err != nil { - return serrors.WrapStr("configuring dataplane", err) + return serrors.Wrap("configuring dataplane", err) } statusPages := service.StatusPages{ "info": service.NewInfoStatusPage(), @@ -117,7 +117,7 @@ func realMain(ctx context.Context) error { defer log.HandlePanic() err := mgmtServer.ListenAndServe() if err != nil && !errors.Is(err, http.ErrServerClosed) { - return serrors.WrapStr("serving service management API", err) + return serrors.Wrap("serving service management API", err) } return nil }) @@ -134,7 +134,7 @@ func realMain(ctx context.Context) error { BatchSize: globalCfg.Router.BatchSize, } if err := dp.DataPlane.Run(errCtx, runConfig); err != nil { - return serrors.WrapStr("running dataplane", err) + return serrors.Wrap("running dataplane", err) } return nil }) @@ -145,7 +145,7 @@ func realMain(ctx context.Context) error { func loadControlConfig() (*control.Config, error) { newConf, err := control.LoadConfig(globalCfg.General.ID, globalCfg.General.ConfigDir) if err != nil { - return nil, serrors.WrapStr("loading topology", err) + return nil, serrors.Wrap("loading topology", err) } return newConf, nil } diff --git a/router/connector.go b/router/connector.go index 6c9fccef71..e1b48efffa 100644 --- a/router/connector.go +++ b/router/connector.go @@ -53,7 +53,7 @@ func (c *Connector) CreateIACtx(ia addr.IA) error { defer c.mtx.Unlock() log.Debug("CreateIACtx", "isd_as", ia) if !c.ia.IsZero() { - return serrors.WithCtx(errMultiIA, "current", c.ia, "new", ia) + return serrors.JoinNoStack(errMultiIA, nil, "current", c.ia, "new", ia) } c.ia = ia return c.DataPlane.SetIA(ia) @@ -65,7 +65,7 @@ func (c *Connector) AddInternalInterface(ia addr.IA, local netip.AddrPort) error defer c.mtx.Unlock() log.Debug("Adding internal interface", "isd_as", ia, "local", local) if !c.ia.Equal(ia) { - return serrors.WithCtx(errMultiIA, "current", c.ia, "new", ia) + return serrors.JoinNoStack(errMultiIA, nil, "current", c.ia, "new", ia) } connection, err := conn.New(local, netip.AddrPort{}, &conn.Config{ReceiveBufferSize: c.ReceiveBufferSize, SendBufferSize: c.SendBufferSize}) @@ -95,13 +95,13 @@ func (c *Connector) AddExternalInterface(localIfID common.IfIDType, link control "dataplane_bfd_enabled", !c.BFD.Disable) if !c.ia.Equal(link.Local.IA) { - return serrors.WithCtx(errMultiIA, "current", c.ia, "new", link.Local.IA) + return serrors.JoinNoStack(errMultiIA, nil, "current", c.ia, "new", link.Local.IA) } if err := c.DataPlane.AddLinkType(intf, link.LinkTo); err != nil { - return serrors.WrapStr("adding link type", err, "if_id", localIfID) + return serrors.Wrap("adding link type", err, "if_id", localIfID) } if err := c.DataPlane.AddNeighborIA(intf, link.Remote.IA); err != nil { - return serrors.WrapStr("adding neighboring IA", err, "if_id", localIfID) + return serrors.Wrap("adding neighboring IA", err, "if_id", localIfID) } link.BFD = c.applyBFDDefaults(link.BFD) @@ -146,7 +146,7 @@ func (c *Connector) AddSvc(ia addr.IA, svc addr.SVC, a netip.AddrPort) error { defer c.mtx.Unlock() log.Debug("Adding service", "isd_as", ia, "svc", svc, "address", a) if !c.ia.Equal(ia) { - return serrors.WithCtx(errMultiIA, "current", c.ia, "new", a) + return serrors.JoinNoStack(errMultiIA, nil, "current", c.ia, "new", a) } return c.DataPlane.AddSvc(svc, a) } @@ -157,7 +157,7 @@ func (c *Connector) DelSvc(ia addr.IA, svc addr.SVC, a netip.AddrPort) error { defer c.mtx.Unlock() log.Debug("Deleting service", "isd_as", ia, "svc", svc, "address", a) if !c.ia.Equal(ia) { - return serrors.WithCtx(errMultiIA, "current", c.ia, "new", a) + return serrors.JoinNoStack(errMultiIA, nil, "current", c.ia, "new", a) } return c.DataPlane.DelSvc(svc, a) } @@ -168,7 +168,7 @@ func (c *Connector) SetKey(ia addr.IA, index int, key []byte) error { defer c.mtx.Unlock() log.Debug("Setting key", "isd_as", ia, "index", index) if !c.ia.Equal(ia) { - return serrors.WithCtx(errMultiIA, "current", c.ia, "new", ia) + return serrors.JoinNoStack(errMultiIA, nil, "current", c.ia, "new", ia) } if index != 0 { return serrors.New("currently only index 0 key is supported") diff --git a/router/control/iactx.go b/router/control/iactx.go index 3f92c84aa8..958e6351d3 100644 --- a/router/control/iactx.go +++ b/router/control/iactx.go @@ -64,7 +64,7 @@ func (cfg *Config) loadTopo(id string, confDir string) error { return err } if err := cfg.initTopo(id, topo); err != nil { - return serrors.WrapStr("initializing topology", err, "file", topoPath) + return serrors.Wrap("initializing topology", err, "file", topoPath) } return nil } @@ -87,7 +87,7 @@ func (cfg *Config) loadMasterKeys(confDir string) error { var err error cfg.MasterKeys, err = keyconf.LoadMaster(filepath.Join(confDir, "keys")) if err != nil { - return serrors.WrapStr("loading master keys", err) + return serrors.Wrap("loading master keys", err) } return nil } @@ -114,7 +114,7 @@ func (iac *IACtx) Configure() error { if errDump != nil { brConfDump = errDump.Error() } - return serrors.WrapStr("config setup", err, "config", brConfDump) + return serrors.Wrap("config setup", err, "config", brConfDump) } log.Debug("Dataplane configured successfully", "config", cfg) return nil diff --git a/router/dataplane.go b/router/dataplane.go index e318c3729f..36b7146c5f 100644 --- a/router/dataplane.go +++ b/router/dataplane.go @@ -363,7 +363,7 @@ func (d *DataPlane) AddExternalInterface(ifID uint16, conn BatchConn, } err := d.addExternalInterfaceBFD(ifID, conn, src, dst, cfg) if err != nil { - return serrors.WrapStr("adding external BFD", err, "if_id", ifID) + return serrors.Wrap("adding external BFD", err, "if_id", ifID) } if d.external == nil { d.external = make(map[uint16]BatchConn) @@ -372,7 +372,7 @@ func (d *DataPlane) AddExternalInterface(ifID uint16, conn BatchConn, d.interfaces = make(map[uint16]BatchConn) } if _, exists := d.external[ifID]; exists { - return serrors.WithCtx(alreadySet, "ifID", ifID) + return serrors.JoinNoStack(alreadySet, nil, "ifID", ifID) } d.interfaces[ifID] = conn d.external[ifID] = conn @@ -392,7 +392,7 @@ func (d *DataPlane) AddNeighborIA(ifID uint16, remote addr.IA) error { return emptyValue } if _, exists := d.neighborIAs[ifID]; exists { - return serrors.WithCtx(alreadySet, "ifID", ifID) + return serrors.JoinNoStack(alreadySet, nil, "ifID", ifID) } if d.neighborIAs == nil { d.neighborIAs = make(map[uint16]addr.IA) @@ -406,7 +406,7 @@ func (d *DataPlane) AddNeighborIA(ifID uint16, remote addr.IA) error { // be called on a not yet running dataplane. func (d *DataPlane) AddLinkType(ifID uint16, linkTo topology.LinkType) error { if _, exists := d.linkTypes[ifID]; exists { - return serrors.WithCtx(alreadySet, "ifID", ifID) + return serrors.JoinNoStack(alreadySet, nil, "ifID", ifID) } if d.linkTypes == nil { d.linkTypes = make(map[uint16]topology.LinkType) @@ -421,10 +421,10 @@ func (d *DataPlane) AddLinkType(ifID uint16, linkTo topology.LinkType) error { // be called on a not yet running dataplane. func (d *DataPlane) AddRemotePeer(local, remote uint16) error { if t, ok := d.linkTypes[local]; ok && t != topology.Peer { - return serrors.WithCtx(unsupportedPathType, "type", t) + return serrors.JoinNoStack(unsupportedPathType, nil, "type", t) } if _, exists := d.peerInterfaces[local]; exists { - return serrors.WithCtx(alreadySet, "local_interface", local) + return serrors.JoinNoStack(alreadySet, nil, "local_interface", local) } if d.peerInterfaces == nil { d.peerInterfaces = make(map[uint16]uint16) @@ -554,13 +554,13 @@ func (d *DataPlane) AddNextHop(ifID uint16, src, dst netip.AddrPort, cfg control } err := d.addNextHopBFD(ifID, src, dst, cfg, sibling) if err != nil { - return serrors.WrapStr("adding next hop BFD", err, "if_id", ifID) + return serrors.Wrap("adding next hop BFD", err, "if_id", ifID) } if d.internalNextHops == nil { d.internalNextHops = make(map[uint16]netip.AddrPort) } if _, exists := d.internalNextHops[ifID]; exists { - return serrors.WithCtx(alreadySet, "ifID", ifID) + return serrors.JoinNoStack(alreadySet, nil, "ifID", ifID) } d.internalNextHops[ifID] = dst return nil @@ -1357,7 +1357,7 @@ func (p *slowPathPacketProcessor) packSCMP( var scmpLayer slayers.SCMP err := scmpLayer.DecodeFromBytes(p.lastLayer.LayerPayload(), gopacket.NilDecodeFeedback) if err != nil { - return serrors.WrapStr("decoding SCMP layer", err) + return serrors.Wrap("decoding SCMP layer", err) } if !scmpLayer.TypeCode.InfoMsg() { return serrors.New("SCMP error for SCMP error pkt -> DROP") @@ -2169,12 +2169,12 @@ func (d *DataPlane) addEndhostPort( err := scmpLayer.DecodeFromBytes(lastLayer.LayerPayload(), gopacket.NilDecodeFeedback) if err != nil { // TODO(JordiSubira): Treat this as a parameter problem. - return serrors.WrapStr("decoding SCMP layer for extracting endhost dst port", err) + return serrors.Wrap("decoding SCMP layer for extracting endhost dst port", err) } port, err = getDstPortSCMP(&scmpLayer) if err != nil { // TODO(JordiSubira): Treat this as a parameter problem. - return serrors.WrapStr("getting dst port from SCMP message", err) + return serrors.Wrap("getting dst port from SCMP message", err) } // if the SCMP dst port is outside the range, we send it to the EndhostPort if port < d.dispatchedPortStart || port > d.dispatchedPortEnd { @@ -2420,33 +2420,36 @@ func (p *slowPathPacketProcessor) prepareSCMP( var ok bool path, ok = p.scionLayer.Path.(*scion.Raw) if !ok { - return nil, serrors.WithCtx(cannotRoute, "details", "unsupported path type", + return nil, serrors.JoinNoStack(cannotRoute, nil, "details", "unsupported path type", "path type", pathType) + } case epic.PathType: epicPath, ok := p.scionLayer.Path.(*epic.Path) if !ok { - return nil, serrors.WithCtx(cannotRoute, "details", "unsupported path type", + return nil, serrors.JoinNoStack(cannotRoute, nil, "details", "unsupported path type", "path type", pathType) + } path = epicPath.ScionPath default: - return nil, serrors.WithCtx(cannotRoute, "details", "unsupported path type", + return nil, serrors.JoinNoStack(cannotRoute, nil, "details", "unsupported path type", "path type", pathType) + } decPath, err := path.ToDecoded() if err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "decoding raw path") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "decoding raw path") } revPathTmp, err := decPath.Reverse() if err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "reversing path for SCMP") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "reversing path for SCMP") } revPath := revPathTmp.(*scion.Decoded) peering, err := determinePeer(revPath.PathMeta, revPath.InfoFields[revPath.PathMeta.CurrINF]) if err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "peering cannot be determined") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "peering cannot be determined") } // Revert potential path segment switches that were done during processing. @@ -2454,7 +2457,8 @@ func (p *slowPathPacketProcessor) prepareSCMP( // An effective cross-over is a change of segment other than at // a peering hop. if err := revPath.IncPath(); err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "reverting cross over for SCMP") + return nil, serrors.JoinNoStack(cannotRoute, err, + "details", "reverting cross over for SCMP") } } // If the packet is sent to an external router, we need to increment the @@ -2467,7 +2471,8 @@ func (p *slowPathPacketProcessor) prepareSCMP( infoField.UpdateSegID(hopField.Mac) } if err := revPath.IncPath(); err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "incrementing path for SCMP") + return nil, serrors.JoinNoStack(cannotRoute, err, + "details", "incrementing path for SCMP") } } @@ -2484,7 +2489,7 @@ func (p *slowPathPacketProcessor) prepareSCMP( scionL.NextHdr = slayers.L4SCMP if err := scionL.SetSrcAddr(addr.HostIP(p.d.internalIP)); err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "setting src addr") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "setting src addr") } typeCode := slayers.CreateSCMPTypeCode(typ, code) scmpH := slayers.SCMP{TypeCode: typeCode} @@ -2536,7 +2541,7 @@ func (p *slowPathPacketProcessor) prepareSCMP( // XXX(matzf) could we use iovec gather to avoid copying quote? err = gopacket.SerializeLayers(p.buffer, sopts, &scmpH, scmpP, gopacket.Payload(quote)) if err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "serializing SCMP message") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "serializing SCMP message") } if needsAuth { @@ -2546,14 +2551,15 @@ func (p *slowPathPacketProcessor) prepareSCMP( now := time.Now() dstA, err := scionL.DstAddr() if err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "parsing destination address") + return nil, serrors.JoinNoStack(cannotRoute, err, + "details", "parsing destination address") } key, err := p.drkeyProvider.GetASHostKey(now, scionL.DstIA, dstA) if err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "retrieving DRKey") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "retrieving DRKey") } if err := p.resetSPAOMetadata(key, now); err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "resetting SPAO header") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "resetting SPAO header") } e2e.Options = []*slayers.EndToEndOption{p.optAuth.EndToEndOption} @@ -2570,16 +2576,17 @@ func (p *slowPathPacketProcessor) prepareSCMP( p.optAuth.Authenticator(), ) if err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "computing CMAC") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "computing CMAC") } if err := e2e.SerializeTo(p.buffer, sopts); err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "serializing SCION E2E headers") + return nil, serrors.JoinNoStack(cannotRoute, err, + "details", "serializing SCION E2E headers") } } else { scionL.NextHdr = slayers.L4SCMP } if err := scionL.SerializeTo(p.buffer, sopts); err != nil { - return nil, serrors.Wrap(cannotRoute, err, "details", "serializing SCION header") + return nil, serrors.JoinNoStack(cannotRoute, err, "details", "serializing SCION header") } log.Debug("scmp", "typecode", scmpH.TypeCode) diff --git a/scion-pki/certs/create.go b/scion-pki/certs/create.go index bd50c0a112..17beaa61d5 100644 --- a/scion-pki/certs/create.go +++ b/scion-pki/certs/create.go @@ -197,11 +197,11 @@ A valid example for a JSON formatted template:: } ct, err := parseCertType(flags.profile) if err != nil { - return serrors.WrapStr("parsing profile", err) + return serrors.Wrap("parsing profile", err) } subject, err := createSubject(args[0], flags.commonName) if err != nil { - return serrors.WrapStr("creating subject", err) + return serrors.Wrap("creating subject", err) } // Only check that the flags are set appropriately here. @@ -224,14 +224,14 @@ A valid example for a JSON formatted template:: var encodedKey []byte if flags.existingKey != "" { if privKey, err = key.LoadPrivateKey(flags.existingKey); err != nil { - return serrors.WrapStr("loading existing private key", err) + return serrors.Wrap("loading existing private key", err) } } else { if privKey, err = key.GeneratePrivateKey(flags.curve); err != nil { - return serrors.WrapStr("creating fresh private key", err) + return serrors.Wrap("creating fresh private key", err) } if encodedKey, err = key.EncodePEMPrivateKey(privKey); err != nil { - return serrors.WrapStr("encoding fresh private key", err) + return serrors.Wrap("encoding fresh private key", err) } } @@ -240,13 +240,13 @@ A valid example for a JSON formatted template:: var caKey key.PrivateKey if loadCA { if caCertRaw, err = os.ReadFile(flags.ca); err != nil { - return serrors.WrapStr("read CA certificate", err) + return serrors.Wrap("read CA certificate", err) } if caCert, err = parseCertificate(caCertRaw); err != nil { - return serrors.WrapStr("parsing CA certificate", err) + return serrors.Wrap("parsing CA certificate", err) } if caKey, err = key.LoadPrivateKey(flags.caKey); err != nil { - return serrors.WrapStr("loading CA private key", err) + return serrors.Wrap("loading CA private key", err) } } if isSelfSigned { @@ -256,7 +256,7 @@ A valid example for a JSON formatted template:: if flags.csr { csr, err := CreateCSR(ct, subject, privKey) if err != nil { - return serrors.WrapStr("creating CSR", err) + return serrors.Wrap("creating CSR", err) } encodedCSR := pem.EncodeToMemory(&pem.Block{ Type: "CERTIFICATE REQUEST", @@ -268,7 +268,7 @@ A valid example for a JSON formatted template:: csrFile := args[1] err = file.WriteFile(csrFile, encodedCSR, 0644, file.WithForce(flags.force)) if err != nil { - return serrors.WrapStr("writing CSR", err) + return serrors.Wrap("writing CSR", err) } fmt.Printf("CSR successfully written to %q\n", csrFile) } else { @@ -282,7 +282,7 @@ A valid example for a JSON formatted template:: CACert: caCert, }) if err != nil { - return serrors.WrapStr("creating certificate", err) + return serrors.Wrap("creating certificate", err) } encodedCert := pem.EncodeToMemory(&pem.Block{ Type: "CERTIFICATE", @@ -298,7 +298,7 @@ A valid example for a JSON formatted template:: certFile := args[1] err = file.WriteFile(certFile, encodedCert, 0644, file.WithForce(flags.force)) if err != nil { - return serrors.WrapStr("writing certificate", err) + return serrors.Wrap("writing certificate", err) } fmt.Printf("Certificate successfully written to %q\n", certFile) } @@ -306,11 +306,11 @@ A valid example for a JSON formatted template:: if encodedKey != nil { keyFile := args[2] if err := file.CheckDirExists(filepath.Dir(keyFile)); err != nil { - return serrors.WrapStr("checking that directory of private key exists", err) + return serrors.Wrap("checking that directory of private key exists", err) } err := file.WriteFile(keyFile, encodedKey, 0600, file.WithForce(flags.force)) if err != nil { - return serrors.WrapStr("writing private key", err) + return serrors.Wrap("writing private key", err) } fmt.Printf("Private key successfully written to %q\n", keyFile) } @@ -519,11 +519,11 @@ func CreateCertificate(params CertParams) ([]byte, error) { } serial := make([]byte, 20) if _, err := rand.Read(serial); err != nil { - return nil, serrors.WrapStr("creating random serial number", err) + return nil, serrors.Wrap("creating random serial number", err) } skid, err := cppki.SubjectKeyID(params.PubKey) if err != nil { - return nil, serrors.WrapStr("computing subject key ID", err) + return nil, serrors.Wrap("computing subject key ID", err) } tmpl.SerialNumber = big.NewInt(0).SetBytes(serial) @@ -557,11 +557,11 @@ func CreateCertificate(params CertParams) ([]byte, error) { } parsed, err := x509.ParseCertificate(cert) if err != nil { - return nil, serrors.WrapStr("parsing new certificate", err) + return nil, serrors.Wrap("parsing new certificate", err) } ct, err := cppki.ValidateCert(parsed) if err != nil { - return nil, serrors.WrapStr("validating new certificate", err) + return nil, serrors.Wrap("validating new certificate", err) } if ct != params.Type { return nil, serrors.New("new certificate of invalid type", "type", ct) diff --git a/scion-pki/certs/fingerprint.go b/scion-pki/certs/fingerprint.go index 67b5ff7c57..3f31651296 100644 --- a/scion-pki/certs/fingerprint.go +++ b/scion-pki/certs/fingerprint.go @@ -55,7 +55,7 @@ If the flag \--format is set to "emoji", the format of the output is a string of chain, err := cppki.ReadPEMCerts(args[0]) if err != nil { - return serrors.WrapStr("loading certificate chain", err) + return serrors.Wrap("loading certificate chain", err) } h := sha256.New() diff --git a/scion-pki/certs/inspect.go b/scion-pki/certs/inspect.go index bbc222f5ed..720ffdb723 100644 --- a/scion-pki/certs/inspect.go +++ b/scion-pki/certs/inspect.go @@ -48,7 +48,7 @@ request (CSR) in human readable format.`, cmd.SilenceUsage = true raw, err := os.ReadFile(args[0]) if err != nil { - return serrors.WrapStr("loading file", err) + return serrors.Wrap("loading file", err) } pemData, rest := pem.Decode(raw) if pemData == nil { @@ -69,7 +69,7 @@ request (CSR) in human readable format.`, } csr, err := x509.ParseCertificateRequest(pemData.Bytes) if err != nil { - return serrors.WrapStr("parsing CSR", err) + return serrors.Wrap("parsing CSR", err) } return prettyPrintCSR(w, csr, flags.short) default: @@ -94,10 +94,10 @@ func prettyPrintCertificate(w io.Writer, certs []*x509.Certificate, short bool) for i, cert := range certs { info, err := format(cert) if err != nil { - return serrors.WrapStr("formatting certificate info", err, "index", i) + return serrors.Wrap("formatting certificate info", err, "index", i) } if _, err = fmt.Fprint(w, info); err != nil { - return serrors.WrapStr("writing certificate info", err, "index", i) + return serrors.Wrap("writing certificate info", err, "index", i) } } return nil @@ -111,10 +111,10 @@ func prettyPrintCSR(w io.Writer, csr *x509.CertificateRequest, short bool) error } info, err := format(csr) if err != nil { - return serrors.WrapStr("formatting CSR info", err) + return serrors.Wrap("formatting CSR info", err) } if _, err = fmt.Fprint(w, info); err != nil { - return serrors.WrapStr("writing CSR info", err) + return serrors.Wrap("writing CSR info", err) } return nil } diff --git a/scion-pki/certs/match.go b/scion-pki/certs/match.go index 278ddf371f..3e3691bb74 100644 --- a/scion-pki/certs/match.go +++ b/scion-pki/certs/match.go @@ -65,11 +65,11 @@ The output contains all the private keys that are authenticated by the certifica certs, err := cppki.ReadPEMCerts(args[0]) if err != nil { - return serrors.WrapStr("parsing certificate", err, "file", args[0]) + return serrors.Wrap("parsing certificate", err, "file", args[0]) } certKey, err := x509.MarshalPKIXPublicKey(certs[0].PublicKey) if err != nil { - return serrors.WrapStr("packing the certificate public key", err) + return serrors.Wrap("packing the certificate public key", err) } var keys []string @@ -102,7 +102,7 @@ func loadPackedPublicFromPrivate(file string) ([]byte, error) { } pub, err := x509.MarshalPKIXPublicKey(key.Public()) if err != nil { - return nil, serrors.WrapStr("packing the public key", err) + return nil, serrors.Wrap("packing the public key", err) } return pub, nil } diff --git a/scion-pki/certs/renew.go b/scion-pki/certs/renew.go index cd13c6bfef..7b94935e62 100644 --- a/scion-pki/certs/renew.go +++ b/scion-pki/certs/renew.go @@ -212,7 +212,7 @@ The template is expressed in JSON. A valid example:: expiryChecker, err := parseExpiresIn(flags.expiresIn) if err != nil { - return serrors.WrapStr("parsing --expires-in", err) + return serrors.Wrap("parsing --expires-in", err) } if len(flags.ca) > 0 && len(flags.remotes) > 0 { @@ -252,7 +252,7 @@ The template is expressed in JSON. A valid example:: } closer, err := setupTracer("scion-pki", flags.tracer) if err != nil { - return serrors.WrapStr("setting up tracing", err) + return serrors.Wrap("setting up tracing", err) } defer closer() @@ -274,7 +274,7 @@ The template is expressed in JSON. A valid example:: defer daemonCancel() sd, err := daemon.NewService(daemonAddr).Connect(daemonCtx) if err != nil { - return serrors.WrapStr("connecting to SCION Daemon", err) + return serrors.Wrap("connecting to SCION Daemon", err) } defer sd.Close() @@ -309,7 +309,7 @@ The template is expressed in JSON. A valid example:: for _, raw := range flags.ca { ca, err := addr.ParseIA(raw) if err != nil { - return serrors.WrapStr("parsing CA", err) + return serrors.Wrap("parsing CA", err) } cas = append(cas, ca) } @@ -317,7 +317,7 @@ The template is expressed in JSON. A valid example:: for _, raw := range flags.remotes { addr, err := snet.ParseUDPAddr(raw) if err != nil { - return serrors.WrapStr("parsing remote", err) + return serrors.Wrap("parsing remote", err) } remotes = append(remotes, addr) } @@ -335,7 +335,7 @@ The template is expressed in JSON. A valid example:: // Load private key. privPrev, err := key.LoadPrivateKey(keyFile) if err != nil { - return serrors.WrapStr("reading private key", err) + return serrors.Wrap("reading private key", err) } privNext := key.PrivateKey(privPrev) @@ -344,10 +344,10 @@ The template is expressed in JSON. A valid example:: var pemPrivNext []byte if !flags.reuseKey { if privNext, err = key.GeneratePrivateKey(flags.curve); err != nil { - return serrors.WrapStr("creating fresh private key", err) + return serrors.Wrap("creating fresh private key", err) } if pemPrivNext, err = key.EncodePEMPrivateKey(privNext); err != nil { - return serrors.WrapStr("encoding fresh private key", err) + return serrors.Wrap("encoding fresh private key", err) } } @@ -362,7 +362,7 @@ The template is expressed in JSON. A valid example:: csr, err := CreateCSR(cppki.AS, subject, privNext) if err != nil { - return serrors.WrapStr("creating CSR", err) + return serrors.Wrap("creating CSR", err) } if flags.outCSR != "" { pemCSR := pem.EncodeToMemory(&pem.Block{ @@ -492,7 +492,7 @@ The template is expressed in JSON. A valid example:: trcs[0].ID.Base, trcs[0].ID.Serial-1, ) } - return nil, serrors.WrapStr("verification failed", verifyError) + return nil, serrors.Wrap("verification failed", verifyError) } return chain, nil } @@ -526,12 +526,12 @@ The template is expressed in JSON. A valid example:: if pemPrivNext != nil { if err := file.WriteFile(outKeyFile, pemPrivNext, 0600, opts...); err != nil { - return serrors.WrapStr("writing fresh private key", err) + return serrors.Wrap("writing fresh private key", err) } printf("Private key successfully written to %q\n", outKeyFile) } if err := file.WriteFile(outCertFile, pemRenewed, 0644, opts...); err != nil { - return serrors.WrapStr("writing renewed certificate chain", err) + return serrors.Wrap("writing renewed certificate chain", err) } printf("Certificate chain successfully written to %q\n", outCertFile) return nil @@ -722,11 +722,11 @@ func (r *renewer) requestRemote( // Resolve local IP based on underlay next hop if nexthop != nil { if localIP, err = addrutil.ResolveLocal(nexthop.IP); err != nil { - return nil, serrors.WrapStr("resolving local address", err) + return nil, serrors.Wrap("resolving local address", err) } } else { if localIP, err = addrutil.DefaultLocalIP(ctx, r.Daemon); err != nil { - return nil, serrors.WrapStr("resolving default address", err) + return nil, serrors.Wrap("resolving default address", err) } } fmt.Printf("Resolved local address:\n %s\n", localIP) @@ -748,7 +748,7 @@ func (r *renewer) requestRemote( conn, err := sn.Listen(ctx, "udp", local.Host) if err != nil { - return nil, serrors.WrapStr("dialing", err) + return nil, serrors.Wrap("dialing", err) } defer conn.Close() @@ -785,17 +785,17 @@ func (r *renewer) doRequest( c, err := dialer.Dial(ctx, remote) if err != nil { - return nil, serrors.WrapStr("dialing gRPC connection", err, "remote", remote) + return nil, serrors.Wrap("dialing gRPC connection", err, "remote", remote) } defer c.Close() client := cppb.NewChainRenewalServiceClient(c) reply, err := client.ChainRenewal(ctx, req, grpc.RetryProfile...) if err != nil { - return nil, serrors.WrapStr("requesting certificate chain", err, "remote", c.Target()) + return nil, serrors.Wrap("requesting certificate chain", err, "remote", c.Target()) } renewed, err := extractChain(reply) if err != nil { - return nil, serrors.WrapStr("extracting certificate chain from response", err) + return nil, serrors.Wrap("extracting certificate chain from response", err) } return renewed, nil } @@ -863,8 +863,9 @@ func loadChain(trcs []*cppki.TRC, file string) ([]*x509.Certificate, error) { fmt.Printf("Try to verify with the predecessor TRC: (Base = %d, Serial = %d)\n", trcs[0].ID.Base, trcs[0].ID.Serial-1) } - return nil, serrors.WrapStr( + return nil, serrors.Wrap( "verification of transport cert failed with provided TRC", err) + } return chain, nil } @@ -910,10 +911,10 @@ func extractChainLegacy(rep *cppb.ChainRenewalResponse) ([]*x509.Certificate, er } chain := make([]*x509.Certificate, 2) if chain[0], err = x509.ParseCertificate(replyBody.Chain.AsCert); err != nil { - return nil, serrors.WrapStr("parsing AS certificate", err) + return nil, serrors.Wrap("parsing AS certificate", err) } if chain[1], err = x509.ParseCertificate(replyBody.Chain.CaCert); err != nil { - return nil, serrors.WrapStr("parsing CA certificate", err) + return nil, serrors.Wrap("parsing CA certificate", err) } if err := cppki.ValidateChain(chain); err != nil { return nil, err diff --git a/scion-pki/certs/sign.go b/scion-pki/certs/sign.go index 15e28e29ad..08dc94237f 100644 --- a/scion-pki/certs/sign.go +++ b/scion-pki/certs/sign.go @@ -86,7 +86,7 @@ and not to \--not-before. RunE: func(cmd *cobra.Command, args []string) error { ct, err := parseCertType(flags.profile) if err != nil { - return serrors.WrapStr("parsing profile", err) + return serrors.Wrap("parsing profile", err) } if ct != cppki.AS && ct != cppki.CA { return serrors.New("not supported", "profile", flags.profile) @@ -96,7 +96,7 @@ and not to \--not-before. csrRaw, err := os.ReadFile(args[0]) if err != nil { - return serrors.WrapStr("loading CSR", err) + return serrors.Wrap("loading CSR", err) } csrPem, rest := pem.Decode(csrRaw) if len(rest) != 0 { @@ -104,20 +104,20 @@ and not to \--not-before. } csr, err := x509.ParseCertificateRequest(csrPem.Bytes) if err != nil { - return serrors.WrapStr("parsing CSR", err) + return serrors.Wrap("parsing CSR", err) } caCertRaw, err := os.ReadFile(flags.ca) if err != nil { - return serrors.WrapStr("read CA certificate", err) + return serrors.Wrap("read CA certificate", err) } caCert, err := parseCertificate(caCertRaw) if err != nil { - return serrors.WrapStr("parsing CA certificate", err) + return serrors.Wrap("parsing CA certificate", err) } caKey, err := key.LoadPrivateKey(flags.caKey) if err != nil { - return serrors.WrapStr("loading CA private key", err) + return serrors.Wrap("loading CA private key", err) } subject := csr.Subject @@ -133,15 +133,15 @@ and not to \--not-before. CACert: caCert, }) if err != nil { - return serrors.WrapStr("creating certificate", err) + return serrors.Wrap("creating certificate", err) } cert, err := x509.ParseCertificate(certRaw) if err != nil { - return serrors.WrapStr("parsing created certificate", err) + return serrors.Wrap("parsing created certificate", err) } if gt, err := cppki.ValidateCert(cert); err != nil { - return serrors.WrapStr("validating created certificate", err) + return serrors.Wrap("validating created certificate", err) } else if gt != ct { return serrors.New("created certificate with wrong type", "expected", ct, diff --git a/scion-pki/certs/verify.go b/scion-pki/certs/verify.go index 4a362511e5..ceaa7b2875 100644 --- a/scion-pki/certs/verify.go +++ b/scion-pki/certs/verify.go @@ -63,7 +63,7 @@ the expected ISD-AS value. cmd.SilenceUsage = true chain, err := cppki.ReadPEMCerts(args[0]) if err != nil { - return serrors.WrapStr("reading chain", err, "file", args[0]) + return serrors.Wrap("reading chain", err, "file", args[0]) } if len(chain) == 0 { return serrors.New("file does not contain any certificate") @@ -101,7 +101,7 @@ the expected ISD-AS value. } } if err := cppki.VerifyChain(chain, opts); err != nil { - return serrors.WrapStr("verification failed", err) + return serrors.Wrap("verification failed", err) } fmt.Printf("Successfully verified certificate chain: %q\n", args[0]) @@ -148,14 +148,14 @@ The CA certificate must be a PEM encoded. cmd.SilenceUsage = true certs, err := cppki.ReadPEMCerts(args[0]) if err != nil { - return serrors.WrapStr("reading certificate", err, "file", args[0]) + return serrors.Wrap("reading certificate", err, "file", args[0]) } if len(certs) != 1 { return serrors.New("file contains multiple certificates", "count", len(certs)) } ct, err := cppki.ValidateCert(certs[0]) if err != nil { - return serrors.WrapStr("validating CA certificate", err) + return serrors.Wrap("validating CA certificate", err) } if ct != cppki.CA { return serrors.New("certificate of wrong type", "type", ct) @@ -167,7 +167,7 @@ The CA certificate must be a PEM encoded. } rootPool, err := trc.TRC.RootPool() if err != nil { - return serrors.WrapStr("failed to extract root certificates from TRC", err) + return serrors.Wrap("failed to extract root certificates from TRC", err) } var currTime time.Time if flags.unixTime != 0 { @@ -179,7 +179,7 @@ The CA certificate must be a PEM encoded. CurrentTime: currTime, }) if err != nil { - return serrors.WrapStr("verification failed", err) + return serrors.Wrap("verification failed", err) } fmt.Printf("Successfully verified CA certificate: %q\n", args[0]) @@ -202,7 +202,7 @@ func loadTRC(trcFile string) (cppki.SignedTRC, error) { raw = block.Bytes } if err != nil { - return cppki.SignedTRC{}, serrors.WrapStr("reading TRC", err, "file", trcFile) + return cppki.SignedTRC{}, serrors.Wrap("reading TRC", err, "file", trcFile) } return cppki.DecodeSignedTRC(raw) } @@ -219,7 +219,7 @@ func loadTRCs(trcFiles []string) ([]*cppki.TRC, error) { } files, err := filepath.Glob(trcFile) if err != nil { - return nil, serrors.WrapStr("resolving TRC glob pattern", err) + return nil, serrors.Wrap("resolving TRC glob pattern", err) } resolvedTRCFiles = append(resolvedTRCFiles, files...) } @@ -228,14 +228,14 @@ func loadTRCs(trcFiles []string) ([]*cppki.TRC, error) { for _, trcFile := range resolvedTRCFiles { signedTRC, err := loadTRC(trcFile) if err != nil { - return nil, serrors.WrapStr("loading from disk", err) + return nil, serrors.Wrap("loading from disk", err) } signedTRCs = append(signedTRCs, signedTRC) } latestSignedTRCs, err := selectLatestTRCs(signedTRCs) if err != nil { - return nil, serrors.WrapStr("selecting latest TRCs", err) + return nil, serrors.Wrap("selecting latest TRCs", err) } return trcSlice(latestSignedTRCs), nil } diff --git a/scion-pki/cmd/scion-pki/gendocs.go b/scion-pki/cmd/scion-pki/gendocs.go index 371e27fd4b..f990b9218f 100644 --- a/scion-pki/cmd/scion-pki/gendocs.go +++ b/scion-pki/cmd/scion-pki/gendocs.go @@ -46,11 +46,11 @@ in the location given as an argument.`, return fmt.Sprintf(":ref:`%s <%s>`", name, ref) } if err := os.MkdirAll(directory, 0755); err != nil { - return serrors.WrapStr("creating directory", err, "directory", directory) + return serrors.Wrap("creating directory", err, "directory", directory) } err := doc.GenReSTTreeCustom(cmd.Parent(), directory, filePrepender, linkHandler) if err != nil { - return serrors.WrapStr("generating RST documentation", err) + return serrors.Wrap("generating RST documentation", err) } return nil diff --git a/scion-pki/conf/trc.go b/scion-pki/conf/trc.go index 28675ec73d..6c62bcf01b 100644 --- a/scion-pki/conf/trc.go +++ b/scion-pki/conf/trc.go @@ -49,7 +49,7 @@ type TRC struct { func LoadTRC(file string) (TRC, error) { var cfg TRC if err := config.LoadFile(file, &cfg); err != nil { - return TRC{}, serrors.WrapStr("unable to load TRC config from file", err, "file", file) + return TRC{}, serrors.Wrap("unable to load TRC config from file", err, "file", file) } cfg.relPath = filepath.Dir(file) return cfg, nil @@ -67,12 +67,12 @@ func (cfg *TRC) Certificates() ([]*x509.Certificate, error) { } read, err := cppki.ReadPEMCerts(certFile) if err != nil { - return nil, serrors.WithCtx(err, "file", certFile) + return nil, serrors.Wrap("reading certificate", err, "file", certFile) } for _, cert := range read { ct, err := cppki.ValidateCert(cert) if err != nil { - return nil, serrors.WithCtx(err, "file", certFile) + return nil, serrors.Wrap("validating certificate", err, "file", certFile) } if ct != cppki.Sensitive && ct != cppki.Regular && ct != cppki.Root { return nil, serrors.New("invalid certificate type", "file", certFile) diff --git a/scion-pki/file/file.go b/scion-pki/file/file.go index e2cabb5061..012160887f 100644 --- a/scion-pki/file/file.go +++ b/scion-pki/file/file.go @@ -91,7 +91,7 @@ func WriteFile(filename string, data []byte, perm os.FileMode, opts ...Option) e return os.WriteFile(filename, data, perm) } if err != nil { - return serrors.WrapStr("reading stat information", err) + return serrors.Wrap("reading stat information", err) } if info.IsDir() { return serrors.New("file is a directory") @@ -102,11 +102,11 @@ func WriteFile(filename string, data []byte, perm os.FileMode, opts ...Option) e ext := filepath.Ext(filename) backup := strings.TrimSuffix(filename, ext) + "." + options.backupPattern + ext if err := os.Rename(filename, backup); err != nil { - return serrors.WrapStr("backing up file", err) + return serrors.Wrap("backing up file", err) } case options.force: if err := os.Remove(filename); err != nil { - return serrors.WrapStr("removing existing file", err) + return serrors.Wrap("removing existing file", err) } default: return os.ErrExist diff --git a/scion-pki/key/fingerprint.go b/scion-pki/key/fingerprint.go index fae45cddc0..07d4c147ec 100644 --- a/scion-pki/key/fingerprint.go +++ b/scion-pki/key/fingerprint.go @@ -73,19 +73,19 @@ The subject key ID is written to standard out. if flags.fullKey { marshaledKey, err := x509.MarshalPKIXPublicKey(pub) if err != nil { - return serrors.WrapStr("full-key-digest", err) + return serrors.Wrap("full-key-digest", err) } cks := sha1.Sum(marshaledKey) skid = cks[:] } else { skid, err = cppki.SubjectKeyID(pub) if err != nil { - return serrors.WrapStr("computing subject key ID", err) + return serrors.Wrap("computing subject key ID", err) } } output, err := encoding.EncodeBytes(skid, flags.format) if err != nil { - return serrors.WrapStr("encoding subject key ID", err) + return serrors.Wrap("encoding subject key ID", err) } fmt.Fprintln(cmd.OutOrStdout(), output) return nil @@ -104,7 +104,7 @@ The subject key ID is written to standard out. func loadPublicKey(filename string) (crypto.PublicKey, error) { raw, err := os.ReadFile(filename) if err != nil { - return nil, serrors.WrapStr("reading input file", err) + return nil, serrors.Wrap("reading input file", err) } block, _ := pem.Decode(raw) if block == nil { @@ -114,7 +114,7 @@ func loadPublicKey(filename string) (crypto.PublicKey, error) { case "PRIVATE KEY": key, err := x509.ParsePKCS8PrivateKey(block.Bytes) if err != nil { - return nil, serrors.WrapStr("parsing private key", err) + return nil, serrors.Wrap("parsing private key", err) } pub, ok := key.(crypto.Signer) @@ -127,13 +127,13 @@ func loadPublicKey(filename string) (crypto.PublicKey, error) { case "PUBLIC KEY": pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return nil, serrors.WrapStr("parsing public key", err) + return nil, serrors.Wrap("parsing public key", err) } return pub, nil case "CERTIFICATE": cert, err := x509.ParseCertificate(block.Bytes) if err != nil { - return nil, serrors.WrapStr("parsing certificate", err) + return nil, serrors.Wrap("parsing certificate", err) } return cert.PublicKey, nil default: diff --git a/scion-pki/key/match.go b/scion-pki/key/match.go index 5bbfb4fc57..c69da0ab2b 100644 --- a/scion-pki/key/match.go +++ b/scion-pki/key/match.go @@ -68,7 +68,7 @@ The output contains all certificates that authenticate the key. } pub, err := x509.MarshalPKIXPublicKey(key.Public()) if err != nil { - return serrors.WrapStr("packing the public key", err) + return serrors.Wrap("packing the public key", err) } var certificates []string @@ -97,11 +97,11 @@ The output contains all certificates that authenticate the key. func loadPackedPublicFromCertificate(file string) ([]byte, error) { certs, err := cppki.ReadPEMCerts(file) if err != nil { - return nil, serrors.WrapStr("parsing certificate", err) + return nil, serrors.Wrap("parsing certificate", err) } pub, err := x509.MarshalPKIXPublicKey(certs[0].PublicKey) if err != nil { - return nil, serrors.WrapStr("packing the public key", err) + return nil, serrors.Wrap("packing the public key", err) } return pub, nil } diff --git a/scion-pki/key/private.go b/scion-pki/key/private.go index 4a9e6adf78..27dd019a1c 100644 --- a/scion-pki/key/private.go +++ b/scion-pki/key/private.go @@ -57,18 +57,18 @@ The contents are the private key in PKCS #8 ASN.1 DER format. filename := args[0] if err := file.CheckDirExists(filepath.Dir(filename)); err != nil { - return serrors.WrapStr("checking that directory of private key exists", err) + return serrors.Wrap("checking that directory of private key exists", err) } key, err := GeneratePrivateKey(flags.curve) if err != nil { - return serrors.WrapStr("generating private key", err) + return serrors.Wrap("generating private key", err) } raw, err := EncodePEMPrivateKey(key) if err != nil { - return serrors.WrapStr("encoding private key", err) + return serrors.Wrap("encoding private key", err) } if err := file.WriteFile(filename, raw, 0600, file.WithForce(flags.force)); err != nil { - return serrors.WrapStr("writing private key", err) + return serrors.Wrap("writing private key", err) } fmt.Printf("Private key successfully written to %q\n", filename) return nil diff --git a/scion-pki/key/public.go b/scion-pki/key/public.go index 38251ba8e8..6a587afea5 100644 --- a/scion-pki/key/public.go +++ b/scion-pki/key/public.go @@ -57,7 +57,7 @@ By default, the public key is written to standard out. out, err := x509.MarshalPKIXPublicKey(priv.Public()) if err != nil { - return serrors.WrapStr("encoding public key", err) + return serrors.Wrap("encoding public key", err) } encoded := pem.EncodeToMemory(&pem.Block{ Type: "PUBLIC KEY", @@ -73,11 +73,11 @@ By default, the public key is written to standard out. // Write public key to file system instead of stdout. if err := file.CheckDirExists(filepath.Dir(flags.out)); err != nil { - return serrors.WrapStr("checking that directory of public key exists", err) + return serrors.Wrap("checking that directory of public key exists", err) } err = file.WriteFile(flags.out, encoded, 0644, file.WithForce(flags.force)) if err != nil { - return serrors.WrapStr("writing public key", err) + return serrors.Wrap("writing public key", err) } fmt.Printf("Public key successfully written to %q\n", flags.out) return nil @@ -96,7 +96,7 @@ By default, the public key is written to standard out. func LoadPrivateKey(filename string) (crypto.Signer, error) { raw, err := os.ReadFile(filename) if err != nil { - return nil, serrors.WrapStr("reading private key", err) + return nil, serrors.Wrap("reading private key", err) } p, rest := pem.Decode(raw) if p == nil { @@ -111,7 +111,7 @@ func LoadPrivateKey(filename string) (crypto.Signer, error) { key, err := x509.ParsePKCS8PrivateKey(p.Bytes) if err != nil { - return nil, serrors.WrapStr("parsing private key", err) + return nil, serrors.Wrap("parsing private key", err) } priv, ok := key.(crypto.Signer) diff --git a/scion-pki/key/symmetric.go b/scion-pki/key/symmetric.go index 4edb96b079..26667de071 100644 --- a/scion-pki/key/symmetric.go +++ b/scion-pki/key/symmetric.go @@ -56,18 +56,18 @@ The content is the symmetrics key in the specified format (base64 or pem with SY return serrors.New("size must be a positive integer") } if err := file.CheckDirExists(filepath.Dir(filename)); err != nil { - return serrors.WrapStr("checking that directory of symmetric key exists", err) + return serrors.Wrap("checking that directory of symmetric key exists", err) } key, err := generatesymmetricKey(flags.size) if err != nil { - return serrors.WrapStr("generating symmetric key", err) + return serrors.Wrap("generating symmetric key", err) } raw, err := encodesymmetricKey(key, flags.format) if err != nil { - return serrors.WrapStr("encoding symmetric key", err) + return serrors.Wrap("encoding symmetric key", err) } if err := file.WriteFile(filename, raw, 0600, file.WithForce(flags.force)); err != nil { - return serrors.WrapStr("writing symmetric key", err) + return serrors.Wrap("writing symmetric key", err) } fmt.Printf("Symmetric key successfully written to %q\n", filename) return nil diff --git a/scion-pki/testcrypto/config.go b/scion-pki/testcrypto/config.go index 30ea8a3138..f67a75d049 100644 --- a/scion-pki/testcrypto/config.go +++ b/scion-pki/testcrypto/config.go @@ -38,11 +38,11 @@ type topo struct { func loadTopo(file string) (topo, error) { raw, err := os.ReadFile(file) if err != nil { - return topo{}, serrors.WrapStr("failed to load topofile", err, "file", file) + return topo{}, serrors.Wrap("failed to load topofile", err, "file", file) } var t topo if err := yaml.Unmarshal(raw, &t); err != nil { - return topo{}, serrors.WrapStr("failed to parse topofile", err, "file", file) + return topo{}, serrors.Wrap("failed to parse topofile", err, "file", file) } for ia, v := range t.ASes { if v.Issuing { diff --git a/scion-pki/testcrypto/testcrypto.go b/scion-pki/testcrypto/testcrypto.go index ceef5a65c3..f852998775 100644 --- a/scion-pki/testcrypto/testcrypto.go +++ b/scion-pki/testcrypto/testcrypto.go @@ -323,11 +323,11 @@ func createTRCs(cfg config) error { sort.Strings(trcConf.CertificateFiles) trc, err := trcs.CreatePayload(trcConf) if err != nil { - return serrors.WrapStr("creating TRC payload", err, "isd", isd) + return serrors.Wrap("creating TRC payload", err, "isd", isd) } raw, err := trc.Encode() if err != nil { - return serrors.WrapStr("encoding TRC payload", err, "isd", isd) + return serrors.Wrap("encoding TRC payload", err, "isd", isd) } parts := make(map[string]cppki.SignedTRC, len(voters[isd])*2) @@ -339,19 +339,19 @@ func createTRCs(cfg config) error { sensitive, err := signPayload(raw, voterInfo.sensitiveKey, voterInfo.sensitiveCert) if err != nil { - return serrors.WrapStr("signing TRC payload - sensitive", err) + return serrors.Wrap("signing TRC payload - sensitive", err) } parts[fmt.Sprintf("ISD%d-B1-S1.%s-sensitive.trc", isd, voter)] = sensitive regular, err := signPayload(raw, voterInfo.regularKey, voterInfo.regularCert) if err != nil { - return serrors.WrapStr("signing TRC payload - regular", err) + return serrors.Wrap("signing TRC payload - regular", err) } parts[fmt.Sprintf("ISD%d-B1-S1.%s-regular.trc", isd, voter)] = regular } combined, err := trcs.CombineSignedPayloads(parts) if err != nil { - return serrors.WrapStr("combining signed TRC payloads", err) + return serrors.Wrap("combining signed TRC payloads", err) } combined = pem.EncodeToMemory(&pem.Block{ Type: "TRC", @@ -359,7 +359,7 @@ func createTRCs(cfg config) error { }) if err := os.WriteFile(filepath.Join(trcDir(isd, cfg.out), fmt.Sprintf("ISD%d-B1-S1.trc", isd)), combined, 0644); err != nil { - return serrors.WrapStr("writing TRC", err) + return serrors.Wrap("writing TRC", err) } } return nil @@ -369,16 +369,16 @@ func loadVoterInfo(voter addr.IA, votingDir string) (*voterInfo, error) { sensitiveKey, err := key.LoadPrivateKey( filepath.Join(votingDir, "sensitive-voting.key")) if err != nil { - return nil, serrors.WrapStr("loading sensitive key", err) + return nil, serrors.Wrap("loading sensitive key", err) } regularKey, err := key.LoadPrivateKey(filepath.Join(votingDir, "regular-voting.key")) if err != nil { - return nil, serrors.WrapStr("loading regular key", err) + return nil, serrors.Wrap("loading regular key", err) } sensitiveCerts, err := cppki.ReadPEMCerts( filepath.Join(votingDir, sensitiveCertName(voter))) if err != nil { - return nil, serrors.WrapStr("loading sensitive cert", err) + return nil, serrors.Wrap("loading sensitive cert", err) } if len(sensitiveCerts) > 1 { return nil, serrors.New("more than one sensitive cert found", "ia", voter) @@ -386,7 +386,7 @@ func loadVoterInfo(voter addr.IA, votingDir string) (*voterInfo, error) { regularCerts, err := cppki.ReadPEMCerts( filepath.Join(votingDir, regularCertName(voter))) if err != nil { - return nil, serrors.WrapStr("loading regular cert", err) + return nil, serrors.Wrap("loading regular cert", err) } if len(regularCerts) > 1 { return nil, serrors.New("more than one regular cert found", "ia", voter) @@ -486,7 +486,7 @@ func flatten(out outConfig) error { for _, trc := range trcs { _, name := filepath.Split(trc) if err := copyFile(filepath.Join(out.base, "trcs", name), trc); err != nil { - return serrors.WithCtx(err, "file", trc) + return serrors.Wrap("copying", err, "file", trc) } } @@ -506,7 +506,7 @@ func flatten(out outConfig) error { for _, file := range append(pems, crts...) { _, name := filepath.Split(file) if err := copyFile(filepath.Join(out.base, "certs", name), file); err != nil { - return serrors.WithCtx(err, "file", file) + return serrors.Wrap("copying", err, "file", file) } } return nil diff --git a/scion-pki/testcrypto/update.go b/scion-pki/testcrypto/update.go index b71edebd91..db659a2b18 100644 --- a/scion-pki/testcrypto/update.go +++ b/scion-pki/testcrypto/update.go @@ -91,7 +91,7 @@ Scenarios: for _, file := range files { trc, err := trcs.DecodeFromFile(file) if err != nil { - return serrors.WrapStr("loading TRC", err, "file", file) + return serrors.Wrap("loading TRC", err, "file", file) } if trc.TRC.ID.Serial > isds[trc.TRC.ID.ISD].TRC.ID.Serial { isds[trc.TRC.ID.ISD] = trc @@ -108,11 +108,11 @@ Scenarios: switch flags.scenario { case "extend": if err := extendTRC(now, out, predecessor); err != nil { - return serrors.WrapStr("generating extension", err, "isd", isd) + return serrors.Wrap("generating extension", err, "isd", isd) } case "re-sign": if err := resignTRC(now, out, predecessor); err != nil { - return serrors.WrapStr("re-signing", err) + return serrors.Wrap("re-signing", err) } case "re-gen": if err := regenTRC(now, out, predecessor); err != nil { @@ -154,15 +154,15 @@ func extendTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error case cppki.Regular: key, err := findkey(cryptoVotingDir(ia, out), cert) if err != nil { - return serrors.WrapStr("searching key", err, "isd_as", ia, "type", t) + return serrors.Wrap("searching key", err, "isd_as", ia, "type", t) } extended, err := extendCert(now, cert, key) if err != nil { - return serrors.WrapStr("creating certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("creating certificate", err, "isd_as", ia, "type", t) } file := filepath.Join(out.base, "certs", regularCertName(ia, int(id.Serial))) if err := writeCert(file, extended); err != nil { - return serrors.WrapStr("writing certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("writing certificate", err, "isd_as", ia, "type", t) } // Cast vote and show proof of possession. signers[cert] = key @@ -172,15 +172,15 @@ func extendTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error case cppki.Root: key, err := findkey(cryptoCADir(ia, out), cert) if err != nil { - return serrors.WrapStr("searching key", err, "isd_as", ia, "type", t) + return serrors.Wrap("searching key", err, "isd_as", ia, "type", t) } extended, err := extendCert(now, cert, key) if err != nil { - return serrors.WrapStr("creating certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("creating certificate", err, "isd_as", ia, "type", t) } file := filepath.Join(out.base, "certs", rootCertName(ia, int(id.Serial))) if err := writeCert(file, extended); err != nil { - return serrors.WrapStr("writing certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("writing certificate", err, "isd_as", ia, "type", t) } // Show acknowledgment signers[cert] = key @@ -207,7 +207,7 @@ func extendTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error } trc, err := signTRC(pld, signers) if err != nil { - return serrors.WrapStr("signing TRC", err) + return serrors.Wrap("signing TRC", err) } return writeTRC(out, trc) } @@ -228,7 +228,7 @@ func resignTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error if t == cppki.Regular { key, err := findkey(cryptoVotingDir(ia, out), cert) if err != nil { - return serrors.WrapStr("searching key", err, "isd_as", ia, "type", t) + return serrors.Wrap("searching key", err, "isd_as", ia, "type", t) } signers[cert] = key votes = append(votes, i) @@ -257,7 +257,7 @@ func resignTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error } trc, err := signTRC(pld, signers) if err != nil { - return serrors.WrapStr("signing TRC", err) + return serrors.Wrap("signing TRC", err) } return writeTRC(out, trc) } @@ -286,7 +286,7 @@ func regenTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error { dir := cryptoVotingDir(ia, out) key, err := findkey(dir, cert) if err != nil { - return serrors.WrapStr("searching key", err, "isd_as", ia, "type", t) + return serrors.Wrap("searching key", err, "isd_as", ia, "type", t) } newKey, err := createKey(fmt.Sprintf("%s/sensitive-voting.s%d.key", dir, id.Serial)) if err != nil { @@ -294,11 +294,11 @@ func regenTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error { } newCert, err := extendCert(now, cert, newKey) if err != nil { - return serrors.WrapStr("creating certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("creating certificate", err, "isd_as", ia, "type", t) } file := filepath.Join(out.base, "certs", sensitiveCertName(ia, int(id.Serial))) if err := writeCert(file, newCert); err != nil { - return serrors.WrapStr("writing certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("writing certificate", err, "isd_as", ia, "type", t) } // Cast vote and show proof of possession. signers[cert] = key @@ -313,11 +313,11 @@ func regenTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error { } newCert, err := extendCert(now, cert, newKey) if err != nil { - return serrors.WrapStr("creating certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("creating certificate", err, "isd_as", ia, "type", t) } file := filepath.Join(out.base, "certs", regularCertName(ia, int(id.Serial))) if err := writeCert(file, newCert); err != nil { - return serrors.WrapStr("writing certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("writing certificate", err, "isd_as", ia, "type", t) } // Show proof of possession. signers[newCert] = newKey @@ -330,11 +330,11 @@ func regenTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error { } newCert, err := extendCert(now, cert, newKey) if err != nil { - return serrors.WrapStr("creating certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("creating certificate", err, "isd_as", ia, "type", t) } file := filepath.Join(out.base, "certs", rootCertName(ia, int(id.Serial))) if err := writeCert(file, newCert); err != nil { - return serrors.WrapStr("writing certificate", err, "isd_as", ia, "type", t) + return serrors.Wrap("writing certificate", err, "isd_as", ia, "type", t) } include = append(include, newCert) } @@ -357,7 +357,7 @@ func regenTRC(now time.Time, out outConfig, predecessor cppki.SignedTRC) error { } trc, err := signTRC(pld, signers) if err != nil { - return serrors.WrapStr("signing TRC", err) + return serrors.Wrap("signing TRC", err) } return writeTRC(out, trc) } @@ -377,7 +377,8 @@ func signTRC(pld cppki.TRC, signers map[*x509.Certificate]crypto.Signer) (cppki. } for cert, key := range signers { if err := sd.AddSignerInfo([]*x509.Certificate{cert}, key); err != nil { - return cppki.SignedTRC{}, serrors.WithCtx(err, "common_name", cert.Subject.CommonName) + return cppki.SignedTRC{}, serrors.Wrap("adding signer info", err, + "common_name", cert.Subject.CommonName) } } @@ -435,7 +436,7 @@ func createKey(file string) (crypto.Signer, error) { return nil, serrors.New("failed to pack private key") } if err := os.WriteFile(file, raw, 0644); err != nil { - return nil, serrors.WrapStr("writing private key", err) + return nil, serrors.Wrap("writing private key", err) } return key, nil } @@ -446,7 +447,7 @@ func extendCert(now time.Time, cert *x509.Certificate, // Choose random serial number. serial := make([]byte, 20) if _, err := rand.Read(serial); err != nil { - return nil, serrors.WrapStr("creating random serial number", err) + return nil, serrors.Wrap("creating random serial number", err) } // ExtraNames are used for marshaling subject := cert.Subject @@ -481,7 +482,7 @@ func writeCert(file string, cert *x509.Certificate) error { func writeTRC(out outConfig, trc cppki.SignedTRC) error { raw, err := trc.Encode() if err != nil { - return serrors.WrapStr("encoding TRC", err) + return serrors.Wrap("encoding TRC", err) } file := filepath.Join(out.base, "trcs", fmt.Sprintf("ISD%d-B%d-S%d.trc", trc.TRC.ID.ISD, trc.TRC.ID.Base, trc.TRC.ID.Serial)) diff --git a/scion-pki/trcs/combine.go b/scion-pki/trcs/combine.go index e7fd868406..0e6f33cf8c 100644 --- a/scion-pki/trcs/combine.go +++ b/scion-pki/trcs/combine.go @@ -72,7 +72,7 @@ func RunCombine(files []string, pld, out string, format string) error { for _, name := range files { dec, err := DecodeFromFile(name) if err != nil { - return serrors.WrapStr("error decoding part", err, "file", name) + return serrors.Wrap("error decoding part", err, "file", name) } trcs[name] = dec } @@ -90,7 +90,7 @@ func RunCombine(files []string, pld, out string, format string) error { }) } if err := os.WriteFile(out, packed, 0644); err != nil { - return serrors.WrapStr("error writing combined TRC", err) + return serrors.Wrap("error writing combined TRC", err) } fmt.Printf("Successfully combined TRC at %s\n", out) return nil @@ -114,7 +114,7 @@ func CombineSignedPayloads(trcs map[string]cppki.SignedTRC) ([]byte, error) { } eci, err := protocol.NewDataEncapsulatedContentInfo(pld) if err != nil { - return nil, serrors.WrapStr("error encoding payload", err) + return nil, serrors.Wrap("error encoding payload", err) } sd := protocol.SignedData{ Version: 1, @@ -125,7 +125,7 @@ func CombineSignedPayloads(trcs map[string]cppki.SignedTRC) ([]byte, error) { // Write signed TRC. packed, err := sd.ContentInfoDER() if err != nil { - return nil, serrors.WrapStr("error packing combined TRC", err) + return nil, serrors.Wrap("error packing combined TRC", err) } return packed, nil } @@ -200,7 +200,7 @@ func verifyPayload(pld string, trcs map[string]cppki.SignedTRC) error { var err error rawPld, err = os.ReadFile(pld) if err != nil { - return serrors.WrapStr("error loading payload", err) + return serrors.Wrap("error loading payload", err) } block, _ := pem.Decode(rawPld) if block != nil && block.Type == "TRC PAYLOAD" { diff --git a/scion-pki/trcs/extract.go b/scion-pki/trcs/extract.go index 7ff915afa9..aca2e8f48e 100644 --- a/scion-pki/trcs/extract.go +++ b/scion-pki/trcs/extract.go @@ -62,7 +62,7 @@ To inspect the created asn.1 file you can use the openssl tool:: RunE: func(cmd *cobra.Command, args []string) error { signed, err := DecodeFromFile(args[0]) if err != nil { - return serrors.WrapStr("failed to load signed TRC", err) + return serrors.Wrap("failed to load signed TRC", err) } raw := signed.TRC.Raw if flags.format == "pem" { @@ -72,7 +72,7 @@ To inspect the created asn.1 file you can use the openssl tool:: }) } if err := os.WriteFile(flags.out, raw, 0644); err != nil { - return serrors.WrapStr("failed to write extracted payload", err) + return serrors.Wrap("failed to write extracted payload", err) } fmt.Printf("Successfully extracted payload at %s\n", flags.out) return nil @@ -112,7 +112,7 @@ func newExtractCertificates(pather command.Pather) *cobra.Command { func runExtractCertificates(in, out string) error { signed, err := DecodeFromFile(in) if err != nil { - return serrors.WrapStr("failed to load signed TRC", err) + return serrors.Wrap("failed to load signed TRC", err) } return writeBundle(out, signed.TRC.Certificates) } @@ -120,7 +120,7 @@ func runExtractCertificates(in, out string) error { func writeBundle(out string, certs []*x509.Certificate) error { file, err := os.Create(out) if err != nil { - return serrors.WrapStr("unable to create file", err) + return serrors.Wrap("unable to create file", err) } defer file.Close() for i, cert := range certs { @@ -129,7 +129,7 @@ func writeBundle(out string, certs []*x509.Certificate) error { Bytes: cert.Raw, } if err := pem.Encode(file, &block); err != nil { - return serrors.WrapStr("unable to encode certificate", err, "index", i) + return serrors.Wrap("unable to encode certificate", err, "index", i) } } return nil diff --git a/scion-pki/trcs/format.go b/scion-pki/trcs/format.go index d3598b8b7e..2e42ffba42 100644 --- a/scion-pki/trcs/format.go +++ b/scion-pki/trcs/format.go @@ -58,7 +58,7 @@ redirected to a file because the raw characters might mess up the terminal. } if flags.out != "" { if err := file.CheckDirExists(filepath.Dir(flags.out)); err != nil { - return serrors.WrapStr("checking that output directory exists", err) + return serrors.Wrap("checking that output directory exists", err) } } cmd.SilenceUsage = true @@ -66,7 +66,7 @@ redirected to a file because the raw characters might mess up the terminal. filename := args[0] raw, err := os.ReadFile(filename) if err != nil { - return serrors.WrapStr("reading file", err) + return serrors.Wrap("reading file", err) } var output []byte @@ -101,7 +101,7 @@ redirected to a file because the raw characters might mess up the terminal. err = file.WriteFile(flags.out, output, 0644, file.WithForce(flags.force)) if err != nil { - return serrors.WrapStr("writing to output file", err) + return serrors.Wrap("writing to output file", err) } fmt.Printf("Transformation successfully written to %q\n", flags.out) return nil diff --git a/scion-pki/trcs/human.go b/scion-pki/trcs/human.go index 1c5e213453..17f12384ea 100644 --- a/scion-pki/trcs/human.go +++ b/scion-pki/trcs/human.go @@ -126,7 +126,7 @@ func getHumanEncoding(raw []byte, predTRC *cppki.TRC, strict bool) (humanTRC, er for i, info := range signed.SignerInfos { d, err := newSignerInfo(info, predCerts) if err != nil && strict { - return humanTRC{}, serrors.WrapStr("decoding signer info", err, "index", i) + return humanTRC{}, serrors.Wrap("decoding signer info", err, "index", i) } h.Signatures = append(h.Signatures, d) } @@ -194,7 +194,7 @@ func (h *humanTRC) setTRC(trc cppki.TRC) error { for i, cert := range trc.Certificates { if t, err := cppki.ValidateCert(cert); err != nil { h.Certificates = append(h.Certificates, certDesc{Error: err.Error()}) - errs = append(errs, serrors.WrapStr("classifying certificate", err, "index", i)) + errs = append(errs, serrors.Wrap("classifying certificate", err, "index", i)) } else { desc := certDesc{ CommonName: cert.Subject.CommonName, diff --git a/scion-pki/trcs/payload.go b/scion-pki/trcs/payload.go index f098ba5e49..c2ba9fc182 100644 --- a/scion-pki/trcs/payload.go +++ b/scion-pki/trcs/payload.go @@ -60,7 +60,7 @@ To inspect the created asn.1 file you can use the openssl tool:: cmd.SilenceUsage = true cfg, err := conf.LoadTRC(flags.tmpl) if err != nil { - return serrors.WrapStr("failed to load template file", err) + return serrors.Wrap("failed to load template file", err) } pred, err := loadPredecessor(cfg.SerialVersion == cfg.BaseVersion, flags.pred) @@ -70,18 +70,18 @@ To inspect the created asn.1 file you can use the openssl tool:: prepareCfg(&cfg, pred) trc, err := CreatePayload(cfg) if err != nil { - return serrors.WrapStr("failed to marshal TRC", err) + return serrors.Wrap("failed to marshal TRC", err) } if pred != nil { update, err := trc.ValidateUpdate(pred) if err != nil { - return serrors.WrapStr("validating update", err) + return serrors.Wrap("validating update", err) } printUpdate(update) } raw, err := trc.Encode() if err != nil { - return serrors.WrapStr("encoding payload", err) + return serrors.Wrap("encoding payload", err) } if flags.format == "pem" { raw = pem.EncodeToMemory(&pem.Block{ @@ -91,7 +91,7 @@ To inspect the created asn.1 file you can use the openssl tool:: } err = os.WriteFile(flags.out, raw, 0644) if err != nil { - return serrors.WrapStr("failed to write file", err, "file", flags.out) + return serrors.Wrap("failed to write file", err, "file", flags.out) } fmt.Printf("Successfully created payload at %s\n", flags.out) return nil @@ -120,7 +120,7 @@ func loadPredecessor(base bool, pred string) (*cppki.TRC, error) { } trc, err := DecodeFromFile(pred) if err != nil { - return nil, serrors.WrapStr("loading predecessor TRC", err, "file", pred) + return nil, serrors.Wrap("loading predecessor TRC", err, "file", pred) } fmt.Println("Generating payload for TRC update.") return &trc.TRC, nil diff --git a/scion-pki/trcs/sign.go b/scion-pki/trcs/sign.go index 6307bf38ee..9da3246454 100644 --- a/scion-pki/trcs/sign.go +++ b/scion-pki/trcs/sign.go @@ -80,7 +80,7 @@ func RunSign(pld, certfile, keyfile, out, outDir string) error { // Read TRC payload rawPld, err := os.ReadFile(pld) if err != nil { - return serrors.WrapStr("error loading payload", err) + return serrors.Wrap("error loading payload", err) } pldBlock, _ := pem.Decode(rawPld) if pldBlock != nil && pldBlock.Type == "TRC PAYLOAD" { @@ -94,7 +94,7 @@ func RunSign(pld, certfile, keyfile, out, outDir string) error { // Load signing cert rawCert, err := os.ReadFile(certfile) if err != nil { - return serrors.WrapStr("error loading signer", err) + return serrors.Wrap("error loading signer", err) } certBlock, rest := pem.Decode(rawCert) if certBlock != nil { @@ -108,19 +108,19 @@ func RunSign(pld, certfile, keyfile, out, outDir string) error { } cert, err := x509.ParseCertificate(rawCert) if err != nil { - return serrors.WrapStr("error parsing signer", err) + return serrors.Wrap("error parsing signer", err) } signed, err := SignPayload(rawPld, priv, cert) if err != nil { - return serrors.WrapStr("error signing TRC payload", err) + return serrors.Wrap("error signing TRC payload", err) } // Verify the signed TRC payload as a sanity check signedTRC, err := cppki.DecodeSignedTRC(signed) if err != nil { - return serrors.WrapStr("error decoding signed TRC payload", err) + return serrors.Wrap("error decoding signed TRC payload", err) } if err := verifyBundle(signedTRC, []*x509.Certificate{cert}); err != nil { - return serrors.WrapStr("error verifying singed TRC payload", err) + return serrors.Wrap("error verifying singed TRC payload", err) } signed = pem.EncodeToMemory(&pem.Block{ Type: "TRC", @@ -131,7 +131,7 @@ func RunSign(pld, certfile, keyfile, out, outDir string) error { return err } if err := os.WriteFile(fname, signed, 0644); err != nil { - return serrors.WrapStr("error writing signed TRC paylod", err) + return serrors.Wrap("error writing signed TRC paylod", err) } fmt.Printf("Successfully signed TRC payload at %s\n", out) return nil @@ -162,11 +162,11 @@ func outPath(out, outDir string, trc *cppki.TRC, cert *x509.Certificate) (string } ia, err := cppki.ExtractIA(cert.Subject) if err != nil { - return "", serrors.WrapStr("extracting ISD-AS from signing certificate", err) + return "", serrors.Wrap("extracting ISD-AS from signing certificate", err) } signType, err := signatureType(trc, cert) if err != nil { - return "", serrors.WrapStr("determining cert type", err) + return "", serrors.Wrap("determining cert type", err) } fname := fmt.Sprintf("ISD%d-B%d-S%d.%s-%s.trc", trc.ID.ISD, trc.ID.Base, trc.ID.Serial, addr.FormatIA(ia, addr.WithFileSeparator()), signType) diff --git a/scion-pki/trcs/verify.go b/scion-pki/trcs/verify.go index 2dca358e86..838e56a4d0 100644 --- a/scion-pki/trcs/verify.go +++ b/scion-pki/trcs/verify.go @@ -71,7 +71,7 @@ func RunVerify(files []string, anchor string, isd addr.ISD) error { for _, name := range files { dec, err := DecodeFromFile(name) if err != nil { - return serrors.WrapStr("error decoding TRC", err, "file", name) + return serrors.Wrap("error decoding TRC", err, "file", name) } trcs = append(trcs, dec) } @@ -104,12 +104,12 @@ func RunVerify(files []string, anchor string, isd addr.ISD) error { } } if err := verifyInitial(trcs[0], anchor); err != nil { - return serrors.WrapStr("verifying first TRC in update chain", err, "id", trcs[0].TRC.ID) + return serrors.Wrap("verifying first TRC in update chain", err, "id", trcs[0].TRC.ID) } fmt.Println("Verified TRC successfully:", trcs[0].TRC.ID) for i := 1; i < len(trcs); i++ { if err := trcs[i].Verify(&trcs[i-1].TRC); err != nil { - return serrors.WrapStr("verifying TRC update", err, "id", trcs[i].TRC.ID) + return serrors.Wrap("verifying TRC update", err, "id", trcs[i].TRC.ID) } fmt.Println("Verified TRC successfully:", trcs[i].TRC.ID) } @@ -120,20 +120,20 @@ func verifyInitial(trc cppki.SignedTRC, anchor string) error { if !trc.TRC.ID.IsBase() { a, err := DecodeFromFile(anchor) if err != nil { - return serrors.WrapStr("loading TRC anchor", err, "anchor", anchor) + return serrors.Wrap("loading TRC anchor", err, "anchor", anchor) } return trc.Verify(&a.TRC) } if err := trc.Verify(nil); err != nil { - return serrors.WrapStr("verifying proof of possession", err) + return serrors.Wrap("verifying proof of possession", err) } certs, err := loadAnchorCerts(anchor) if err != nil { - return serrors.WithCtx(err, "anchor", anchor) + return serrors.Wrap("loading anchor", err, "anchor", anchor) } if err := verifyBundle(trc, certs); err != nil { - return serrors.WrapStr("checking verifiable with bundled certificates", err) + return serrors.Wrap("checking verifiable with bundled certificates", err) } return nil } @@ -153,7 +153,7 @@ func loadAnchorCerts(file string) ([]*x509.Certificate, error) { return certs, nil } errs := serrors.List{trcErr, certErr} - return nil, serrors.WrapStr("anchor contents not supported", errs.ToError()) + return nil, serrors.Wrap("anchor contents not supported", errs.ToError()) } func verifyBundle(signed cppki.SignedTRC, certs []*x509.Certificate) error { @@ -162,7 +162,7 @@ func verifyBundle(signed cppki.SignedTRC, certs []*x509.Certificate) error { } for i, si := range signed.SignerInfos { if err := verifySignerInfo(si, signed.TRC.Raw, certs); err != nil { - return serrors.WithCtx(err, "index", i) + return serrors.WrapNoStack("verifying signer info", err, "index", i) } } return nil @@ -174,7 +174,7 @@ func verifySignerInfo(si protocol.SignerInfo, pld []byte, certs []*x509.Certific } siContentType, err := si.GetContentTypeAttribute() if err != nil { - return serrors.WrapStr("error getting ContentType", err) + return serrors.Wrap("error getting ContentType", err) } if !siContentType.Equal(oid.ContentTypeData) { return serrors.New("SignerInfo with invalid ContentType", "type", siContentType) @@ -185,7 +185,7 @@ func verifySignerInfo(si protocol.SignerInfo, pld []byte, certs []*x509.Certific } attrDigest, err := si.GetMessageDigestAttribute() if err != nil { - return serrors.WrapStr("SignerInfo with invalid message digest", err) + return serrors.Wrap("SignerInfo with invalid message digest", err) } actualDigest := hash.New() actualDigest.Write(pld) @@ -194,7 +194,7 @@ func verifySignerInfo(si protocol.SignerInfo, pld []byte, certs []*x509.Certific } input, err := si.SignedAttrs.MarshaledForVerifying() if err != nil { - return serrors.WrapStr("error marshalling signature input", err) + return serrors.Wrap("error marshalling signature input", err) } // FIXME(roosd): this also finds certificates based on subject key id. cert, err := si.FindCertificate(certs) diff --git a/scion/cmd/scion/address.go b/scion/cmd/scion/address.go index df9e34f9c8..5ee64bb559 100644 --- a/scion/cmd/scion/address.go +++ b/scion/cmd/scion/address.go @@ -65,7 +65,7 @@ case, the host could have multiple SCION addresses. defer cancelF() sd, err := daemon.NewService(daemonAddr).Connect(ctx) if err != nil { - return serrors.WrapStr("connecting to SCION Daemon", err) + return serrors.Wrap("connecting to SCION Daemon", err) } defer sd.Close() diff --git a/scion/cmd/scion/gendocs.go b/scion/cmd/scion/gendocs.go index 924938087d..594364cad1 100644 --- a/scion/cmd/scion/gendocs.go +++ b/scion/cmd/scion/gendocs.go @@ -46,11 +46,11 @@ in the location given as an argument.`, return fmt.Sprintf(":ref:`%s <%s>`", name, ref) } if err := os.MkdirAll(directory, 0755); err != nil { - return serrors.WrapStr("creating directory", err, "directory", directory) + return serrors.Wrap("creating directory", err, "directory", directory) } err := doc.GenReSTTreeCustom(cmd.Parent(), directory, filePrepender, linkHandler) if err != nil { - return serrors.WrapStr("generating RST documentation", err) + return serrors.Wrap("generating RST documentation", err) } return nil diff --git a/scion/cmd/scion/ping.go b/scion/cmd/scion/ping.go index 48da4d60db..85645eccef 100644 --- a/scion/cmd/scion/ping.go +++ b/scion/cmd/scion/ping.go @@ -111,19 +111,19 @@ On other errors, ping will exit with code 2. RunE: func(cmd *cobra.Command, args []string) error { remote, err := addr.ParseAddr(args[0]) if err != nil { - return serrors.WrapStr("parsing remote", err) + return serrors.Wrap("parsing remote", err) } if err := app.SetupLog(flags.logLevel); err != nil { - return serrors.WrapStr("setting up logging", err) + return serrors.Wrap("setting up logging", err) } closer, err := setupTracer("ping", flags.tracer) if err != nil { - return serrors.WrapStr("setting up tracing", err) + return serrors.Wrap("setting up tracing", err) } defer closer() printf, err := getPrintf(flags.format, cmd.OutOrStdout()) if err != nil { - return serrors.WrapStr("get formatting", err) + return serrors.Wrap("get formatting", err) } cmd.SilenceUsage = true @@ -147,7 +147,7 @@ On other errors, ping will exit with code 2. defer cancelF() sd, err := daemon.NewService(daemonAddr).Connect(ctx) if err != nil { - return serrors.WrapStr("connecting to SCION Daemon", err) + return serrors.Wrap("connecting to SCION Daemon", err) } defer sd.Close() @@ -200,7 +200,7 @@ On other errors, ping will exit with code 2. target = nextHop.IP } if localIP, err = addrutil.ResolveLocal(target); err != nil { - return serrors.WrapStr("resolving local address", err) + return serrors.Wrap("resolving local address", err) } printf("Resolved local address:\n %s\n", localIP) diff --git a/scion/cmd/scion/showpaths.go b/scion/cmd/scion/showpaths.go index 55141ea5a1..703152e690 100644 --- a/scion/cmd/scion/showpaths.go +++ b/scion/cmd/scion/showpaths.go @@ -73,14 +73,14 @@ On other errors, showpaths will exit with code 2. RunE: func(cmd *cobra.Command, args []string) error { dst, err := addr.ParseIA(args[0]) if err != nil { - return serrors.WrapStr("invalid destination ISD-AS", err) + return serrors.Wrap("invalid destination ISD-AS", err) } if err := app.SetupLog(flags.logLevel); err != nil { - return serrors.WrapStr("setting up logging", err) + return serrors.Wrap("setting up logging", err) } closer, err := setupTracer("showpaths", flags.tracer) if err != nil { - return serrors.WrapStr("setting up tracing", err) + return serrors.Wrap("setting up tracing", err) } defer closer() @@ -89,7 +89,7 @@ On other errors, showpaths will exit with code 2. } printf, err := getPrintf(flags.format, cmd.OutOrStdout()) if err != nil { - return serrors.WrapStr("get formatting", err) + return serrors.Wrap("get formatting", err) } cmd.SilenceUsage = true diff --git a/scion/cmd/scion/traceroute.go b/scion/cmd/scion/traceroute.go index 4438ccf1cf..51777d9c39 100644 --- a/scion/cmd/scion/traceroute.go +++ b/scion/cmd/scion/traceroute.go @@ -87,19 +87,19 @@ On other errors, traceroute will exit with code 2. RunE: func(cmd *cobra.Command, args []string) error { remote, err := addr.ParseAddr(args[0]) if err != nil { - return serrors.WrapStr("parsing remote", err) + return serrors.Wrap("parsing remote", err) } if err := app.SetupLog(flags.logLevel); err != nil { - return serrors.WrapStr("setting up logging", err) + return serrors.Wrap("setting up logging", err) } closer, err := setupTracer("traceroute", flags.tracer) if err != nil { - return serrors.WrapStr("setting up tracing", err) + return serrors.Wrap("setting up tracing", err) } defer closer() printf, err := getPrintf(flags.format, cmd.OutOrStdout()) if err != nil { - return serrors.WrapStr("get formatting", err) + return serrors.Wrap("get formatting", err) } cmd.SilenceUsage = true @@ -122,7 +122,7 @@ On other errors, traceroute will exit with code 2. defer cancelF() sd, err := daemon.NewService(daemonAddr).Connect(ctx) if err != nil { - return serrors.WrapStr("connecting to SCION Daemon", err) + return serrors.Wrap("connecting to SCION Daemon", err) } defer sd.Close() info, err := app.QueryASInfo(traceCtx, sd) @@ -155,7 +155,7 @@ On other errors, traceroute will exit with code 2. target = nextHop.IP } if localIP, err = addrutil.ResolveLocal(target); err != nil { - return serrors.WrapStr("resolving local address", err) + return serrors.Wrap("resolving local address", err) } printf("Resolved local address:\n %s\n", localIP) } diff --git a/scion/ping/ping.go b/scion/ping/ping.go index 1dc0e1b76b..cf0d65f3e7 100644 --- a/scion/ping/ping.go +++ b/scion/ping/ping.go @@ -205,7 +205,7 @@ func (p *pinger) Ping( defer wg.Done() for i := uint16(0); i < p.attempts; i++ { if err := p.send(remote, dPath, nextHop); err != nil { - errSend <- serrors.WrapStr("sending", err) + errSend <- serrors.Wrap("sending", err) return } select { @@ -306,7 +306,7 @@ func (p *pinger) drain(ctx context.Context) { if err := p.conn.ReadFrom(&pkt, &ov); err != nil && p.errHandler != nil { // Rate limit the error reports. if now := time.Now(); now.Sub(last) > 500*time.Millisecond { - p.errHandler(serrors.WrapStr("reading packet", err)) + p.errHandler(serrors.Wrap("reading packet", err)) last = now } } diff --git a/scion/showpaths/showpaths.go b/scion/showpaths/showpaths.go index 37319efd0d..7f5457279e 100644 --- a/scion/showpaths/showpaths.go +++ b/scion/showpaths/showpaths.go @@ -306,12 +306,12 @@ func (r Result) Alive() int { func Run(ctx context.Context, dst addr.IA, cfg Config) (*Result, error) { sdConn, err := daemon.NewService(cfg.Daemon).Connect(ctx) if err != nil { - return nil, serrors.WrapStr("connecting to the SCION Daemon", err, "addr", cfg.Daemon) + return nil, serrors.Wrap("connecting to the SCION Daemon", err, "addr", cfg.Daemon) } defer sdConn.Close() localIA, err := sdConn.LocalIA(ctx) if err != nil { - return nil, serrors.WrapStr("determining local ISD-AS", err) + return nil, serrors.Wrap("determining local ISD-AS", err) } if dst == localIA { return &Result{ @@ -326,7 +326,7 @@ func Run(ctx context.Context, dst addr.IA, cfg Config) (*Result, error) { allPaths, err := sdConn.Paths(ctx, dst, 0, daemon.PathReqFlags{Refresh: cfg.Refresh}) if err != nil { - return nil, serrors.WrapStr("retrieving paths from the SCION Daemon", err) + return nil, serrors.Wrap("retrieving paths from the SCION Daemon", err) } paths, err := path.Filter(cfg.Sequence, allPaths) if err != nil { @@ -358,7 +358,7 @@ func Run(ctx context.Context, dst addr.IA, cfg Config) (*Result, error) { Topology: sdConn, }.GetStatuses(ctx, p, pathprobe.WithEPIC(cfg.Epic)) if err != nil { - return nil, serrors.WrapStr("getting statuses", err) + return nil, serrors.Wrap("getting statuses", err) } } path.Sort(paths) diff --git a/scion/traceroute/traceroute.go b/scion/traceroute/traceroute.go index 9221090130..067fd7be5e 100644 --- a/scion/traceroute/traceroute.go +++ b/scion/traceroute/traceroute.go @@ -146,7 +146,7 @@ func (t *tracerouter) Traceroute(ctx context.Context) (Stats, error) { var idxPath scion.Decoded if err := idxPath.DecodeFromBytes(scionPath.Raw); err != nil { - return t.stats, serrors.WrapStr("decoding path", err) + return t.stats, serrors.Wrap("decoding path", err) } ctx, cancel := context.WithCancel(ctx) defer cancel() @@ -166,7 +166,7 @@ func (t *tracerouter) Traceroute(ctx context.Context) (Stats, error) { if i != 0 && !prevXover { u, err := t.probeHop(ctx, hf, !info.ConsDir) if err != nil { - return t.stats, serrors.WrapStr("probing hop", err, "hop_index", i) + return t.stats, serrors.Wrap("probing hop", err, "hop_index", i) } if t.updateHandler != nil && !u.empty() { t.updateHandler(u) @@ -183,7 +183,7 @@ func (t *tracerouter) Traceroute(ctx context.Context) (Stats, error) { if i < len(idxPath.HopFields)-1 && !xover { u, err := t.probeHop(ctx, hf, info.ConsDir) if err != nil { - return t.stats, serrors.WrapStr("probing hop", err, "hop_index", i) + return t.stats, serrors.Wrap("probing hop", err, "hop_index", i) } if t.updateHandler != nil && !u.empty() { t.updateHandler(u) @@ -191,7 +191,7 @@ func (t *tracerouter) Traceroute(ctx context.Context) (Stats, error) { } if i < len(idxPath.HopFields)-1 { if err := idxPath.IncPath(); err != nil { - return t.stats, serrors.WrapStr("incrementing path", err) + return t.stats, serrors.Wrap("incrementing path", err) } } prevXover = xover @@ -202,7 +202,7 @@ func (t *tracerouter) Traceroute(ctx context.Context) (Stats, error) { func (t *tracerouter) probeHop(ctx context.Context, hfIdx uint8, egress bool) (Update, error) { var decoded scion.Decoded if err := decoded.DecodeFromBytes(t.path.Dataplane().(path.SCION).Raw); err != nil { - return Update{}, serrors.WrapStr("decoding path", err) + return Update{}, serrors.Wrap("decoding path", err) } hf := &decoded.HopFields[hfIdx] @@ -214,7 +214,7 @@ func (t *tracerouter) probeHop(ctx context.Context, hfIdx uint8, egress bool) (U scionAlertPath, err := path.NewSCIONFromDecoded(decoded) if err != nil { - return Update{}, serrors.WrapStr("setting alert flag", err) + return Update{}, serrors.Wrap("setting alert flag", err) } var alertPath snet.DataplanePath @@ -249,7 +249,7 @@ func (t *tracerouter) probeHop(ctx context.Context, hfIdx uint8, egress bool) (U sendTs := time.Now() t.stats.Sent++ if err := t.conn.WriteTo(pkt, t.nextHop); err != nil { - return u, serrors.WrapStr("writing", err) + return u, serrors.Wrap("writing", err) } select { case <-time.After(t.timeout): @@ -293,7 +293,7 @@ func (t tracerouter) drain(ctx context.Context) { if err := t.conn.ReadFrom(&pkt, &ov); err != nil && t.errHandler != nil { // Rate limit the error reports. if now := time.Now(); now.Sub(last) > 500*time.Millisecond { - t.errHandler(serrors.WrapStr("reading packet", err)) + t.errHandler(serrors.Wrap("reading packet", err)) last = now } } diff --git a/tools/braccept/runner/compare.go b/tools/braccept/runner/compare.go index cd1c528d26..77971bc24a 100644 --- a/tools/braccept/runner/compare.go +++ b/tools/braccept/runner/compare.go @@ -93,7 +93,7 @@ func comparePkts(got, want gopacket.Packet, normalizeFn NormalizePacketFn) error for _, l := range got.Layers() { err = compareLayers(l, want.Layer(l.LayerType())) if err != nil { - errors = append(errors, serrors.WrapStr("layer mismatch", err)) + errors = append(errors, serrors.Wrap("layer mismatch", err)) } } return errors.ToError() diff --git a/tools/braccept/runner/run.go b/tools/braccept/runner/run.go index 4e775e58dc..03e3993e19 100644 --- a/tools/braccept/runner/run.go +++ b/tools/braccept/runner/run.go @@ -49,7 +49,7 @@ type RunConfig struct { func NewRunConfig() (*RunConfig, error) { devs, err := net.Interfaces() if err != nil { - return nil, serrors.WrapStr("listing network interfaces", err) + return nil, serrors.Wrap("listing network interfaces", err) } var packetChans []reflect.SelectCase handles := make(map[string]*afpacket.TPacket) @@ -61,7 +61,7 @@ func NewRunConfig() (*RunConfig, error) { } handle, err := afpacket.NewTPacket(afpacket.OptInterface(dev.Name)) if err != nil { - return nil, serrors.WrapStr("creating TPacket", err) + return nil, serrors.Wrap("creating TPacket", err) } handles[dev.Name] = handle deviceNames = append(deviceNames, dev.Name) @@ -124,7 +124,7 @@ func (c *RunConfig) ExpectPacket(pkt ExpectedPacket, normalizeFn NormalizePacket return errors.ToError() } // Timeout receiving packets - return serrors.WithCtx(errTimeout, "other err", errors.ToError()) + return serrors.Join(errTimeout, nil, "other err", errors.ToError()) } got, ok := pktV.Interface().(gopacket.Packet) if !ok { @@ -140,12 +140,12 @@ func (c *RunConfig) ExpectPacket(pkt ExpectedPacket, normalizeFn NormalizePacket continue } if err := got.ErrorLayer(); err != nil { - errors = append(errors, serrors.WrapStr("error decoding packet", err.Error(), + errors = append(errors, serrors.Wrap("error decoding packet", err.Error(), "pkt", i)) continue } if err := comparePkts(got, pkt.Pkt, normalizeFn); err != nil { - errors = append(errors, serrors.WrapStr("received mismatching packet", err, + errors = append(errors, serrors.Wrap("received mismatching packet", err, "pkt", i)) continue } @@ -202,7 +202,7 @@ func (t *Case) Run(cfg *RunConfig) error { } if err := cfg.WritePacket(t.WriteTo, t.Input); err != nil { - return serrors.WrapStr("writing input packet", err) + return serrors.Wrap("writing input packet", err) } ePkt := ExpectedPacket{ Storer: storer, @@ -222,8 +222,9 @@ func (t *Case) Run(cfg *RunConfig) error { if errors.Is(err, errTimeout) { log.Debug(t.Name, "msg", "timeout occurred") } - return serrors.WrapStr("Errors were found", err, + return serrors.Wrap("Errors were found", err, "Packets are stored in", t.StoreDir) + } type packetStorer struct { diff --git a/tools/buildkite/buildkite.go b/tools/buildkite/buildkite.go index 55fcb2b22b..ac85517c07 100644 --- a/tools/buildkite/buildkite.go +++ b/tools/buildkite/buildkite.go @@ -85,7 +85,7 @@ func (d *Downloader) ArtifactsFromBuild(build *buildkite.Build) error { jobGroup.Go(func() error { artifacts, err := d.artifactsByURL(*job.ArtifactsURL) if err != nil { - return serrors.WrapStr("fetching artifacts", err, "job", job.Name) + return serrors.Wrap("fetching artifacts", err, "job", job.Name) } artifactsGroup, _ := errgroup.WithContext(ctx) @@ -109,7 +109,7 @@ func (d *Downloader) ArtifactsFromBuild(build *buildkite.Build) error { file := filepath.Join(d.Dir, base+".tar.gz") d.info("Start downloading: %s\n", file) if err := d.downloadArtifact(a, file); err != nil { - return serrors.WrapStr("downloading artifact", err, "job", job.Name) + return serrors.Wrap("downloading artifact", err, "job", job.Name) } d.info("Done downloading: %s (%s)\n", file, time.Since(start)) diff --git a/tools/buildkite/cmd/buildkite_artifacts/main.go b/tools/buildkite/cmd/buildkite_artifacts/main.go index fb40c6f229..9fd7e5e3b2 100644 --- a/tools/buildkite/cmd/buildkite_artifacts/main.go +++ b/tools/buildkite/cmd/buildkite_artifacts/main.go @@ -63,7 +63,7 @@ set. The token must have the following permissions: IncludeRetriedJobs: true, }) if err != nil { - return serrors.WrapStr("fetching build", err) + return serrors.Wrap("fetching build", err) } d := buildkite.Downloader{ Client: client, diff --git a/tools/end2end/main.go b/tools/end2end/main.go index d16578140d..55b5a6ac24 100644 --- a/tools/end2end/main.go +++ b/tools/end2end/main.go @@ -166,7 +166,7 @@ func (s server) handlePing(conn *snet.Conn) error { rawPld := make([]byte, common.MaxMTU) n, clientAddr, err := readFrom(conn, rawPld) if err != nil { - return serrors.WrapStr("reading packet", err) + return serrors.Wrap("reading packet", err) } var pld Ping @@ -181,7 +181,7 @@ func (s server) handlePing(conn *snet.Conn) error { bytes.NewReader(pld.Trace), ) if err != nil { - return serrors.WrapStr("extracting trace information", err) + return serrors.Wrap("extracting trace information", err) } span, _ := opentracing.StartSpanFromContext( context.Background(), @@ -208,11 +208,11 @@ func (s server) handlePing(conn *snet.Conn) error { Trace: pld.Trace, }) if err != nil { - return withTag(serrors.WrapStr("packing pong", err)) + return withTag(serrors.Wrap("packing pong", err)) } // Send pong if _, err := conn.WriteTo(raw, clientUDPAddr); err != nil { - return withTag(serrors.WrapStr("sending reply", err)) + return withTag(serrors.Wrap("sending reply", err)) } log.Info("Sent pong to", "client", clientUDPAddr) return nil @@ -298,15 +298,15 @@ func (c *client) ping(ctx context.Context, n int, path snet.Path) (func(), error Trace: tracing.IDFromCtx(ctx), }) if err != nil { - return nil, serrors.WrapStr("packing ping", err) + return nil, serrors.Wrap("packing ping", err) } log.FromCtx(ctx).Info("Dialing", "remote", remote) c.conn, err = c.network.Dial(ctx, "udp", integration.Local.Host, &remote) if err != nil { - return nil, serrors.WrapStr("dialing conn", err) + return nil, serrors.Wrap("dialing conn", err) } if err := c.conn.SetWriteDeadline(getDeadline(ctx)); err != nil { - return nil, serrors.WrapStr("setting write deadline", err) + return nil, serrors.Wrap("setting write deadline", err) } log.Info("sending ping", "attempt", n, "remote", c.conn.RemoteAddr()) if _, err := c.conn.Write(rawPing); err != nil { @@ -335,7 +335,7 @@ func (c *client) getRemote(ctx context.Context, n int) (snet.Path, error) { paths, err := c.sdConn.Paths(ctx, remote.IA, integration.Local.IA, daemon.PathReqFlags{Refresh: n != 0}) if err != nil { - return nil, withTag(serrors.WrapStr("requesting paths", err)) + return nil, withTag(serrors.Wrap("requesting paths", err)) } // If all paths had an error, let's try them again. if len(paths) <= len(c.errorPaths) { @@ -377,17 +377,17 @@ func (c *client) getRemote(ctx context.Context, n int) (snet.Path, error) { func (c *client) pong(ctx context.Context) error { if err := c.conn.SetReadDeadline(getDeadline(ctx)); err != nil { - return serrors.WrapStr("setting read deadline", err) + return serrors.Wrap("setting read deadline", err) } rawPld := make([]byte, common.MaxMTU) n, serverAddr, err := readFrom(c.conn, rawPld) if err != nil { - return serrors.WrapStr("reading packet", err) + return serrors.Wrap("reading packet", err) } var pld Pong if err := json.Unmarshal(rawPld[:n], &pld); err != nil { - return serrors.WrapStr("unpacking pong", err, "data", string(rawPld)) + return serrors.Wrap("unpacking pong", err, "data", string(rawPld)) } expected := Pong{ @@ -417,8 +417,8 @@ func readFrom(conn *snet.Conn, pld []byte) (int, net.Addr, error) { if !(errors.As(err, &opErr) && opErr.RevInfo() != nil) { return n, remoteAddr, err } - return n, remoteAddr, serrors.WithCtx(err, + return n, remoteAddr, serrors.WrapNoStack("error", err, "isd_as", opErr.RevInfo().IA(), - "interface", opErr.RevInfo().IfID, - ) + "interface", opErr.RevInfo().IfID) + } diff --git a/tools/end2end_integration/main.go b/tools/end2end_integration/main.go index 477d666fc6..1b5d47ba9f 100644 --- a/tools/end2end_integration/main.go +++ b/tools/end2end_integration/main.go @@ -181,10 +181,10 @@ func runTests(in integration.Integration, pairs []integration.IAPair) error { var ctr int doneDir, err := filepath.Abs(filepath.Join(integration.LogDir(), "socks")) if err != nil { - return serrors.WrapStr("determining abs path", err) + return serrors.Wrap("determining abs path", err) } if err := os.MkdirAll(doneDir, os.ModePerm); err != nil { - return serrors.WrapStr("creating socks directory", err) + return serrors.Wrap("creating socks directory", err) } // this is a bit of a hack, socket file names have a max length of 108 // and inside bazel tests we easily have longer paths, therefore we @@ -192,13 +192,13 @@ func runTests(in integration.Integration, pairs []integration.IAPair) error { // file. tmpDir, err := os.MkdirTemp("", "e2e_integration") if err != nil { - return serrors.WrapStr("creating temp dir", err) + return serrors.Wrap("creating temp dir", err) } if err := os.Remove(tmpDir); err != nil { - return serrors.WrapStr("deleting temp dir", err) + return serrors.Wrap("deleting temp dir", err) } if err := os.Symlink(doneDir, tmpDir); err != nil { - return serrors.WrapStr("symlinking socks dir", err) + return serrors.Wrap("symlinking socks dir", err) } doneDir = tmpDir defer os.Remove(doneDir) @@ -210,7 +210,7 @@ func runTests(in integration.Integration, pairs []integration.IAPair) error { log.Info(fmt.Sprintf("Test %v: %s", in.Name(), testInfo)) }) if err != nil { - return serrors.WrapStr("creating done listener", err) + return serrors.Wrap("creating done listener", err) } defer clean() @@ -256,7 +256,7 @@ func runTests(in integration.Integration, pairs []integration.IAPair) error { Tester: tester, }) if err != nil { - err = serrors.WithCtx(err, "file", relFile(logFile)) + err = serrors.Wrap("running integration", err, "file", relFile(logFile)) } clientResults <- err }(src, dsts) diff --git a/tools/integration/aslist.go b/tools/integration/aslist.go index dbf43d1285..dcfc880adf 100644 --- a/tools/integration/aslist.go +++ b/tools/integration/aslist.go @@ -35,12 +35,12 @@ type ASList struct { func LoadASList(fileName string) (*ASList, error) { buffer, err := os.ReadFile(fileName) if err != nil { - return nil, serrors.WrapStr("Unable to read from file", err, "name", fileName) + return nil, serrors.Wrap("Unable to read from file", err, "name", fileName) } var asList ASList err = yaml.Unmarshal(buffer, &asList) if err != nil { - return nil, serrors.WrapStr("Unable to parse YAML data", err) + return nil, serrors.Wrap("Unable to parse YAML data", err) } return &asList, nil } diff --git a/tools/integration/binary.go b/tools/integration/binary.go index 86104f59cb..21341d53ae 100644 --- a/tools/integration/binary.go +++ b/tools/integration/binary.go @@ -115,7 +115,7 @@ func (bi *binaryIntegration) StartServer(ctx context.Context, dst *snet.UDPAddr) if needSCIOND(args) { daemonAddr, err := GetSCIONDAddress(GenFile(DaemonAddressesFile), dst.IA) if err != nil { - return nil, serrors.WrapStr("unable to determine SCION Daemon address", err) + return nil, serrors.Wrap("unable to determine SCION Daemon address", err) } args = replacePattern(Daemon, daemonAddr, args) } @@ -164,7 +164,7 @@ func (bi *binaryIntegration) StartServer(ctx context.Context, dst *snet.UDPAddr) }() if err = r.Start(); err != nil { - return nil, serrors.WrapStr("Failed to start server", err, "dst", dst.IA) + return nil, serrors.Wrap("Failed to start server", err, "dst", dst.IA) } select { case <-ready: @@ -185,7 +185,7 @@ func (bi *binaryIntegration) StartClient(ctx context.Context, if needSCIOND(args) { daemonAddr, err := GetSCIONDAddress(GenFile(DaemonAddressesFile), src.IA) if err != nil { - return nil, serrors.WrapStr("unable to determine SCION Daemon address", err) + return nil, serrors.Wrap("unable to determine SCION Daemon address", err) } args = replacePattern(Daemon, daemonAddr, args) } @@ -198,7 +198,7 @@ func (bi *binaryIntegration) StartClient(ctx context.Context, r.cmd.Env = append(r.cmd.Env, fmt.Sprintf("%s=1", GoIntegrationEnv)) pr, pw, err := os.Pipe() if err != nil { - return nil, serrors.WrapStr("creating pipe", err) + return nil, serrors.Wrap("creating pipe", err) } r.cmd.Stderr = pw r.cmd.Stdout = pw diff --git a/tools/integration/cmd.go b/tools/integration/cmd.go index e93b920991..795a18a0f8 100644 --- a/tools/integration/cmd.go +++ b/tools/integration/cmd.go @@ -43,7 +43,7 @@ func (c Cmd) Template(src, dst *snet.UDPAddr) (Cmd, error) { if needSCIOND(args) { daemonAddr, err := GetSCIONDAddress(GenFile(DaemonAddressesFile), src.IA) if err != nil { - return Cmd{}, serrors.WrapStr("unable to determine SCION Daemon address", err) + return Cmd{}, serrors.Wrap("unable to determine SCION Daemon address", err) } args = replacePattern(Daemon, daemonAddr, args) } diff --git a/tools/integration/done.go b/tools/integration/done.go index 33263377f4..d69e62f524 100644 --- a/tools/integration/done.go +++ b/tools/integration/done.go @@ -27,7 +27,7 @@ import ( // ListenDone opens a RPC server to listen for done signals. func ListenDone(dir string, onDone func(src, dst addr.IA)) (string, func(), error) { if err := os.MkdirAll(dir, os.ModePerm); err != nil { - return "", nil, serrors.WrapStr("creating socket directory", err) + return "", nil, serrors.Wrap("creating socket directory", err) } file, err := os.CreateTemp(dir, "integration-*.sock") if err != nil { diff --git a/tools/integration/integration.go b/tools/integration/integration.go index 518bef3de7..09c455b9a5 100644 --- a/tools/integration/integration.go +++ b/tools/integration/integration.go @@ -308,16 +308,16 @@ func RunClient(in Integration, pair IAPair, timeout time.Duration, defer cancel() c, err := in.StartClient(ctx, pair.Src, pair.Dst) if err != nil { - return serrors.WrapStr("starting client", err) + return serrors.Wrap("starting client", err) } if err = c.Wait(); err != nil { - return serrors.WrapStr("waiting for completion", err) + return serrors.Wrap("waiting for completion", err) } if checkOutput == nil { return nil } if err := checkOutput(c.Output()); err != nil { - return serrors.WrapStr("checking output", err) + return serrors.Wrap("checking output", err) } return nil } diff --git a/tools/integration/integrationlib/common.go b/tools/integration/integrationlib/common.go index f9b2388a3b..15bb087f4f 100644 --- a/tools/integration/integrationlib/common.go +++ b/tools/integration/integrationlib/common.go @@ -59,7 +59,7 @@ var ( func Setup() error { err := addFlags() if err != nil { - return serrors.WrapStr("adding flags", err) + return serrors.Wrap("adding flags", err) } validateFlags() return nil @@ -68,7 +68,7 @@ func Setup() error { func addFlags() error { err := envFlags.LoadExternalVars() if err != nil { - return serrors.WrapStr("reading scion environment", err) + return serrors.Wrap("reading scion environment", err) } // TODO(JordiSubira): Make this flag optional and consider the same case as Unspecified // if it isn't explicitly set. diff --git a/tools/pktgen/cmd/pktgen/config.go b/tools/pktgen/cmd/pktgen/config.go index 1f6f487013..0f497bb5a9 100644 --- a/tools/pktgen/cmd/pktgen/config.go +++ b/tools/pktgen/cmd/pktgen/config.go @@ -45,11 +45,11 @@ type jsonConfig struct { func parseEthernet(cfg *jsonConfig) (*layers.Ethernet, error) { src, err := net.ParseMAC(cfg.Ethernet.SrcMAC) if err != nil { - return nil, serrors.WrapStr("parsing SrcMAC", err) + return nil, serrors.Wrap("parsing SrcMAC", err) } dst, err := net.ParseMAC(cfg.Ethernet.DstMAC) if err != nil { - return nil, serrors.WrapStr("parsing DstMAC", err) + return nil, serrors.Wrap("parsing DstMAC", err) } return &layers.Ethernet{ SrcMAC: src, diff --git a/tools/pktgen/cmd/pktgen/main.go b/tools/pktgen/cmd/pktgen/main.go index d56d951ace..c92f5c233b 100644 --- a/tools/pktgen/cmd/pktgen/main.go +++ b/tools/pktgen/cmd/pktgen/main.go @@ -67,7 +67,7 @@ func main() { RunE: func(cmd *cobra.Command, args []string) error { dst, err := snet.ParseUDPAddr(args[0]) if err != nil { - return serrors.WrapStr("parsing destination addr", err) + return serrors.Wrap("parsing destination addr", err) } return run(cfg, dst) }, @@ -98,20 +98,20 @@ func main() { func run(cfg flags, dst *snet.UDPAddr) error { defer log.Flush() if err := log.Setup(log.Config{Console: log.ConsoleConfig{Level: cfg.logLevel}}); err != nil { - return serrors.WrapStr("setting up log", err) + return serrors.Wrap("setting up log", err) } raw, err := os.ReadFile(cfg.config) if err != nil { - return serrors.WrapStr("reading config file", err) + return serrors.Wrap("reading config file", err) } var layersCfg jsonConfig if err := json.Unmarshal(raw, &layersCfg); err != nil { - return serrors.WrapStr("parsing layers config", err, "file", cfg.config) + return serrors.Wrap("parsing layers config", err, "file", cfg.config) } ethernetLayer, err := parseEthernet(&layersCfg) if err != nil { - return serrors.WrapStr("parsing ethernet config", err, "file", cfg.config) + return serrors.Wrap("parsing ethernet config", err, "file", cfg.config) } ipv4Layer := parseIPv4(&layersCfg) udpLayer := parseUDP(&layersCfg) @@ -121,12 +121,12 @@ func run(cfg flags, dst *snet.UDPAddr) error { ctx := app.WithSignal(context.Background(), os.Kill) sdConn, err := daemon.NewService(cfg.daemon).Connect(ctx) if err != nil { - return serrors.WrapStr("connecting to SCION daemon", err) + return serrors.Wrap("connecting to SCION daemon", err) } defer sdConn.Close() localIA, err := sdConn.LocalIA(ctx) if err != nil { - return serrors.WrapStr("determining local ISD-AS", err) + return serrors.Wrap("determining local ISD-AS", err) } path, err := path.Choose(ctx, sdConn, dst.IA, path.WithInteractive(cfg.interactive), @@ -135,13 +135,13 @@ func run(cfg flags, dst *snet.UDPAddr) error { path.WithColorScheme(path.DefaultColorScheme(cfg.noColor)), ) if err != nil { - return serrors.WrapStr("fetching paths", err) + return serrors.Wrap("fetching paths", err) } dst.NextHop = path.UnderlayNextHop() dst.Path = path.Dataplane() localIP, err := resolveLocal(dst) if err != nil { - return serrors.WrapStr("resolving local IP", err) + return serrors.Wrap("resolving local IP", err) } scionPath, ok := path.Dataplane().(snetpath.SCION) if !ok { @@ -149,7 +149,7 @@ func run(cfg flags, dst *snet.UDPAddr) error { } decPath := &scion.Decoded{} if err := decPath.DecodeFromBytes(scionPath.Raw); err != nil { - return serrors.WrapStr("decoding path", err) + return serrors.Wrap("decoding path", err) } scionLayer.PathType = scion.PathType @@ -161,10 +161,10 @@ func run(cfg flags, dst *snet.UDPAddr) error { 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) + return serrors.Wrap("setting SCION dest address", err) } if err := scionLayer.SetSrcAddr(addr.HostIP(localIP)); err != nil { - return serrors.WrapStr("setting SCION source address", err) + return serrors.Wrap("setting SCION source address", err) } scionudpLayer := &slayers.UDP{} scionudpLayer.SrcPort = 40111 @@ -179,7 +179,7 @@ func run(cfg flags, dst *snet.UDPAddr) error { } if err := gopacket.SerializeLayers(input, options, ethernetLayer, ipv4Layer, udpLayer, scionLayer, scionudpLayer, gopacket.Payload(payload)); err != nil { - return serrors.WrapStr("serializing go packet", err) + return serrors.Wrap("serializing go packet", err) } if err := pktgen.StorePcap(cfg.out, input.Bytes()); err != nil { return err @@ -196,7 +196,7 @@ func resolveLocal(dst *snet.UDPAddr) (netip.Addr, error) { } resolvedIP, err := addrutil.ResolveLocal(target) if err != nil { - return netip.Addr{}, serrors.WrapStr("resolving local address", err) + return netip.Addr{}, serrors.Wrap("resolving local address", err) } localIP, ok := netip.AddrFromSlice(resolvedIP) if !ok { diff --git a/tools/pktgen/pcap.go b/tools/pktgen/pcap.go index 1827230bc5..1666de6318 100644 --- a/tools/pktgen/pcap.go +++ b/tools/pktgen/pcap.go @@ -28,20 +28,20 @@ import ( func StorePcap(file string, pkt []byte) error { f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644) if err != nil { - return serrors.WrapStr("creating file", err, "file", file) + return serrors.Wrap("creating file", err, "file", file) } defer f.Close() w := pcapgo.NewWriter(f) if err := w.WriteFileHeader(65535, layers.LinkTypeEthernet); err != nil { - return serrors.WrapStr("writing header", err, "file", file) + return serrors.Wrap("writing header", err, "file", file) } c := gopacket.CaptureInfo{ Length: len(pkt), CaptureLength: len(pkt), } if err := w.WritePacket(c, pkt); err != nil { - return serrors.WrapStr("writing packet", err, "file", file) + return serrors.Wrap("writing packet", err, "file", file) } return nil } From 08852b413736d41109034a7af74c36c3397095b4 Mon Sep 17 00:00:00 2001 From: Lukas Vogel Date: Wed, 28 Aug 2024 10:16:27 +0200 Subject: [PATCH 10/29] control: allow to query for latest TRC (#4601) Currently querying for the latest TRC was not allowed, because TRC ID validation would fail. However it should be completely fine to query for the latest TRC. This commit fixes it. --- control/trust/grpc/proto.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/control/trust/grpc/proto.go b/control/trust/grpc/proto.go index 2eee5c53b1..9e1c9198a6 100644 --- a/control/trust/grpc/proto.go +++ b/control/trust/grpc/proto.go @@ -65,6 +65,14 @@ func requestToTRCQuery(req *cppb.TRCRequest) (cppki.TRCID, error) { Base: scrypto.Version(req.Base), Serial: scrypto.Version(req.Serial), } + // If the query is for the latest version don't validate the ID fully, only + // the ISD ID. + if id.Base.IsLatest() && id.Serial.IsLatest() { + if id.ISD == 0 { + return cppki.TRCID{}, cppki.ErrWildcardISD + } + return id, nil + } if err := id.Validate(); err != nil { return cppki.TRCID{}, err } From fbd9eb0d92615dec753cf878058f506d29fd795c Mon Sep 17 00:00:00 2001 From: Lukas Vogel Date: Wed, 28 Aug 2024 13:19:48 +0200 Subject: [PATCH 11/29] crypto: do not load already loaded TRC files (#4588) This commit introduces a TRC loader that keeps track of what TRC files have already been read. By doing so we can omit duplicate work of parsing TRC files and storing them in the DB. This applies to the control service and the daemon. --- control/trust.go | 2 +- control/trust/crypto_loader.go | 32 ++++++++++++++++---- daemon/cmd/daemon/main.go | 11 ++++--- private/trust/store.go | 55 ++++++++++++++++++++++++++++++++-- private/trust/store_test.go | 42 ++++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 13 deletions(-) diff --git a/control/trust.go b/control/trust.go index b16e49c05f..cff947de3d 100644 --- a/control/trust.go +++ b/control/trust.go @@ -103,7 +103,7 @@ func newCachingSignerGen( gen := trust.SignerGen{ IA: ia, - DB: cstrust.CryptoLoader{ + DB: &cstrust.CryptoLoader{ Dir: filepath.Join(cfgDir, "crypto/as"), TRCDirs: []string{filepath.Join(cfgDir, "certs")}, DB: db, diff --git a/control/trust/crypto_loader.go b/control/trust/crypto_loader.go index 238e69b30e..1081499468 100644 --- a/control/trust/crypto_loader.go +++ b/control/trust/crypto_loader.go @@ -18,6 +18,7 @@ import ( "context" "crypto/x509" "errors" + "sync" "github.com/scionproto/scion/pkg/log" "github.com/scionproto/scion/pkg/private/serrors" @@ -33,9 +34,13 @@ type CryptoLoader struct { Dir string // TRCDirs are optional directories from which TRCs are loaded. TRCDirs []string + + trcLoaders map[string]*trust.TRCLoader + trcLoadersInitMtx sync.Mutex } -func (l CryptoLoader) SignedTRC(ctx context.Context, id cppki.TRCID) (cppki.SignedTRC, error) { +func (l *CryptoLoader) SignedTRC(ctx context.Context, id cppki.TRCID) (cppki.SignedTRC, error) { + l.initTRCLoaders() if err := l.loadTRCs(ctx); err != nil { log.FromCtx(ctx).Info("Failed to load TRCs from disk, continuing", "err", err) } @@ -44,7 +49,7 @@ func (l CryptoLoader) SignedTRC(ctx context.Context, id cppki.TRCID) (cppki.Sign // Chains loads chains from disk, stores them to DB, and returns the result from // DB. The fallback mode is always the result of the DB. -func (l CryptoLoader) Chains(ctx context.Context, +func (l *CryptoLoader) Chains(ctx context.Context, query trust.ChainQuery) ([][]*x509.Certificate, error) { r, err := trust.LoadChains(ctx, l.Dir, l.DB) @@ -70,7 +75,24 @@ func (l CryptoLoader) Chains(ctx context.Context, return l.DB.Chains(ctx, query) } -func (l CryptoLoader) loadTRCs(ctx context.Context) error { +func (l *CryptoLoader) initTRCLoaders() { + l.trcLoadersInitMtx.Lock() + defer l.trcLoadersInitMtx.Unlock() + if l.trcLoaders != nil { + return + } + l.trcLoaders = make(map[string]*trust.TRCLoader, len(l.TRCDirs)+1) + for _, dir := range append([]string{l.Dir}, l.TRCDirs...) { + if _, ok := l.trcLoaders[dir]; !ok { + l.trcLoaders[dir] = &trust.TRCLoader{ + DB: l.DB, + Dir: dir, + } + } + } +} + +func (l *CryptoLoader) loadTRCs(ctx context.Context) error { var errs serrors.List for _, dir := range append([]string{l.Dir}, l.TRCDirs...) { if err := l.loadTRCsFromDir(ctx, dir); err != nil { @@ -80,8 +102,8 @@ func (l CryptoLoader) loadTRCs(ctx context.Context) error { return errs.ToError() } -func (l CryptoLoader) loadTRCsFromDir(ctx context.Context, dir string) error { - r, err := trust.LoadTRCs(ctx, dir, l.DB) +func (l *CryptoLoader) loadTRCsFromDir(ctx context.Context, dir string) error { + r, err := l.trcLoaders[dir].Load(ctx) if err != nil { return err } diff --git a/daemon/cmd/daemon/main.go b/daemon/cmd/daemon/main.go index 5faf0c9bc2..32fd124427 100644 --- a/daemon/cmd/daemon/main.go +++ b/daemon/cmd/daemon/main.go @@ -159,10 +159,13 @@ func realMain(ctx context.Context) error { CacheHits: metrics.NewPromCounter(trustmetrics.CacheHitsTotal), MaxCacheExpiration: globalCfg.TrustEngine.Cache.Expiration.Duration, } - trcLoader := periodic.Start(periodic.Func{ + trcLoader := trust.TRCLoader{ + Dir: filepath.Join(globalCfg.General.ConfigDir, "certs"), + DB: trustDB, + } + trcLoaderTask := periodic.Start(periodic.Func{ Task: func(ctx context.Context) { - trcDirs := filepath.Join(globalCfg.General.ConfigDir, "certs") - res, err := trust.LoadTRCs(ctx, trcDirs, trustDB) + res, err := trcLoader.Load(ctx) if err != nil { log.SafeInfo(log.FromCtx(ctx), "TRC loading failed", "err", err) } @@ -172,7 +175,7 @@ func realMain(ctx context.Context) error { }, TaskName: "daemon_trc_loader", }, 10*time.Second, 10*time.Second) - defer trcLoader.Stop() + defer trcLoaderTask.Stop() var drkeyClientEngine *sd_drkey.ClientEngine if globalCfg.DRKeyLevel2DB.Connection != "" { diff --git a/private/trust/store.go b/private/trust/store.go index 1eaea6f017..76815cb656 100644 --- a/private/trust/store.go +++ b/private/trust/store.go @@ -21,6 +21,7 @@ import ( "fmt" "os" "path/filepath" + "sync" "time" "github.com/scionproto/scion/pkg/private/serrors" @@ -112,9 +113,22 @@ func LoadChains(ctx context.Context, dir string, db DB) (LoadResult, error) { } // LoadTRCs loads all *.trc located in a directory in the database. This -// function exits on the first encountered error. TRCs with a not before time -// in the future are ignored. +// function exits on the first encountered error. TRCs with a not before time in +// the future are ignored. +// +// This function is not recommended for repeated use as it will read all TRC +// files in a directory on every invocation. Consider using a TRCLoader if you +// want to monitor a directory for new TRCs. func LoadTRCs(ctx context.Context, dir string, db DB) (LoadResult, error) { + return loadTRCs(ctx, dir, db, nil) +} + +func loadTRCs( + ctx context.Context, + dir string, + db DB, + ignoreFiles map[string]struct{}, +) (LoadResult, error) { if _, err := os.Stat(dir); err != nil { return LoadResult{}, serrors.WrapNoStack("stating directory", err, "dir", dir) } @@ -127,6 +141,10 @@ func LoadTRCs(ctx context.Context, dir string, db DB) (LoadResult, error) { res := LoadResult{Ignored: map[string]error{}} // TODO(roosd): should probably be a transaction. for _, f := range files { + // ignore as per request of the caller + if _, ok := ignoreFiles[f]; ok { + continue + } raw, err := os.ReadFile(f) if err != nil { return res, serrors.WrapNoStack("reading TRC", err, "file", f) @@ -148,10 +166,41 @@ func LoadTRCs(ctx context.Context, dir string, db DB) (LoadResult, error) { return res, serrors.WrapNoStack("adding TRC to DB", err, "file", f) } if !inserted { - res.Ignored[f] = serrors.JoinNoStack(ErrAlreadyExists, err) + res.Ignored[f] = ErrAlreadyExists continue } res.Loaded = append(res.Loaded, f) } return res, nil } + +// TRCLoader loads TRCs from a directory and stores them in the database. It +// tracks files that it has already loaded and does not load them again. +type TRCLoader struct { + Dir string + DB DB + + seen map[string]struct{} + mtx sync.Mutex +} + +// Load loads all TRCs from the directory into database. Files that have been +// loaded by a previous Load invocation are silently ignored. +func (l *TRCLoader) Load(ctx context.Context) (LoadResult, error) { + l.mtx.Lock() + defer l.mtx.Unlock() + if l.seen == nil { + l.seen = make(map[string]struct{}) + } + + result, err := loadTRCs(ctx, l.Dir, l.DB, l.seen) + for _, f := range result.Loaded { + l.seen[f] = struct{}{} + } + for f, err := range result.Ignored { + if errors.Is(err, ErrAlreadyExists) { + l.seen[f] = struct{}{} + } + } + return result, err +} diff --git a/private/trust/store_test.go b/private/trust/store_test.go index b5c040342a..642b07bde7 100644 --- a/private/trust/store_test.go +++ b/private/trust/store_test.go @@ -317,3 +317,45 @@ func TestLoadTRCs(t *testing.T) { }) } } + +func TestTRCLoaderLoad(t *testing.T) { + dir := genCrypto(t) + + testCases := map[string]struct { + inputDir string + setupDB func(ctrl *gomock.Controller) trust.DB + test func(t *testing.T, loader *trust.TRCLoader) + }{ + "repeated load": { + inputDir: filepath.Join(dir, "ISD1/trcs"), + setupDB: func(ctrl *gomock.Controller) trust.DB { + db := mock_trust.NewMockDB(ctrl) + db.EXPECT().InsertTRC(gomock.Any(), gomock.Any()).Times(2).Return( + true, nil, + ) + return db + }, + test: func(t *testing.T, loader *trust.TRCLoader) { + res, err := loader.Load(context.Background()) + require.NoError(t, err) + assert.Len(t, res.Loaded, 2) + res, err = loader.Load(context.Background()) + require.NoError(t, err) + assert.Len(t, res.Loaded, 0) + }, + }, + } + for name, tc := range testCases { + name, tc := name, tc + t.Run(name, func(t *testing.T) { + t.Parallel() + ctrl := gomock.NewController(t) + db := tc.setupDB(ctrl) + loader := &trust.TRCLoader{ + DB: db, + Dir: tc.inputDir, + } + tc.test(t, loader) + }) + } +} From 9e58974dd6181f8ae91e7fc15fc2c189b49176c3 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:49:34 +0200 Subject: [PATCH 12/29] build: bump go version to 1.23 (#4603) This required upgrading rules_go to 0.47.0 because of some magic parameter that must now be passed to the go assembler in support of the internal/V0 ABI split in go 1.22. It wasn't possible to upgrade rules_go further without also upgrading bazel and other stuff. So... one problem at a time. As a result of rules_go upgrade, the proto generation has changed, hence the other diffs. Contributes to #4555 --- Makefile | 2 +- WORKSPACE | 13 +- dist/package.bzl | 2 +- go.mod | 2 +- .../d3flamegraph/D3_FLAME_GRAPH_LICENSE | 201 ------------------ .../pprof/third_party/d3flamegraph/D3_LICENSE | 13 -- .../cmd/vendor/golang.org/x/build}/LICENSE | 2 +- .../cmd/vendor/golang.org/x/telemetry/LICENSE | 27 +++ .../src/cmd/vendor/golang.org/x/text/LICENSE | 27 +++ .../src/cmd/vendor/rsc.io/markdown/LICENSE | 27 +++ pkg/proto/control_plane/cppki.pb.go | 2 +- pkg/proto/control_plane/drkey.pb.go | 2 +- .../seg_detached_extensions.pb.go | 2 +- pkg/proto/control_plane/renewal.pb.go | 2 +- pkg/proto/control_plane/seg.pb.go | 2 +- pkg/proto/control_plane/seg_extensions.pb.go | 2 +- pkg/proto/control_plane/svc_resolution.pb.go | 2 +- pkg/proto/crypto/signed.pb.go | 2 +- pkg/proto/daemon/daemon.pb.go | 2 +- pkg/proto/discovery/discovery.pb.go | 2 +- pkg/proto/drkey/drkey.pb.go | 2 +- pkg/proto/gateway/control.pb.go | 2 +- pkg/proto/gateway/prefix.pb.go | 2 +- pkg/proto/hidden_segment/hidden_segment.pb.go | 2 +- private/app/path/path.go | 2 +- tools/buildkite/buildkite.go | 2 +- 26 files changed, 107 insertions(+), 241 deletions(-) delete mode 100644 licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE delete mode 100644 licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE rename licenses/data/{org_golang_x_tools/cmd/getgo => go_sdk/src/cmd/vendor/golang.org/x/build}/LICENSE (96%) mode change 100755 => 100644 create mode 100644 licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE create mode 100644 licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE create mode 100644 licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE diff --git a/Makefile b/Makefile index 1def0cf11f..d82db1af82 100644 --- a/Makefile +++ b/Makefile @@ -120,7 +120,7 @@ GO_BUILD_TAGS_ARG=$(shell bazel info --ui_event_filters=-stdout,-stderr --announ lint-go-golangci: $(info ==> $@) @if [ -t 1 ]; then tty=true; else tty=false; fi; \ - tools/quiet docker run --tty=$$tty --rm -v golangci-lint-modcache:/go -v golangci-lint-buildcache:/root/.cache -v "${PWD}:/src" -w /src golangci/golangci-lint:v1.54.2 golangci-lint run --config=/src/.golangcilint.yml --timeout=3m $(GO_BUILD_TAGS_ARG) --skip-dirs doc ./... + tools/quiet docker run --tty=$$tty --rm -v golangci-lint-modcache:/go -v golangci-lint-buildcache:/root/.cache -v "${PWD}:/src" -w /src golangci/golangci-lint:v1.60.3 golangci-lint run --config=/src/.golangcilint.yml --timeout=3m $(GO_BUILD_TAGS_ARG) --skip-dirs doc ./... lint-go-semgrep: $(info ==> $@) diff --git a/WORKSPACE b/WORKSPACE index 89a24af2c3..d1f70c41ee 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -46,18 +46,20 @@ aspect_bazel_lib_register_toolchains() # Bazel rules for Golang http_archive( name = "io_bazel_rules_go", - sha256 = "91585017debb61982f7054c9688857a2ad1fd823fc3f9cb05048b0025c47d023", + sha256 = "af47f30e9cbd70ae34e49866e201b3f77069abb111183f2c0297e7e74ba6bbc0", urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.42.0/rules_go-v0.42.0.zip", - "https://github.com/bazelbuild/rules_go/releases/download/v0.42.0/rules_go-v0.42.0.zip", + "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.47.0/rules_go-v0.47.0.zip", + "https://github.com/bazelbuild/rules_go/releases/download/v0.47.0/rules_go-v0.47.0.zip", ], ) load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") +go_rules_dependencies() + go_register_toolchains( nogo = "@//:nogo", - version = "1.21.10", + version = "1.23.0", ) # Gazelle @@ -71,9 +73,6 @@ http_archive( ) load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies") - -go_rules_dependencies() - load("//:tool_deps.bzl", "tool_deps") tool_deps() diff --git a/dist/package.bzl b/dist/package.bzl index ab2f7b4b01..88c9e1544e 100644 --- a/dist/package.bzl +++ b/dist/package.bzl @@ -77,7 +77,7 @@ def scion_pkg_deb(name, executables = {}, systemds = [], configs = [], **kwargs) "@platforms//cpu:x86_64": "amd64", "@platforms//cpu:x86_32": "i386", "@platforms//cpu:aarch64": "arm64", - "@platforms//cpu:arm": "armel", + "@platforms//cpu:armv7": "armel", "@platforms//cpu:s390x": "s390x", # Note: some rules_go toolchains don't (currently) seem to map (cleanly) to @platforms//cpu. # "@platforms//cpu:ppc": "ppc64", diff --git a/go.mod b/go.mod index 4bfaae2219..bc273bb421 100644 --- a/go.mod +++ b/go.mod @@ -127,4 +127,4 @@ require ( modernc.org/token v1.1.0 // indirect ) -go 1.21.10 +go 1.23.0 diff --git a/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE b/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE deleted file mode 100644 index 8dada3edaf..0000000000 --- a/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - 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. diff --git a/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE b/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE deleted file mode 100644 index b0145150fd..0000000000 --- a/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2010-2021 Mike Bostock - -Permission to use, copy, modify, and/or distribute this software for any purpose -with or without fee is hereby granted, provided that the above copyright notice -and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS -OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF -THIS SOFTWARE. diff --git a/licenses/data/org_golang_x_tools/cmd/getgo/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/build/LICENSE old mode 100755 new mode 100644 similarity index 96% rename from licenses/data/org_golang_x_tools/cmd/getgo/LICENSE rename to licenses/data/go_sdk/src/cmd/vendor/golang.org/x/build/LICENSE index 32017f8fa1..6a66aea5ea --- a/licenses/data/org_golang_x_tools/cmd/getgo/LICENSE +++ b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/build/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017 The Go Authors. All rights reserved. +Copyright (c) 2009 The Go Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE new file mode 100644 index 0000000000..2a7cf70da6 --- /dev/null +++ b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE @@ -0,0 +1,27 @@ +Copyright 2009 The Go Authors. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google LLC nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE new file mode 100644 index 0000000000..6a66aea5ea --- /dev/null +++ b/licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/pkg/proto/control_plane/cppki.pb.go b/pkg/proto/control_plane/cppki.pb.go index f5da379ed7..1e0e0ebd58 100644 --- a/pkg/proto/control_plane/cppki.pb.go +++ b/pkg/proto/control_plane/cppki.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/control_plane/v1/cppki.proto diff --git a/pkg/proto/control_plane/drkey.pb.go b/pkg/proto/control_plane/drkey.pb.go index fc0516ab55..4c4082d3e5 100644 --- a/pkg/proto/control_plane/drkey.pb.go +++ b/pkg/proto/control_plane/drkey.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/control_plane/v1/drkey.proto diff --git a/pkg/proto/control_plane/experimental/seg_detached_extensions.pb.go b/pkg/proto/control_plane/experimental/seg_detached_extensions.pb.go index da4342be28..1839f2fe17 100755 --- a/pkg/proto/control_plane/experimental/seg_detached_extensions.pb.go +++ b/pkg/proto/control_plane/experimental/seg_detached_extensions.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/control_plane/experimental/v1/seg_detached_extensions.proto diff --git a/pkg/proto/control_plane/renewal.pb.go b/pkg/proto/control_plane/renewal.pb.go index 6ed4230684..75c974e727 100644 --- a/pkg/proto/control_plane/renewal.pb.go +++ b/pkg/proto/control_plane/renewal.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/control_plane/v1/renewal.proto diff --git a/pkg/proto/control_plane/seg.pb.go b/pkg/proto/control_plane/seg.pb.go index 7355fd77d7..6db657273a 100644 --- a/pkg/proto/control_plane/seg.pb.go +++ b/pkg/proto/control_plane/seg.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/control_plane/v1/seg.proto diff --git a/pkg/proto/control_plane/seg_extensions.pb.go b/pkg/proto/control_plane/seg_extensions.pb.go index f072070bfd..8b6dbf54b5 100644 --- a/pkg/proto/control_plane/seg_extensions.pb.go +++ b/pkg/proto/control_plane/seg_extensions.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/control_plane/v1/seg_extensions.proto diff --git a/pkg/proto/control_plane/svc_resolution.pb.go b/pkg/proto/control_plane/svc_resolution.pb.go index 3c83185bdf..5eba401dcc 100644 --- a/pkg/proto/control_plane/svc_resolution.pb.go +++ b/pkg/proto/control_plane/svc_resolution.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/control_plane/v1/svc_resolution.proto diff --git a/pkg/proto/crypto/signed.pb.go b/pkg/proto/crypto/signed.pb.go index f094495b11..6e4d150b16 100644 --- a/pkg/proto/crypto/signed.pb.go +++ b/pkg/proto/crypto/signed.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/crypto/v1/signed.proto diff --git a/pkg/proto/daemon/daemon.pb.go b/pkg/proto/daemon/daemon.pb.go index 75850fa7fe..1d642fac7c 100644 --- a/pkg/proto/daemon/daemon.pb.go +++ b/pkg/proto/daemon/daemon.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/daemon/v1/daemon.proto diff --git a/pkg/proto/discovery/discovery.pb.go b/pkg/proto/discovery/discovery.pb.go index edc503dbf8..b81355ccd0 100644 --- a/pkg/proto/discovery/discovery.pb.go +++ b/pkg/proto/discovery/discovery.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/discovery/v1/discovery.proto diff --git a/pkg/proto/drkey/drkey.pb.go b/pkg/proto/drkey/drkey.pb.go index 3b31cb7307..07bac92423 100644 --- a/pkg/proto/drkey/drkey.pb.go +++ b/pkg/proto/drkey/drkey.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/drkey/v1/drkey.proto diff --git a/pkg/proto/gateway/control.pb.go b/pkg/proto/gateway/control.pb.go index b7178c3d44..3b5cec38de 100644 --- a/pkg/proto/gateway/control.pb.go +++ b/pkg/proto/gateway/control.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/gateway/v1/control.proto diff --git a/pkg/proto/gateway/prefix.pb.go b/pkg/proto/gateway/prefix.pb.go index 2fd1890680..6340e150a2 100644 --- a/pkg/proto/gateway/prefix.pb.go +++ b/pkg/proto/gateway/prefix.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/gateway/v1/prefix.proto diff --git a/pkg/proto/hidden_segment/hidden_segment.pb.go b/pkg/proto/hidden_segment/hidden_segment.pb.go index c778eadbeb..8813feabe2 100644 --- a/pkg/proto/hidden_segment/hidden_segment.pb.go +++ b/pkg/proto/hidden_segment/hidden_segment.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 +// protoc-gen-go v1.33.0 // protoc v3.21.10 // source: proto/hidden_segment/v1/hidden_segment.proto diff --git a/private/app/path/path.go b/private/app/path/path.go index 4edd9276ec..4258aaf1bf 100644 --- a/private/app/path/path.go +++ b/private/app/path/path.go @@ -258,7 +258,7 @@ func DefaultColorScheme(disable bool) ColorScheme { } func (cs ColorScheme) KeyValue(k, v string) string { - return fmt.Sprintf("%s: %s", cs.Keys.Sprintf(k), cs.Values.Sprintf(v)) + return fmt.Sprintf("%s: %s", cs.Keys.Sprint(k), cs.Values.Sprint(v)) } func (cs ColorScheme) KeyValues(kv ...string) []string { diff --git a/tools/buildkite/buildkite.go b/tools/buildkite/buildkite.go index ac85517c07..8a82b86ff5 100644 --- a/tools/buildkite/buildkite.go +++ b/tools/buildkite/buildkite.go @@ -121,7 +121,7 @@ func (d *Downloader) ArtifactsFromBuild(build *buildkite.Build) error { } cmd := exec.Command("tar", "-xf", file, "-C", dir, "--strip-components", "1") if out, err := cmd.CombinedOutput(); err != nil { - d.error(string(out)) + d.error("%s", string(out)) return err } d.info("Done unpacking: %s (%s)\n", dir, time.Since(start)) From f51e6dab7a36efbccbd2a08aea4a2b4ca1cedc68 Mon Sep 17 00:00:00 2001 From: Lukas Vogel Date: Mon, 2 Sep 2024 14:38:18 +0200 Subject: [PATCH 13/29] daemon: improve revcache performance (#4607) When dealing with a lot of paths the current implementation is not optimal. Specifically filterRevoked showed up quite prominently in a pprof. See image below: ![image](https://github.com/user-attachments/assets/23b337e7-dece-4191-bcf5-75761de93a83) - Use a typed cache, to prevent string key conversion. - Only support single key lookups to prevent map allocation on lookup. Overall this even simplifies the code. --- go.mod | 1 + go.sum | 2 + go_deps.bzl | 6 +++ licenses/data/at_zgo_zcache_v2/LICENSE | 19 +++++++ private/revcache/memrevcache/BUILD.bazel | 2 +- private/revcache/memrevcache/memrevcache.go | 40 +++++--------- .../revcache/memrevcache/memrevcache_test.go | 5 +- private/revcache/mock_revcache/mock.go | 4 +- private/revcache/revcache.go | 13 +---- private/revcache/revcachetest/revcachetest.go | 53 ++++++++----------- private/revcache/util.go | 38 +++++-------- private/revcache/util_test.go | 21 ++++---- private/segment/segfetcher/pather.go | 7 +-- private/segment/segfetcher/resolver_test.go | 32 ++--------- 14 files changed, 99 insertions(+), 144 deletions(-) create mode 100644 licenses/data/at_zgo_zcache_v2/LICENSE diff --git a/go.mod b/go.mod index bc273bb421..90fd42899a 100644 --- a/go.mod +++ b/go.mod @@ -54,6 +54,7 @@ require ( google.golang.org/protobuf v1.34.1 gopkg.in/yaml.v2 v2.4.0 modernc.org/sqlite v1.29.9 + zgo.at/zcache/v2 v2.1.0 ) require ( diff --git a/go.sum b/go.sum index 90e7b0c623..e1191c31f9 100644 --- a/go.sum +++ b/go.sum @@ -497,3 +497,5 @@ modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0 modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +zgo.at/zcache/v2 v2.1.0 h1:USo+ubK+R4vtjw4viGzTe/zjXyPw6R7SK/RL3epBBxs= +zgo.at/zcache/v2 v2.1.0/go.mod h1:gyCeoLVo01QjDZynjime8xUGHHMbsLiPyUTBpDGd4Gk= diff --git a/go_deps.bzl b/go_deps.bzl index b775a95c55..0baba4fc0b 100644 --- a/go_deps.bzl +++ b/go_deps.bzl @@ -7,6 +7,12 @@ load("@bazel_gazelle//:deps.bzl", "go_repository") def go_deps(): + go_repository( + name = "at_zgo_zcache_v2", + importpath = "zgo.at/zcache/v2", + sum = "h1:USo+ubK+R4vtjw4viGzTe/zjXyPw6R7SK/RL3epBBxs=", + version = "v2.1.0", + ) go_repository( name = "co_honnef_go_tools", importpath = "honnef.co/go/tools", diff --git a/licenses/data/at_zgo_zcache_v2/LICENSE b/licenses/data/at_zgo_zcache_v2/LICENSE new file mode 100644 index 0000000000..f49969d7fa --- /dev/null +++ b/licenses/data/at_zgo_zcache_v2/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012-2019 Patrick Mylund Nielsen and the go-cache contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/private/revcache/memrevcache/BUILD.bazel b/private/revcache/memrevcache/BUILD.bazel index b6b7e5a6b7..fc90048c2d 100644 --- a/private/revcache/memrevcache/BUILD.bazel +++ b/private/revcache/memrevcache/BUILD.bazel @@ -8,7 +8,7 @@ go_library( deps = [ "//pkg/private/ctrl/path_mgmt:go_default_library", "//private/revcache:go_default_library", - "@com_github_patrickmn_go_cache//:go_default_library", + "@at_zgo_zcache_v2//:go_default_library", ], ) diff --git a/private/revcache/memrevcache/memrevcache.go b/private/revcache/memrevcache/memrevcache.go index 5f64a0520c..6d72ec7428 100644 --- a/private/revcache/memrevcache/memrevcache.go +++ b/private/revcache/memrevcache/memrevcache.go @@ -19,7 +19,7 @@ import ( "sync" "time" - cache "github.com/patrickmn/go-cache" + cache "zgo.at/zcache/v2" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/private/revcache" @@ -29,7 +29,7 @@ var _ revcache.RevCache = (*memRevCache)(nil) type memRevCache struct { // Do not embed or use type directly to reduce the cache's API surface - c *cache.Cache + c *cache.Cache[revcache.Key, *path_mgmt.RevInfo] lock sync.RWMutex } @@ -38,20 +38,17 @@ func New() *memRevCache { return &memRevCache{ // We insert all the items with expiration so no need to have a default expiration. // The cleaning should happen manually using the DeleteExpired method. - c: cache.New(cache.NoExpiration, 0), + c: cache.New[revcache.Key, *path_mgmt.RevInfo](cache.NoExpiration, 0), } } -func (c *memRevCache) Get(_ context.Context, keys revcache.KeySet) (revcache.Revocations, error) { +func (c *memRevCache) Get(_ context.Context, key revcache.Key) (*path_mgmt.RevInfo, error) { c.lock.RLock() defer c.lock.RUnlock() - revs := make(revcache.Revocations, len(keys)) - for k := range keys { - if revInfo, ok := c.get(k.String()); ok { - revs[k] = revInfo - } + if revInfo, ok := c.c.Get(key); ok { + return revInfo, nil } - return revs, nil + return nil, nil } func (c *memRevCache) GetAll(_ context.Context) (revcache.ResultChan, error) { @@ -61,22 +58,12 @@ func (c *memRevCache) GetAll(_ context.Context) (revcache.ResultChan, error) { items := c.c.Items() resCh := make(chan revcache.RevOrErr, len(items)) for _, item := range items { - if rev, ok := item.Object.(*path_mgmt.RevInfo); ok { - resCh <- revcache.RevOrErr{Rev: rev} - } + resCh <- revcache.RevOrErr{Rev: item.Object} } close(resCh) return resCh, nil } -func (c *memRevCache) get(key string) (*path_mgmt.RevInfo, bool) { - obj, ok := c.c.Get(key) - if !ok { - return nil, false - } - return obj.(*path_mgmt.RevInfo), true -} - func (c *memRevCache) Insert(_ context.Context, rev *path_mgmt.RevInfo) (bool, error) { c.lock.Lock() defer c.lock.Unlock() @@ -84,15 +71,14 @@ func (c *memRevCache) Insert(_ context.Context, rev *path_mgmt.RevInfo) (bool, e if ttl <= 0 { return false, nil } - k := revcache.NewKey(rev.IA(), rev.IfID) - key := k.String() - val, ok := c.get(key) + key := revcache.NewKey(rev.IA(), rev.IfID) + val, ok := c.c.Get(key) if !ok { - c.c.Set(key, rev, ttl) + c.c.SetWithExpire(key, rev, ttl) return true, nil } if rev.Timestamp().After(val.Timestamp()) { - c.c.Set(key, rev, ttl) + c.c.SetWithExpire(key, rev, ttl) return true, nil } return false, nil @@ -102,7 +88,7 @@ func (c *memRevCache) DeleteExpired(_ context.Context) (int64, error) { c.lock.Lock() defer c.lock.Unlock() var cnt int64 - c.c.OnEvicted(func(string, interface{}) { + c.c.OnEvicted(func(revcache.Key, *path_mgmt.RevInfo) { cnt++ }) c.c.DeleteExpired() diff --git a/private/revcache/memrevcache/memrevcache_test.go b/private/revcache/memrevcache/memrevcache_test.go index 1ee2ff5095..6d2be35049 100644 --- a/private/revcache/memrevcache/memrevcache_test.go +++ b/private/revcache/memrevcache/memrevcache_test.go @@ -37,9 +37,8 @@ func (c *testRevCache) InsertExpired(t *testing.T, _ context.Context, if ttl >= 0 { panic("Should only be used for expired elements") } - k := revcache.NewKey(rev.IA(), rev.IfID) - key := k.String() - c.c.Set(key, rev, time.Microsecond) + key := revcache.NewKey(rev.IA(), rev.IfID) + c.c.SetWithExpire(key, rev, time.Microsecond) // Unfortunately inserting with negative TTL makes entries available forever, // so we use 1 micro second and sleep afterwards // to simulate the insertion of an expired entry. diff --git a/private/revcache/mock_revcache/mock.go b/private/revcache/mock_revcache/mock.go index e5b82df594..a5a2f5f301 100644 --- a/private/revcache/mock_revcache/mock.go +++ b/private/revcache/mock_revcache/mock.go @@ -66,10 +66,10 @@ func (mr *MockRevCacheMockRecorder) DeleteExpired(arg0 interface{}) *gomock.Call } // Get mocks base method. -func (m *MockRevCache) Get(arg0 context.Context, arg1 revcache.KeySet) (revcache.Revocations, error) { +func (m *MockRevCache) Get(arg0 context.Context, arg1 revcache.Key) (*path_mgmt.RevInfo, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Get", arg0, arg1) - ret0, _ := ret[0].(revcache.Revocations) + ret0, _ := ret[0].(*path_mgmt.RevInfo) ret1, _ := ret[1].(error) return ret0, ret1 } diff --git a/private/revcache/revcache.go b/private/revcache/revcache.go index 0e8f061080..0e5826990d 100644 --- a/private/revcache/revcache.go +++ b/private/revcache/revcache.go @@ -43,14 +43,6 @@ func (k Key) String() string { return fmt.Sprintf("%s#%s", k.IA, k.IfID) } -// KeySet is a set of keys. -type KeySet map[Key]struct{} - -// SingleKey is a convenience function to return a KeySet with a single key. -func SingleKey(ia addr.IA, ifID common.IfIDType) KeySet { - return KeySet{Key{IA: ia, IfID: ifID}: {}} -} - // RevOrErr is either a revocation or an error. type RevOrErr struct { Rev *path_mgmt.RevInfo @@ -64,7 +56,7 @@ type ResultChan <-chan RevOrErr type RevCache interface { // Get items with the given keys from the cache. Returns all present requested items that are // not expired or an error if the query failed. - Get(ctx context.Context, keys KeySet) (Revocations, error) + Get(ctx context.Context, key Key) (*path_mgmt.RevInfo, error) // GetAll returns a channel that will provide all items in the revocation cache. If the cache // can't prepare the result channel a nil channel and the error are returned. If the querying // succeeded the channel will contain the revocations in the cache, or an error if the stored @@ -83,6 +75,3 @@ type RevCache interface { db.LimitSetter io.Closer } - -// Revocations is the map of revocations. -type Revocations map[Key]*path_mgmt.RevInfo diff --git a/private/revcache/revcachetest/revcachetest.go b/private/revcache/revcachetest/revcachetest.go index 76e02c2044..c6d55efb80 100644 --- a/private/revcache/revcachetest/revcachetest.go +++ b/private/revcache/revcachetest/revcachetest.go @@ -85,16 +85,15 @@ func testInsertGet(t *testing.T, revCache TestableRevCache) { assert.True(t, inserted, "Insert should return true for a new entry") assert.NoError(t, err, "Insert a new entry should not err") key1 := revcache.NewKey(ia110, ifID15) - revs, err := revCache.Get(ctx, revcache.KeySet{key1: {}}) + aRev, err := revCache.Get(ctx, key1) assert.NoError(t, err, "Get should not err for existing entry") - assert.NotEmpty(t, revs, "Get should return existing entry") - assert.Equal(t, rev, revs[key1], "Get should return previously inserted value") + assert.Equal(t, rev, aRev, "Get should return previously inserted value") inserted, err = revCache.Insert(ctx, rev) assert.False(t, inserted, "Insert should return false for already existing entry") assert.NoError(t, err, "Insert should not err") - revs, err = revCache.Get(ctx, revcache.SingleKey(ia110, ifID19)) + aRev, err = revCache.Get(ctx, revcache.NewKey(ia110, ifID19)) assert.NoError(t, err, "Get should not err") - assert.Empty(t, revs, "Get should return empty result for not present value") + assert.Nil(t, aRev, "Get should return empty result for not present value") } func testGetMultikey(t *testing.T, revCache TestableRevCache) { @@ -105,12 +104,7 @@ func testGetMultikey(t *testing.T, revCache TestableRevCache) { ctx, cancelF := context.WithTimeout(context.Background(), TimeOut) defer cancelF() - // First test the empty cache - revs, err := revCache.Get(ctx, revcache.KeySet{}) - assert.NoError(t, err, "Get should not err") - assert.Empty(t, revs, "Should return no revs") - - _, err = revCache.Insert(ctx, rev1) + _, err := revCache.Insert(ctx, rev1) require.NoError(t, err) _, err = revCache.Insert(ctx, rev2) require.NoError(t, err) @@ -120,22 +114,19 @@ func testGetMultikey(t *testing.T, revCache TestableRevCache) { require.NoError(t, err) key1 := revcache.NewKey(ia110, ifID15) - revs, err = revCache.Get(ctx, revcache.KeySet{key1: {}}) + aRev1, err := revCache.Get(ctx, key1) assert.NoError(t, err, "Get should not err") - assert.Equal(t, len(revs), 1, "Should contain one rev") - assert.Equal(t, revcache.Revocations{key1: rev1}, revs, - "Get should return revs for the given keys") + assert.Equal(t, rev1, aRev1, "Get should return rev for the given keys") key2 := revcache.NewKey(ia110, ifID19) key3 := revcache.NewKey(ia120, ifID15) key4 := revcache.NewKey(ia120, ifID19) // not the key of sr4 - searchKeys := revcache.KeySet{key1: {}, key2: {}, key3: {}, key4: {}} - revs, err = revCache.Get(ctx, searchKeys) - assert.NoError(t, err, "Get should not err") - expectedResult := revcache.Revocations{ - key1: rev1, key2: rev2, key3: rev3, + searchKeys := map[revcache.Key]*path_mgmt.RevInfo{key1: rev1, key2: rev2, key3: rev3, key4: nil} + for key, eRev := range searchKeys { + aRev, err := revCache.Get(ctx, key) + assert.NoError(t, err, "Get should not err") + assert.Equal(t, eRev, aRev, "Get should return the requested revocation for key %s", key) } - assert.Equal(t, expectedResult, revs, "Get should return the requested revocations") } func testGetAll(t *testing.T, revCache TestableRevCache) { @@ -235,10 +226,9 @@ func testInsertNewer(t *testing.T, revCache TestableRevCache) { assert.True(t, inserted, "Insert should return true for a new entry") assert.NoError(t, err, "Insert a new entry should not err") key1 := revcache.NewKey(ia110, ifID15) - revs, err := revCache.Get(ctx, revcache.KeySet{key1: {}}) + aRev, err := revCache.Get(ctx, key1) assert.NoError(t, err, "Get should not err for existing entry") - assert.NotEmpty(t, revs, "Get should return non empty map for inserted value") - assert.Equal(t, revNew, revs[key1], "Get should return previously inserted value") + assert.Equal(t, revNew, aRev, "Get should return previously inserted value") } func testGetExpired(t *testing.T, revCache TestableRevCache) { @@ -252,8 +242,8 @@ func testGetExpired(t *testing.T, revCache TestableRevCache) { RawTTL: 1, } revCache.InsertExpired(t, ctx, revNew) - revs, err := revCache.Get(ctx, revcache.SingleKey(ia110, ifID15)) - assert.Empty(t, revs, "Expired entry should not be returned") + aRev, err := revCache.Get(ctx, revcache.NewKey(ia110, ifID15)) + assert.Nil(t, aRev, "Expired entry should not be returned") assert.NoError(t, err, "Should not error for expired entry") } @@ -272,13 +262,12 @@ func testGetMuliKeysExpired(t *testing.T, revCache TestableRevCache) { _, err := revCache.Insert(ctx, rev110_19) assert.NoError(t, err) validKey := revcache.NewKey(ia110, ifID19) - srCache, err := revCache.Get(ctx, revcache.KeySet{ - revcache.NewKey(ia110, ifID15): {}, - validKey: {}, - }) + aRev, err := revCache.Get(ctx, validKey) + assert.NoError(t, err, "Should not error for valid entry") + assert.Equal(t, rev110_19, aRev, "Valid entry should be returned") + aRev, err = revCache.Get(ctx, revcache.NewKey(ia110, ifID15)) + assert.Nil(t, aRev, "Expired entry should not be returned") assert.NoError(t, err, "Should not error for expired entry") - assert.Equal(t, revcache.Revocations{validKey: rev110_19}, srCache, - "Expired entry should not be returned") } func testDeleteExpired(t *testing.T, revCache TestableRevCache) { diff --git a/private/revcache/util.go b/private/revcache/util.go index db0e1894e1..ded1166999 100644 --- a/private/revcache/util.go +++ b/private/revcache/util.go @@ -17,7 +17,6 @@ package revcache import ( "context" - "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/private/common" seg "github.com/scionproto/scion/pkg/segment" "github.com/scionproto/scion/private/storage/cleaner" @@ -35,33 +34,20 @@ func NewCleaner(rc RevCache, s string) *cleaner.Cleaner { func NoRevokedHopIntf(ctx context.Context, revCache RevCache, s *seg.PathSegment) (bool, error) { - revKeys := make(KeySet) - addRevKeys([]*seg.PathSegment{s}, revKeys, true) - revs, err := revCache.Get(ctx, revKeys) - return len(revs) == 0, err -} - -// addRevKeys adds all revocations keys for the given segments to the keys set. -// If hopOnly is set, only the first hop entry is considered. -func addRevKeys(segs []*seg.PathSegment, keys KeySet, hopOnly bool) { - addIntfs := func(ia addr.IA, ingress, egress uint16) { - if ingress != 0 { - keys[Key{IA: ia, IfID: common.IfIDType(ingress)}] = struct{}{} - } - if egress != 0 { - keys[Key{IA: ia, IfID: common.IfIDType(egress)}] = struct{}{} - } - } - for _, s := range segs { - for _, asEntry := range s.ASEntries { - hop := asEntry.HopEntry.HopField - addIntfs(asEntry.Local, hop.ConsIngress, hop.ConsEgress) - if hopOnly { - continue + for _, asEntry := range s.ASEntries { + hop := asEntry.HopEntry.HopField + for _, key := range [2]Key{ + {IA: asEntry.Local, IfID: common.IfIDType(hop.ConsIngress)}, + {IA: asEntry.Local, IfID: common.IfIDType(hop.ConsEgress)}, + } { + rev, err := revCache.Get(ctx, key) + if err != nil || rev != nil { + return false, err } - for _, peer := range asEntry.PeerEntries { - addIntfs(asEntry.Local, peer.HopField.ConsIngress, peer.HopField.ConsEgress) + if rev != nil { + return false, nil } } } + return true, nil } diff --git a/private/revcache/util_test.go b/private/revcache/util_test.go index 94e92f1651..01f71672f3 100644 --- a/private/revcache/util_test.go +++ b/private/revcache/util_test.go @@ -49,20 +49,23 @@ func TestNoRevokedHopIntf(t *testing.T) { t.Run("empty", func(t *testing.T) { revCache := mock_revcache.NewMockRevCache(ctrl) - revCache.EXPECT().Get(gomock.Eq(ctx), gomock.Any()) + revCache.EXPECT().Get(gomock.Eq(ctx), gomock.Any()).AnyTimes() noR, err := revcache.NoRevokedHopIntf(ctx, revCache, seg210_222_1) assert.NoError(t, err) assert.True(t, noR, "no revocation expected") }) t.Run("on segment revocation", func(t *testing.T) { - sRev := defaultRevInfo(ia211, graph.If_210_X_211_A, now) + sRev := defaultRevInfo(ia211, graph.If_211_A_210_X, now) revCache := mock_revcache.NewMockRevCache(ctrl) - revCache.EXPECT().Get(gomock.Eq(ctx), gomock.Any()).Return( - revcache.Revocations{ - revcache.Key{IA: addr.MustParseIA("2-ff00:0:211"), - IfID: common.IfIDType(graph.If_210_X_211_A)}: sRev, - }, nil, - ) + revCache.EXPECT().Get(gomock.Eq(ctx), gomock.Any()).DoAndReturn( + func(_ context.Context, key revcache.Key) (*path_mgmt.RevInfo, error) { + iaFmt := key.IA.String() + _ = iaFmt + if key.IA == ia211 && key.IfID == common.IfIDType(graph.If_211_A_210_X) { + return sRev, nil + } + return nil, nil + }).AnyTimes() noR, err := revcache.NoRevokedHopIntf(ctx, revCache, seg210_222_1) assert.NoError(t, err) assert.False(t, noR, "revocation expected") @@ -71,7 +74,7 @@ func TestNoRevokedHopIntf(t *testing.T) { revCache := mock_revcache.NewMockRevCache(ctrl) revCache.EXPECT().Get(gomock.Eq(ctx), gomock.Any()).Return( nil, serrors.New("TestError"), - ) + ).AnyTimes() _, err := revcache.NoRevokedHopIntf(ctx, revCache, seg210_222_1) assert.Error(t, err) }) diff --git a/private/segment/segfetcher/pather.go b/private/segment/segfetcher/pather.go index 8d8ce965ec..47668c5cae 100644 --- a/private/segment/segfetcher/pather.go +++ b/private/segment/segfetcher/pather.go @@ -133,21 +133,22 @@ func (p *Pather) filterRevoked(ctx context.Context, logger := log.FromCtx(ctx) var newPaths []combinator.Path + debugOn := logger.Enabled(log.DebugLevel) revokedInterfaces := make(map[snet.PathInterface]struct{}) for _, path := range paths { revoked := false for _, iface := range path.Metadata.Interfaces { // cache automatically expires outdated revocations every second, // so a cache hit implies revocation is still active. - revs, err := p.RevCache.Get(ctx, revcache.SingleKey(iface.IA, iface.ID)) + rev, err := p.RevCache.Get(ctx, revcache.NewKey(iface.IA, iface.ID)) if err != nil { logger.Error("Failed to get revocation", "err", err) // continue, the client might still get some usable paths like this. } - if len(revs) > 0 { + if rev != nil && debugOn { revokedInterfaces[snet.PathInterface{IA: iface.IA, ID: iface.ID}] = struct{}{} } - revoked = revoked || len(revs) > 0 + revoked = revoked || rev != nil } if !revoked { newPaths = append(newPaths, path) diff --git a/private/segment/segfetcher/resolver_test.go b/private/segment/segfetcher/resolver_test.go index d452476fd9..06f27bdca1 100644 --- a/private/segment/segfetcher/resolver_test.go +++ b/private/segment/segfetcher/resolver_test.go @@ -16,7 +16,6 @@ package segfetcher_test import ( "context" - "fmt" "testing" "time" @@ -389,10 +388,9 @@ func TestResolverWithRevocations(t *testing.T) { futureT := time.Now().Add(2 * time.Minute) revoke := func(t *testing.T, revCache *mock_revcache.MockRevCache, key revcache.Key) { - ksMatcher := keySetContains{keys: []revcache.Key{key}} rev := &path_mgmt.RevInfo{} - revCache.EXPECT().Get(gomock.Any(), ksMatcher). - Return(revcache.Revocations{key: rev}, nil) + revCache.EXPECT().Get(gomock.Any(), key). + Return(rev, nil) } tests := map[string]resolverTest{ "Up wildcard (cached)": { @@ -447,11 +445,8 @@ func TestResolverWithRevocations(t *testing.T) { }, ExpectRevcache: func(t *testing.T, revCache *mock_revcache.MockRevCache) { key110 := revcache.Key{IA: core_110, IfID: common.IfIDType(graph.If_110_X_130_A)} - ksMatcher := keySetContains{keys: []revcache.Key{key110}} rev := &path_mgmt.RevInfo{} - revCache.EXPECT().Get(gomock.Any(), ksMatcher).Return(revcache.Revocations{ - key110: rev, - }, nil) + revCache.EXPECT().Get(gomock.Any(), key110).Return(rev, nil) revCache.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes() }, ExpectedSegments: segfetcher.Segments{tg.seg210_130_core, tg.seg210_130_2_core}, @@ -475,27 +470,6 @@ func resultsFromSegs(segs ...*seg.Meta) query.Results { return results } -type keySetContains struct { - keys []revcache.Key -} - -func (m keySetContains) Matches(other interface{}) bool { - ks, ok := other.(revcache.KeySet) - if !ok { - return false - } - for _, k := range m.keys { - if _, ok := ks[k]; !ok { - return false - } - } - return true -} - -func (m keySetContains) String() string { - return fmt.Sprintf("revcache.KeySet containing %v", m.keys) -} - type neverLocal struct{} func (neverLocal) IsSegLocal(_ segfetcher.Request) bool { From a864a8c12e228cf0a891f6ab81ce5daf8f3673c8 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:18:45 +0200 Subject: [PATCH 14/29] topology: allow peering links between core ASes (#4605) Fixes #4484 --- .buildkite/pipeline.yml | 6 ++--- control/beaconing/originator.go | 8 +++++- control/beaconing/originator_test.go | 3 +++ control/beaconing/testdata/topology-core.json | 10 +++++++ private/path/combinator/combinator_test.go | 27 ++++++++++++++++--- .../testdata/00_core_core_invalid_peering.txt | 25 +++++++++++++++++ .../combinator/testdata/00_multi_peering.txt | 22 +++++++++++++++ private/topology/topology.go | 2 +- tools/await-connectivity | 11 +++++--- 9 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 private/path/combinator/testdata/00_core_core_invalid_peering.txt diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 72c9c14cdb..766833d3ce 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -116,7 +116,7 @@ steps: - ./scion.sh run - tools/await-connectivity - ./bin/scion_integration || ( echo "^^^ +++" && false ) - - ./bin/end2end_integration || ( echo "^^^ +++" && false ) + - ./bin/end2end_integration --attempts=3 || ( echo "^^^ +++" && false ) plugins: &scion-run-hooks - scionproto/metahook#v0.3.0: pre-command: .buildkite/cleanup-leftovers.sh @@ -142,7 +142,7 @@ steps: - ./scion.sh topology -c topology/default-no-peers.topo - ./scion.sh run - tools/await-connectivity - - ./bin/end2end_integration || ( echo "^^^ +++" && false ) + - ./bin/end2end_integration --attempts=3 || ( echo "^^^ +++" && false ) - ./tools/integration/revocation_test.sh plugins: *scion-run-hooks artifact_paths: *scion-run-artifact-paths @@ -158,7 +158,7 @@ steps: - ./scion.sh run - tools/await-connectivity - echo "--- run tests" - - ./bin/end2end_integration -d || ( echo "^^^ +++" && false ) + - ./bin/end2end_integration -d --attempts=3 || ( echo "^^^ +++" && false ) plugins: *scion-run-hooks artifact_paths: *scion-run-artifact-paths timeout_in_minutes: 15 diff --git a/control/beaconing/originator.go b/control/beaconing/originator.go index c35b4e9038..3c7bf2067c 100644 --- a/control/beaconing/originator.go +++ b/control/beaconing/originator.go @@ -32,6 +32,7 @@ import ( "github.com/scionproto/scion/pkg/private/serrors" seg "github.com/scionproto/scion/pkg/segment" "github.com/scionproto/scion/private/periodic" + "github.com/scionproto/scion/private/topology" ) var _ periodic.Task = (*Originator)(nil) @@ -95,6 +96,9 @@ func (o *Originator) originateBeacons(ctx context.Context) { return } + // Core ases can have peering too. Fetch the peering interfaces. + peers := sortedIntfs(o.AllInterfaces, topology.Peer) + // Only log on info and error level every propagation period to reduce // noise. The offending logs events are redirected to debug level. silent := !o.Tick.Passed() @@ -109,6 +113,7 @@ func (o *Originator) originateBeacons(ctx context.Context) { intf: intf, timestamp: o.Tick.Now(), summary: s, + peers: peers, } go func() { defer log.HandlePanic() @@ -154,6 +159,7 @@ type beaconOriginator struct { intf *ifstate.Interface timestamp time.Time summary *summary + peers []uint16 } // originateBeacon originates a beacon on the given ifID. @@ -206,7 +212,7 @@ func (o *beaconOriginator) createBeacon(ctx context.Context) (*seg.PathSegment, return nil, serrors.Wrap("creating segment", err) } - if err := o.Extender.Extend(ctx, beacon, 0, o.intf.TopoInfo().ID, nil); err != nil { + if err := o.Extender.Extend(ctx, beacon, 0, o.intf.TopoInfo().ID, o.peers); err != nil { return nil, serrors.Wrap("extending segment", err) } return beacon, nil diff --git a/control/beaconing/originator_test.go b/control/beaconing/originator_test.go index e7d64673a5..63d625bfe3 100644 --- a/control/beaconing/originator_test.go +++ b/control/beaconing/originator_test.go @@ -104,6 +104,9 @@ func TestOriginatorRun(t *testing.T) { hopF := b.ASEntries[b.MaxIdx()].HopEntry.HopField // Check the interface matches. assert.Equal(t, hopF.ConsEgress, egIfID) + // Check that the expected peering entry is there too. + peering := b.ASEntries[b.MaxIdx()].PeerEntries[0] + assert.Equal(t, peering.HopField.ConsIngress, uint16(4242)) // Check that the beacon is sent to the correct border router. br := net.UDPAddrFromAddrPort(interfaceInfos(topo)[egIfID].InternalAddr) assert.Equal(t, br, nextHop) diff --git a/control/beaconing/testdata/topology-core.json b/control/beaconing/testdata/topology-core.json index 11284ccd2f..eaae64d627 100644 --- a/control/beaconing/testdata/topology-core.json +++ b/control/beaconing/testdata/topology-core.json @@ -45,6 +45,16 @@ "isd_as": "1-ff00:0:111", "link_to": "CHILD", "mtu": 1280 + }, + "4242": { + "underlay": { + "local": "127.0.0.5:0", + "remote": "127.0.0.4:0" + }, + "isd_as": "2-ff00:0:220", + "link_to": "PEER", + "remote_interface_id": 2424, + "mtu": 1280 } } } diff --git a/private/path/combinator/combinator_test.go b/private/path/combinator/combinator_test.go index 15bb1b6d4e..af67f0ebf4 100644 --- a/private/path/combinator/combinator_test.go +++ b/private/path/combinator/combinator_test.go @@ -96,10 +96,12 @@ func TestBadPeering(t *testing.T) { } } -func TestMultiPeering(t *testing.T) { +func TestMiscPeering(t *testing.T) { ctrl := gomock.NewController(t) defer ctrl.Finish() g := graph.NewDefaultGraph(ctrl) + // Add a core-core peering link. It can be used in some cases. + g.AddLink("1-ff00:0:130", 4001, "2-ff00:0:210", 4002, true) testCases := []struct { Name string @@ -111,7 +113,7 @@ func TestMultiPeering(t *testing.T) { Downs []*seg.PathSegment }{ { - Name: "two peerings between same ases", + Name: "two peerings between same ases and core core peering", FileName: "00_multi_peering.txt", SrcIA: addr.MustParseIA("1-ff00:0:112"), DstIA: addr.MustParseIA("2-ff00:0:212"), @@ -125,8 +127,27 @@ func TestMultiPeering(t *testing.T) { g.Beacon([]uint16{graph.If_210_X_211_A, graph.If_211_A_212_X}), }, }, + { + // In this case, the 130-210 peering link should not be used (the router would reject) + // because the hop through 210 would be assimilated to a valley path: one of the + // joined segments is a core segment, not a down segment. + Name: "core to core peering forbidden", + FileName: "00_core_core_invalid_peering.txt", + SrcIA: addr.MustParseIA("1-ff00:0:131"), + DstIA: addr.MustParseIA("2-ff00:0:221"), + Ups: []*seg.PathSegment{ + g.Beacon([]uint16{graph.If_130_A_131_X}), + }, + Cores: []*seg.PathSegment{ + g.Beacon([]uint16{ + graph.If_220_X_210_X, graph.If_210_X_110_X, graph.If_110_X_130_A}), + }, + Downs: []*seg.PathSegment{ + g.Beacon([]uint16{graph.If_220_X_221_X}), + }, + }, } - t.Log("TestMultiPeering") + t.Log("TestMiscPeering") for _, tc := range testCases { t.Run(tc.Name, func(t *testing.T) { result := combinator.Combine(tc.SrcIA, tc.DstIA, tc.Ups, tc.Cores, tc.Downs, false) diff --git a/private/path/combinator/testdata/00_core_core_invalid_peering.txt b/private/path/combinator/testdata/00_core_core_invalid_peering.txt new file mode 100644 index 0000000000..6b712da657 --- /dev/null +++ b/private/path/combinator/testdata/00_core_core_invalid_peering.txt @@ -0,0 +1,25 @@ +Path #0: + Weight: 5 + Fields: + IF .. + HF InIF=1613 OutIF=0 + HF InIF=0 OutIF=1316 + IF .. + HF InIF=1311 OutIF=0 + HF InIF=1121 OutIF=1113 + HF InIF=2122 OutIF=2111 + HF InIF=0 OutIF=2221 + IF C. + HF InIF=0 OutIF=2224 + HF InIF=2422 OutIF=0 + Interfaces: + 1-ff00:0:131#1613 + 1-ff00:0:130#1316 + 1-ff00:0:130#1311 + 1-ff00:0:110#1113 + 1-ff00:0:110#1121 + 2-ff00:0:210#2111 + 2-ff00:0:210#2122 + 2-ff00:0:220#2221 + 2-ff00:0:220#2224 + 2-ff00:0:221#2422 diff --git a/private/path/combinator/testdata/00_multi_peering.txt b/private/path/combinator/testdata/00_multi_peering.txt index d0aafe0697..e6191e236c 100644 --- a/private/path/combinator/testdata/00_multi_peering.txt +++ b/private/path/combinator/testdata/00_multi_peering.txt @@ -31,6 +31,28 @@ Path #1: 2-ff00:0:211#2325 2-ff00:0:212#2523 Path #2: + Weight: 5 + Fields: + IF .P + HF InIF=1714 OutIF=0 + HF InIF=1432 OutIF=1417 + HF InIF=4001 OutIF=3214 + IF CP + HF InIF=4002 OutIF=2123 + HF InIF=2321 OutIF=2325 + HF InIF=2523 OutIF=0 + Interfaces: + 1-ff00:0:112#1714 + 1-ff00:0:111#1417 + 1-ff00:0:111#1432 + 1-ff00:0:130#3214 + 1-ff00:0:130#4001 + 2-ff00:0:210#4002 + 2-ff00:0:210#2123 + 2-ff00:0:211#2321 + 2-ff00:0:211#2325 + 2-ff00:0:212#2523 +Path #3: Weight: 6 Fields: IF .. diff --git a/private/topology/topology.go b/private/topology/topology.go index ef1234a602..4677a61592 100644 --- a/private/topology/topology.go +++ b/private/topology/topology.go @@ -593,7 +593,7 @@ func (m IDAddrMap) copy() IDAddrMap { func (i IFInfo) CheckLinks(isCore bool, brName string) error { if isCore { switch i.LinkType { - case Core, Child: + case Core, Child, Peer: default: return serrors.New("Illegal link type for core AS", "type", i.LinkType, "br", brName) diff --git a/tools/await-connectivity b/tools/await-connectivity index 4f0d1f2aee..e0876f1509 100755 --- a/tools/await-connectivity +++ b/tools/await-connectivity @@ -61,7 +61,7 @@ check_connectivity() { for as in $cores; do missing=$(comm -23 \ <(printf "%s\n" $cores | grep -v $as | sort) \ - <(curl -sfS $(cs_api_url_segments "$as") | jq '.[].start_isd_as' -r | sort -u) + <(curl --connect-timeout 5 -sfS $(cs_api_url_segments "$as") | jq '.[].start_isd_as' -r | sort -u) ) if [ -n "$missing" ]; then echo "$as: waiting for" $missing @@ -71,7 +71,7 @@ check_connectivity() { # non-core ASes: wait for at least one (up-)segment for as in $noncores; do - curl -sfS $(cs_api_url_segments "$as") | jq -e 'length > 0' > /dev/null || { + curl --connect-timeout 5 -sfS $(cs_api_url_segments "$as") | jq -e 'length > 0' > /dev/null || { echo "$as waiting for up segment" ret=1 } @@ -88,12 +88,12 @@ main() { local noncores=$(sed -n '/Non-core/,${s/^- //p}' gen/as_list.yml) for i in $(seq 1 "$QUIET"); do - check_connectivity "$cores" "$noncores" > /dev/null && exit 0 + check_connectivity "$cores" "$noncores" > /dev/null && return 0 sleep 1 done for i in $(seq "$QUIET" $((TIMEOUT-1))); do echo "Check after ${i}s" - check_connectivity "$cores" "$noncores" && exit 0 + check_connectivity "$cores" "$noncores" && return 0 sleep 1 done echo "Check after ${TIMEOUT}s" @@ -101,3 +101,6 @@ main() { } main "$@" + +# that is not enough. Down segment registrations don't seem to happen fast. +sleep 10 From e88ddce159a03039b64907be17186aa3787021f5 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Mon, 9 Sep 2024 12:41:08 +0200 Subject: [PATCH 15/29] ci: udate version of upload artefact action (#4613) --- .github/workflows/gobra.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gobra.yml b/.github/workflows/gobra.yml index 4dadbab9e8..5d544611d1 100644 --- a/.github/workflows/gobra.yml +++ b/.github/workflows/gobra.yml @@ -33,7 +33,7 @@ jobs: caching: '1' statsFile: ${{ env.statsFile }} - name: Upload the verification report - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: verification_stats.json path: ${{ env.statsFile }} From 79e7080b3f9471434c3b2e35026ae43dec794c9d Mon Sep 17 00:00:00 2001 From: Marten Gartner Date: Mon, 9 Sep 2024 12:59:16 +0200 Subject: [PATCH 16/29] underlay: support SockOptInt on all platforms incl Windows (#4610) There is an issue that `syscall.GetsockoptInt` and `syscall.SetsockoptInt` have different signatures on windows than on all other platforms. One fix is to have extra windows code to support this. In the end it would be great to have Windows support for all SCION services, too. The issue popped up when building the router, not sure if it affects other services. --- private/underlay/sockctrl/BUILD.bazel | 48 ++++++++++++++++++- private/underlay/sockctrl/sockctrl.go | 6 +-- private/underlay/sockctrl/sockctrl_windows.go | 43 +++++++++++++++++ private/underlay/sockctrl/sockopt.go | 3 ++ private/underlay/sockctrl/sockopt_windows.go | 39 +++++++++++++++ 5 files changed, 134 insertions(+), 5 deletions(-) create mode 100644 private/underlay/sockctrl/sockctrl_windows.go create mode 100644 private/underlay/sockctrl/sockopt_windows.go diff --git a/private/underlay/sockctrl/BUILD.bazel b/private/underlay/sockctrl/BUILD.bazel index 67e19ae27d..f1d0dfe0db 100644 --- a/private/underlay/sockctrl/BUILD.bazel +++ b/private/underlay/sockctrl/BUILD.bazel @@ -4,9 +4,55 @@ go_library( name = "go_default_library", srcs = [ "sockctrl.go", + "sockctrl_windows.go", "sockopt.go", + "sockopt_windows.go", ], importpath = "github.com/scionproto/scion/private/underlay/sockctrl", visibility = ["//visibility:public"], - deps = ["//pkg/private/serrors:go_default_library"], + deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:android": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:darwin": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:dragonfly": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:freebsd": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:ios": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:netbsd": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:openbsd": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:plan9": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:solaris": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "//pkg/private/serrors:go_default_library", + ], + "//conditions:default": [], + }), ) diff --git a/private/underlay/sockctrl/sockctrl.go b/private/underlay/sockctrl/sockctrl.go index 2faeef054a..af9dc41692 100644 --- a/private/underlay/sockctrl/sockctrl.go +++ b/private/underlay/sockctrl/sockctrl.go @@ -12,11 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build go1.9 -// +build go1.9 +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build !windows -// This version of sockctrl is for Go versions >= 1.9, where the socket FDs are -// accessible via RawConn.Control(). package sockctrl import ( diff --git a/private/underlay/sockctrl/sockctrl_windows.go b/private/underlay/sockctrl/sockctrl_windows.go new file mode 100644 index 0000000000..81fd84c7bb --- /dev/null +++ b/private/underlay/sockctrl/sockctrl_windows.go @@ -0,0 +1,43 @@ +// Copyright 2024 ETH Zurich +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build windows + +package sockctrl + +import ( + "net" + "syscall" + + "github.com/scionproto/scion/pkg/private/serrors" +) + +func SockControl(c *net.UDPConn, f func(syscall.Handle) error) error { + rawConn, err := c.SyscallConn() + if err != nil { + return serrors.Wrap("sockctrl: error accessing raw connection", err) + } + var ctrlErr error + err = rawConn.Control(func(fd uintptr) { + ctrlErr = f(syscall.Handle(fd)) + }) + if err != nil { + return serrors.Wrap("sockctrl: RawConn.Control error", err) + } + if ctrlErr != nil { + return serrors.Wrap("sockctrl: control function error", ctrlErr) + } + return nil +} diff --git a/private/underlay/sockctrl/sockopt.go b/private/underlay/sockctrl/sockopt.go index cbf9339f06..d5b56e5cfc 100644 --- a/private/underlay/sockctrl/sockopt.go +++ b/private/underlay/sockctrl/sockopt.go @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build !windows + package sockctrl import ( diff --git a/private/underlay/sockctrl/sockopt_windows.go b/private/underlay/sockctrl/sockopt_windows.go new file mode 100644 index 0000000000..8a9ceb07b8 --- /dev/null +++ b/private/underlay/sockctrl/sockopt_windows.go @@ -0,0 +1,39 @@ +// Copyright 2024 ETH Zurich +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build windows + +package sockctrl + +import ( + "net" + "syscall" +) + +func GetsockoptInt(c *net.UDPConn, level, opt int) (int, error) { + var val int + err := SockControl(c, func(fd syscall.Handle) error { + var err error + val, err = syscall.GetsockoptInt(fd, level, opt) + return err + }) + return val, err +} + +func SetsockoptInt(c *net.UDPConn, level, opt, value int) error { + return SockControl(c, func(fd syscall.Handle) error { + return syscall.SetsockoptInt(fd, level, opt, value) + }) +} From a9e9256f2af464e348db2342be7e905c054a174a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pereira?= Date: Thu, 12 Sep 2024 18:36:53 +0200 Subject: [PATCH 17/29] router: make `AddLinkType` acquire the DataPlane mutex (#4614) Fixes issue #4282. With this change, the implementation of `AddLinkType` matches that of the other setters and the comment that precedes it. --- router/dataplane.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/router/dataplane.go b/router/dataplane.go index 36b7146c5f..1701fcc8ab 100644 --- a/router/dataplane.go +++ b/router/dataplane.go @@ -405,6 +405,11 @@ func (d *DataPlane) AddNeighborIA(ifID uint16, remote addr.IA) error { // the given ID is already set, this method will return an error. This can only // be called on a not yet running dataplane. func (d *DataPlane) AddLinkType(ifID uint16, linkTo topology.LinkType) error { + d.mtx.Lock() + defer d.mtx.Unlock() + if d.IsRunning() { + return modifyExisting + } if _, exists := d.linkTypes[ifID]; exists { return serrors.JoinNoStack(alreadySet, nil, "ifID", ifID) } From 2663569dcb32d8023c98a9b5fe9be53d7b88a2f6 Mon Sep 17 00:00:00 2001 From: Sebastian Leisinger Date: Fri, 13 Sep 2024 13:12:52 +0200 Subject: [PATCH 18/29] tracing: wrap existing logger instead of creating a new one (#4616) When starting a span from Context add the debug_id and tracing_id to the logger on the context (if it exists) instead of creating a new one. This preserves the logger that is attached to the parentCtx. --- private/tracing/context.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/private/tracing/context.go b/private/tracing/context.go index 4cad2c3423..ae2b5cf0b7 100644 --- a/private/tracing/context.go +++ b/private/tracing/context.go @@ -32,9 +32,11 @@ func CtxWith(parentCtx context.Context, operationName string, span, ctx := opentracing.StartSpanFromContext(parentCtx, operationName, opts...) if spanCtx, ok := span.Context().(jaeger.SpanContext); ok { id := spanCtx.TraceID() - return span, log.CtxWith(ctx, log.New("debug_id", id.String()[:8], "trace_id", id)) + ctx, _ = log.WithLabels(ctx, "debug_id", id.String()[:8], "trace_id", id) + return span, ctx } - return span, log.CtxWith(ctx, log.New("debug_id", log.NewDebugID())) + ctx, _ = log.WithLabels(ctx, "debug_id", log.NewDebugID()) + return span, ctx } // LoggerWith attaches the trace ID if the context contains a span. From 22a3c24ead862ed4654f4909c43da25d74bb99ba Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Fri, 13 Sep 2024 23:12:24 +0200 Subject: [PATCH 19/29] ci: allow dash in subsystem (#4612) Allow scion-pki, see #4611 --- .github/workflows/pr-title.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-title.yml b/.github/workflows/pr-title.yml index 41a54c144c..c875e63bb4 100644 --- a/.github/workflows/pr-title.yml +++ b/.github/workflows/pr-title.yml @@ -15,13 +15,13 @@ jobs: # Check that PR is of the form `: ` url='https://docs.scion.org/en/latest/dev/git.html#good-commit-messages' - if [[ ! "$TITLE" =~ ^[a-z0-9,/]*:[[:space:]] ]]; then + if [[ ! "$TITLE" =~ ^[a-z0-9,/-]*:[[:space:]] ]]; then echo '::error::The PR title should start with `: `. See '"$url" exit 1 fi # Title should be lower case; initialisms and identifiers still occur occasionally and should be allowed. # -> enforce only the first word - if [[ ! "$TITLE" =~ ^[a-z0-9,/]*:[[:space:]][a-z] ]]; then + if [[ ! "$TITLE" =~ ^[a-z0-9,/-]*:[[:space:]][a-z] ]]; then echo '::error::The PR title should be lower case (enforced on first letter). See '"$url" exit 1 fi From a192c66db0041fdbfda27ab1056559b0447dde9b Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Tue, 17 Sep 2024 10:45:46 +0200 Subject: [PATCH 20/29] doc: rewrite TRC ceremony documentation to include scion-pki (#4615) Rewrite the TRC ceremony documentation to include the scion-pki tool which is a lot more ergonomic than openssl based approach. The openssl based approach is still kept such that people do not need to trust the distributed scion-pki tool. Furthermore, the documentation and tests are updated to use openssl 3.0.14. And finally, the scion-pki tool is extended to support RFC3339 based timestamps when creating TRC payloads for both NotBefore and NotAfter fields. The legacy unix timestamp and duration based validity time are still supported. --- Makefile | 1 + doc/command/scion-pki/scion-pki_trc.rst | 2 +- .../scion-pki/scion-pki_trc_inspect.rst | 8 +- doc/conf.py | 51 +-- doc/cryptography/ca-operations.rst | 252 +++++++++----- .../trc-signing-ceremony-phases-base.rst | 268 +++++++++++---- .../trc-signing-ceremony-phases-sensitive.rst | 267 ++++++++++++--- .../trc-signing-ceremony-preparations.rst | 318 +++++++++++++----- doc/requirements.in | 9 +- doc/requirements.txt | 19 +- pkg/scrypto/cppki/trc.go | 6 +- scion-pki/cmd/scion-pki/version.go | 2 +- scion-pki/conf/testdata/testcfg.rfc3339.toml | 13 + scion-pki/conf/testdata/testcfg.unix.toml | 13 + scion-pki/conf/trc.go | 3 + scion-pki/conf/trc_test.go | 24 +- scion-pki/conf/validity.go | 46 ++- scion-pki/testcrypto/testcrypto.go | 2 +- scion-pki/trcs/BUILD.bazel | 6 +- scion-pki/trcs/{human.go => inspect.go} | 8 +- .../trcs/{human_test.go => inspect_test.go} | 0 tools/buildrill/_check_gazelle_mode | 12 + tools/buildrill/go_integration_test_sync | 15 + tools/cryptoplayground/BUILD.bazel | 35 ++ tools/cryptoplayground/crypto_lib.sh | 201 ++++++++++- tools/cryptoplayground/trc_ceremony.sh | 117 +++++-- .../trc_ceremony_sensitive.sh | 79 ++++- 27 files changed, 1382 insertions(+), 395 deletions(-) create mode 100644 scion-pki/conf/testdata/testcfg.rfc3339.toml create mode 100644 scion-pki/conf/testdata/testcfg.unix.toml rename scion-pki/trcs/{human.go => inspect.go} (97%) rename scion-pki/trcs/{human_test.go => inspect_test.go} (100%) create mode 100755 tools/buildrill/_check_gazelle_mode create mode 100755 tools/buildrill/go_integration_test_sync diff --git a/Makefile b/Makefile index d82db1af82..25e994ea58 100644 --- a/Makefile +++ b/Makefile @@ -86,6 +86,7 @@ mocks: gazelle: go_deps.bzl bazel run //:gazelle --verbose_failures --config=quiet + ./tools/buildrill/go_integration_test_sync licenses: tools/licenses.sh diff --git a/doc/command/scion-pki/scion-pki_trc.rst b/doc/command/scion-pki/scion-pki_trc.rst index 1fe83166b4..8ce820ac61 100644 --- a/doc/command/scion-pki/scion-pki_trc.rst +++ b/doc/command/scion-pki/scion-pki_trc.rst @@ -27,7 +27,7 @@ SEE ALSO * :ref:`scion-pki trc combine ` - Combine partially signed TRCs * :ref:`scion-pki trc extract ` - Extract parts of a signed TRC * :ref:`scion-pki trc format ` - Reformat a TRC or TRC payload -* :ref:`scion-pki trc inspect ` - Represent TRC in a human readable form +* :ref:`scion-pki trc inspect ` - Print TRC details in a human readable format * :ref:`scion-pki trc payload ` - Generate new TRC payload * :ref:`scion-pki trc sign ` - Sign a TRC * :ref:`scion-pki trc verify ` - Verify a TRC chain diff --git a/doc/command/scion-pki/scion-pki_trc_inspect.rst b/doc/command/scion-pki/scion-pki_trc_inspect.rst index 39ffbd38d1..0caa37ea17 100644 --- a/doc/command/scion-pki/scion-pki_trc_inspect.rst +++ b/doc/command/scion-pki/scion-pki_trc_inspect.rst @@ -5,13 +5,13 @@ scion-pki trc inspect --------------------- -Represent TRC in a human readable form +Print TRC details in a human readable format Synopsis ~~~~~~~~ -'human' outputs the TRC contents in a human readable form. +'inspect' prints the details of a TRC a human-readable fromat. The input file can either be a TRC payload, or a signed TRC. The output can either be in yaml, or json. @@ -29,8 +29,8 @@ Examples :: - scion-pki trc human ISD1-B1-S1.pld.der - scion-pki trc human ISD1-B1-S1.trc + scion-pki trc inspect ISD1-B1-S1.pld.der + scion-pki trc inspect ISD1-B1-S1.trc Options ~~~~~~~ diff --git a/doc/conf.py b/doc/conf.py index e41f7b1b42..9f26c8ac5d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -7,9 +7,9 @@ # -- Project information ----------------------------------------------------- -project = 'SCION' -copyright = '2023, Anapaya Systems, ETH Zurich, SCION Association' -author = 'Anapaya Systems, ETH Zurich, SCION Association' +project = "SCION" +copyright = "2023, Anapaya Systems, ETH Zurich, SCION Association" +author = "Anapaya Systems, ETH Zurich, SCION Association" # -- General configuration --------------------------------------------------- @@ -18,32 +18,37 @@ # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'recommonmark', - 'sphinx_rtd_theme', - 'sphinx.ext.extlinks', - 'sphinxcontrib.openapi', - 'sphinx_copybutton', + "recommonmark", + "sphinx_copybutton", + "sphinx_design", + "sphinx_rtd_theme", + "sphinx.ext.extlinks", + "sphinxcontrib.openapi", ] -copybutton_prompt_text = r'\w*\$ ' # matches e.g. $ +copybutton_prompt_text = r"\w*\$ " # matches e.g. $ copybutton_prompt_is_regexp = True copybutton_only_copy_prompt_lines = True # Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] +templates_path = ["_templates"] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = [ - 'venv', 'requirements.in', 'requirements.txt', - '_build', 'Thumbs.db', '.DS_Store', - 'manuals/*/*', # manuals/.rst uses "include" directive to compose files from subdirectories - 'dev/design/TEMPLATE.rst', + "venv", + "requirements.in", + "requirements.txt", + "_build", + "Thumbs.db", + ".DS_Store", + "manuals/*/*", # manuals/.rst uses "include" directive to compose files from subdirectories + "dev/design/TEMPLATE.rst", ] -master_doc = 'index' +master_doc = "index" nitpicky = True @@ -55,17 +60,19 @@ # Note: somewhat obviously, these links will only work if the current rev has been pushed. try: file_ref_commit = subprocess.run( - ['git', 'rev-parse', "HEAD"], - capture_output=True, text=True, check=True + ["git", "rev-parse", "HEAD"], capture_output=True, text=True, check=True ).stdout.strip() except subprocess.CalledProcessError: file_ref_commit = "master" # only used on unexpected problem with executing git extlinks = { # :issue:`123` is an issue link displayed as "#123" - 'issue': ('https://github.com/scionproto/scion/issues/%s', '#%s'), + "issue": ("https://github.com/scionproto/scion/issues/%s", "#%s"), # :file-ref:`foo/bar.go` is a link to a file in the repo, displayed as "foo/bar.go" - 'file-ref': ('https://github.com/scionproto/scion/blob/'+file_ref_commit+'/%s', '%s'), + "file-ref": ( + "https://github.com/scionproto/scion/blob/" + file_ref_commit + "/%s", + "%s", + ), } # -- Options for HTML output ------------------------------------------------- @@ -73,7 +80,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'sphinx_rtd_theme' +html_theme = "sphinx_rtd_theme" html_theme_options = dict( style_external_links=True, @@ -85,8 +92,8 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = [''] +html_static_path = [""] html_css_files = [ - 'css/custom.css', + "css/custom.css", ] diff --git a/doc/cryptography/ca-operations.rst b/doc/cryptography/ca-operations.rst index 379b6a373f..71d2c91d77 100644 --- a/doc/cryptography/ca-operations.rst +++ b/doc/cryptography/ca-operations.rst @@ -15,9 +15,16 @@ Certificates. The process of creating new CA Certificates is described in section `CA Certificates`_. The process of creating new AS Certificates is described in section `AS Certificates`_. -To follow the steps in this document, ``openssl`` version ``1.1.1d`` or later is +To follow the steps in this document, ``openssl`` version ``3.0.14`` or later is required. +.. note:: + + The following document is meant as an example for easily running a manual CA + for testing purposes. In productive environments, these processes should be + automated and proper CA software should be used. + + .. _ca-cert: CA Certificates @@ -32,42 +39,49 @@ itself. Creating the initial CA Certificate ----------------------------------- -The steps in creating a new CA Certificate are: +.. tab-set:: + :sync-group: tool -#. Define the configuration of the CA Certificate in accordance with - :ref:`the SCION requirements `. -#. Create a new key pair. -#. Create a Certificate Signing Request using the key pair. -#. Use the Root Key and the Certificate Signing Request to create the new CA Certificate. + .. tab-item:: scion-pki + :sync: scion-pki -The configuration is defined in a file. OpenSSL reads the file and creates a -certificate that is compatible with SCION. An example configuration file is -included below. Note that the file includes the text ``{{.ShortOrg}}``; this -text **must** be replaced with the shortname of your organization. For example, -if your organization name is **ExampleCorp**, the line should contain ``name = -ExampleCorp Secure CA Certificate``. + The steps in creating a new CA Certificate are: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE ca_conf START - :end-before: LITERALINCLUDE ca_conf END + #. Define the subject of the CA Certificate. + #. Create the certificate using the Root Key. -.. attention:: + The subject template has already been created in preparation for the TRC + ceremony. Here is a reminder how it looks like: - SCION CA certificates have short lifetimes (a lifetime of 11 days is recommended). + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE basic_conf_scion_pki START + :end-before: LITERALINCLUDE basic_conf_scion_pki END -Once the file is ready, the rest of the steps can be executed through a series -of ``openssl`` commands. + .. tab-item:: openssl + :sync: openssl -These commands contain must be configured using the following values: + The steps in creating a new CA Certificate are: -- CA Certificate validity start date. Prior to this date, the certificate is - not considered valid. To configure this, replace occurrences of ``$STARTDATE`` - with the date in ``YYYYMMDDHHMMSSZ`` notation. For example, June 24th, 2020 UTC - at noon is formatted as ``20200624120000Z``. -- CA Certificate validity end date. After this date, the certificate is no - longer valid. To configure this, replace occurrences of ``$ENDDATE`` with - the desired date. This uses the same notation as the ``$STARTDATE``. -- Folder where the keys are contained. To configure this, replace ``$KEYDIR`` with the folder name. + #. Define the configuration of the CA Certificate in accordance with + :ref:`the SCION requirements `. + #. Create a new key pair. + #. Create a Certificate Signing Request using the key pair. + #. Use the Root Key and the Certificate Signing Request to create the new CA Certificate. + + The configuration is defined in a file. OpenSSL reads the file and creates a + certificate that is compatible with SCION. An example configuration file is + included below. Note that the file includes the text ``{{.ShortOrg}}``; this + text **must** be replaced with the shortname of your organization. For example, + if your organization name is **ExampleCorp**, the line should contain ``name = + ExampleCorp Secure CA Certificate``. + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE ca_conf START + :end-before: LITERALINCLUDE ca_conf END + +.. attention:: + + SCION CA certificates have short lifetimes (a lifetime of 11 days is recommended). .. note:: @@ -75,19 +89,51 @@ These commands contain must be configured using the following values: ``$KEYDIR`` folder, and have the names ``cp-ca.key`` and ``cp-root.key``. If this is not the case, the commands should be adjusted with the proper key locations. -Finally, to create the CA certificate, run the commands below. +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE gen_ca START - :end-before: LITERALINCLUDE gen_ca END - :dedent: 4 + .. tab-item:: scion-pki + :sync: scion-pki -After generating the certificate, check that the output is reasonable: + Once the file is ready, create the certificate using the ``scion-pki`` + binary with the desired common name. -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_ca START - :end-before: LITERALINCLUDE check_ca END - :dedent: 4 + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_ca_scion_pki START + :end-before: LITERALINCLUDE gen_ca_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + Once the file is ready, the rest of the steps can be executed through a series + of ``openssl`` commands. + + These commands contain must be configured using the following values: + + - CA Certificate validity start date. Prior to this date, the certificate is + not considered valid. To configure this, replace occurrences of ``$STARTDATE`` + with the date in ``YYYYMMDDHHMMSSZ`` notation. For example, June 24th, 2020 UTC + at noon is formatted as ``20200624120000Z``. + - CA Certificate validity end date. After this date, the certificate is no + longer valid. To configure this, replace occurrences of ``$ENDDATE`` with + the desired date. This uses the same notation as the ``$STARTDATE``. + - Folder where the keys are contained. To configure this, replace ``$KEYDIR`` with the folder name. + + + Finally, to create the CA certificate, run the commands below. + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_ca START + :end-before: LITERALINCLUDE gen_ca END + :dedent: 4 + + After generating the certificate, check that the output is reasonable: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_ca START + :end-before: LITERALINCLUDE check_ca END + :dedent: 4 The certificate can be validated with with the ``scion-pki`` binary: @@ -151,69 +197,107 @@ The steps in creating a new AS Certificate are: #. The CA uses its CA Key and the Certificate Signing Request to create the new AS Certificate. #. (If the AS and CA are different entities) The CA sends the AS Certificate back to the AS. -The configuration is defined in a file. OpenSSL reads the file and creates a -certificate that is compatible with SCION. An example configuration file is -included below. Note that the file includes the text ``{{.ShortOrg}}``; this -text **must** be replaced with the shortname of your organization. For example, -if your organization name is **ExampleCorp**, the line should contain ``name = -ExampleCorp Secure CA Certificate``. +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE as_conf START - :end-before: LITERALINCLUDE as_conf END + .. tab-item:: scion-pki + :sync: scion-pki -.. attention:: + The subject template needs to be adapted to the entity that is creating the certificate + signing request. For simplicity, we reuse the same template for both the CA and the AS. + Adapt your template according to your needs. - SCION AS certificates have short lifetimes (a lifetime of 3 days is recommended). + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_as_scion_pki_as_steps START + :end-before: LITERALINCLUDE gen_as_scion_pki_as_steps END -To create the key pair and certificate signing request (CSR), the AS then runs -the OpenSSL commands below. In these commands, replace ``$KEYDIR`` with the -folder where private keys should be stored: + .. tab-item:: openssl + :sync: openssl -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE gen_as_as_steps START - :end-before: LITERALINCLUDE gen_as_as_steps END - :dedent: 4 + The configuration is defined in a file. OpenSSL reads the file and creates a + certificate that is compatible with SCION. An example configuration file is + included below. Note that the file includes the text ``{{.ShortOrg}}``; this + text **must** be replaced with the shortname of your organization. For example, + if your organization name is **ExampleCorp**, the line should contain ``name = + ExampleCorp Secure CA Certificate``. + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE as_conf START + :end-before: LITERALINCLUDE as_conf END + + .. attention:: + + SCION AS certificates have short lifetimes (a lifetime of 3 days is recommended). + + To create the key pair and certificate signing request (CSR), the AS then runs + the OpenSSL commands below. In these commands, replace ``$KEYDIR`` with the + folder where private keys should be stored: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_as_as_steps START + :end-before: LITERALINCLUDE gen_as_as_steps END + :dedent: 4 If the AS and CA are different entities, the certificate signing request can then be sent to a CA for signing. This step is performed by an entity that is a CA in the ISD. The CA creates the certificate using its private key and the certificate signing request -received from the AS. The CA must also define the following: - -- CA Certificate validity start date. Prior to this date, the certificate is - not considered valid. To configure this, in the command below replace - occurrences of ``$STARTDATE`` with the date in ``YYYYMMDDHHMMSSZ`` notation. - For example, June 24th, 2020 UTC at noon is formatted as ``20200624120000Z``. -- CA Certificate validity end date. After this date, the certificate is no - longer valid. To configure this, in the command below replace occurrences of - ``$ENDDATE`` with the desired date. This uses the same notation as the - ``$STARTDATE``. - -Additionally, the CA should set ``$KEYDIR`` to the folder in which the private +received from the AS. The CA should set ``$KEYDIR`` to the folder in which the private key file (the file is called ``cp-ca.key``, in this example) is stored. -To create the certificate, the CA runs: +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE gen_as_ca_steps START - :end-before: LITERALINCLUDE gen_as_ca_steps END - :dedent: 4 + .. tab-item:: scion-pki + :sync: scion-pki -After generating the certificate, check that the output is reasonable: + The CA must also define the following: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_as START - :end-before: LITERALINCLUDE check_as END - :dedent: 4 + - AS Certificate validity start date and end date in RFC3339 format. -The certificate can be validated with with the ``scion-pki`` binary: + To create the certificate, the CA runs: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_as_type START - :end-before: LITERALINCLUDE check_as_type END - :dedent: 4 + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_as_scion_pki_ca_steps START + :end-before: LITERALINCLUDE gen_as_scion_pki_ca_steps END + :dedent: 4 + + + .. tab-item:: openssl + :sync: openssl + + The CA must also define the following: + + - AS Certificate validity start date. Prior to this date, the certificate is + not considered valid. To configure this, in the command below replace + occurrences of ``$STARTDATE`` with the date in ``YYYYMMDDHHMMSSZ`` notation. + For example, June 24th, 2020 UTC at noon is formatted as ``20200624120000Z``. + - AS Certificate validity end date. After this date, the certificate is no + longer valid. To configure this, in the command below replace occurrences of + ``$ENDDATE`` with the desired date. This uses the same notation as the + ``$STARTDATE``. + + To create the certificate, the CA runs: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_as_ca_steps START + :end-before: LITERALINCLUDE gen_as_ca_steps END + :dedent: 4 + + After generating the certificate, check that the output is reasonable: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_as START + :end-before: LITERALINCLUDE check_as END + :dedent: 4 + + The certificate can be validated with with the ``scion-pki`` binary: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_as_type START + :end-before: LITERALINCLUDE check_as_type END + :dedent: 4 If the AS and CA are different entities, the CA should then send the certificate back to the AS that request it. diff --git a/doc/cryptography/trc-signing-ceremony-phases-base.rst b/doc/cryptography/trc-signing-ceremony-phases-base.rst index 5537899ef8..2fab6a5ead 100644 --- a/doc/cryptography/trc-signing-ceremony-phases-base.rst +++ b/doc/cryptography/trc-signing-ceremony-phases-base.rst @@ -65,21 +65,51 @@ contained on the drive. For each certificate, the *ceremony administrator* displays the validity period and checks that they cover the previously agreed upon TRC validity. -.. literalinclude:: trc_ceremony.sh - :start-after: LITERALINCLUDE display_validity START - :end-before: LITERALINCLUDE display_validity END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE display_validity_scion-pki START + :end-before: LITERALINCLUDE display_validity_scion-pki END + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE display_validity START + :end-before: LITERALINCLUDE display_validity END Further, checks that the signature algorithms are correct: -.. literalinclude:: trc_ceremony.sh - :start-after: LITERALINCLUDE display_signature_algo START - :end-before: LITERALINCLUDE display_signature_algo END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE display_signature_algo_scion-pki START + :end-before: LITERALINCLUDE display_signature_algo_scion-pki END + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE display_signature_algo START + :end-before: LITERALINCLUDE display_signature_algo END And finally, checks that the certificates are of valid type: -.. literalinclude:: trc_ceremony.sh - :start-after: LITERALINCLUDE validate_certificate_type START - :end-before: LITERALINCLUDE validate_certificate_type END +.. tab-set:: + + .. tab-item:: scion-pki + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE validate_certificate_type START + :end-before: LITERALINCLUDE validate_certificate_type END If the results of these checks are as expected, the *ceremony administrator* computes the SHA256 sum for each certificate: @@ -123,10 +153,9 @@ update. The value will be used to fill in the ``{{.VotingQuorum}}`` variable below. Last, ask the *voting representatives* for the validity period of the new TRC. -The value will be used to fill in the ``{{.NotBefore}}`` and ``{{.Validity}}`` -variable below. The ``{{.NotBefore}}`` variable is represented as a UNIX -timestamp (seconds since Epoch January 1st, 1970 UTC, e.g. ``1593000000`` -equals June 24th, 2020 UTC at noon). +The value will be used to fill in the ``{{.NotBefore}}`` and ``{{.NotAfter}}`` +variable below. The ``{{.NotBefore}}`` and ``{{.NotAfter}}`` variable are +represented as a `RFC3339 `__ timestamp. To highlight variable types, we include some examples. The format must include the part after the ``=`` sign exactly as it is written (i.e., with the exact @@ -138,6 +167,9 @@ same quoting, parentheses, etc.). .. note:: + Previous versions of ``scion-pki`` used UNIX timestamps for ``NotBefore`` and + and a time duration string for ``Validity``. + The UNIX timestamp can be displayed in human readable form using the ``date`` command:: @@ -160,9 +192,15 @@ correct. Once the data has been verified, compute the DER encoding of the TRC data: -.. literalinclude:: trc_ceremony.sh - :start-after: LITERALINCLUDE create_payload START - :end-before: LITERALINCLUDE create_payload END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE create_payload START + :end-before: LITERALINCLUDE create_payload END Compute the SHA256 sum of the TRC payload file using: @@ -192,10 +230,24 @@ have cast their votes and copied the signatures onto the *USB flash drive*. As part of this phase, the *voting representatives* inspect the TRC payload. Display the TRC payload using: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE display_payload START - :end-before: LITERALINCLUDE display_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload_scion_pki START + :end-before: LITERALINCLUDE display_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload START + :end-before: LITERALINCLUDE display_payload END + :dedent: 4 Walk the *voting representatives* through the output and describe the meaning and implications of each part. @@ -221,20 +273,35 @@ should be available at the following locations on the *USB flash drive*: To assemble the final TRC in a file, run the following command: -.. literalinclude:: trc_ceremony.sh - :start-after: LITERALINCLUDE combine_payload START - :end-before: LITERALINCLUDE combine_payload END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE combine_payload START + :end-before: LITERALINCLUDE combine_payload END To check that the resulting TRC is correct, run: -.. literalinclude:: trc_ceremony.sh - :start-after: LITERALINCLUDE verify_payload START - :end-before: LITERALINCLUDE verify_payload END +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE verify_trc START - :end-before: LITERALINCLUDE verify_trc END - :dedent: 4 + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE verify_payload START + :end-before: LITERALINCLUDE verify_payload END + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE verify_trc START + :end-before: LITERALINCLUDE verify_trc END + :dedent: 4 Copy the signed TRC to the *USB flash drive* in the root directory. Disconnect the *USB flash drive*. @@ -255,10 +322,24 @@ confirm that verification has finished successfully. If any verification fails, Furthermore, the *voting representatives* inspect that all signatures are present. Display the signed TRC with this command: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE display_signatures START - :end-before: LITERALINCLUDE display_signatures END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_signatures_scion_pki START + :end-before: LITERALINCLUDE display_signatures_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_signatures START + :end-before: LITERALINCLUDE display_signatures END + :dedent: 4 Walk the *voting representatives* through the output and describe the meaning and implications of each part. @@ -298,7 +379,7 @@ put in the current working directory. .. important:: It is required that the machine used to execute the commands has openssl - version 1.1.1d or higher installed. + version 3.0.14 or higher installed. Phase 1 - Exchange of Certificates ---------------------------------- @@ -406,17 +487,45 @@ one using the *regular voting certificate* and one using the *sensitive voting c Before signing, check that the TRC payload is sound: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE display_payload START - :end-before: LITERALINCLUDE display_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload_scion_pki START + :end-before: LITERALINCLUDE display_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload START + :end-before: LITERALINCLUDE display_payload END + :dedent: 4 To compute the signatures, run: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE sign_payload START - :end-before: LITERALINCLUDE sign_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sign_payload_scion_pki START + :end-before: LITERALINCLUDE sign_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sign_payload START + :end-before: LITERALINCLUDE sign_payload END + :dedent: 4 .. Warning:: @@ -425,10 +534,24 @@ To compute the signatures, run: To sanity check that the signatures were created correctly, run: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_signed_payload START - :end-before: LITERALINCLUDE check_signed_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_signed_payload_scion_pki START + :end-before: LITERALINCLUDE check_signed_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_signed_payload START + :end-before: LITERALINCLUDE check_signed_payload END + :dedent: 4 Connect the *USB flash drive* to the *device*, and copy ``$TRCID.regular.trc`` and @@ -459,25 +582,52 @@ If the sum differs, then **Phase 3** and **Phase 4** need to be repeated. Next, check that all the fields are consistent with earlier choices. To print the fields that are present in the TRC, run: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE verify_trc START - :end-before: LITERALINCLUDE verify_trc END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony.sh + :start-after: LITERALINCLUDE verify_payload START + :end-before: LITERALINCLUDE verify_payload END + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE verify_trc START + :end-before: LITERALINCLUDE verify_trc END + :dedent: 4 + + .. note:: + + The ``-no_check_time`` flag is needed when the validity time of the TRC is in + the future. If there is a mismatch between any of the fields and the desired policy, then **Phase 3** and **Phase 4** need to be repeated. -.. note:: +As a final check, run: - The ``-no_check_time`` flag is needed when the validity time of the TRC is in - the future. +.. tab-set:: + :sync-group: tool -As a final check, run: + .. tab-item:: scion-pki + :sync: scion-pki -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE display_signatures START - :end-before: LITERALINCLUDE display_signatures END - :dedent: 4 + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_signatures_scion_pki START + :end-before: LITERALINCLUDE display_signatures_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_signatures START + :end-before: LITERALINCLUDE display_signatures END + :dedent: 4 and check that the signature information of each signature is present; there should be 2 signatures for each *voting representative*. If a signature is missing, then diff --git a/doc/cryptography/trc-signing-ceremony-phases-sensitive.rst b/doc/cryptography/trc-signing-ceremony-phases-sensitive.rst index e6232a24e2..331d17e401 100644 --- a/doc/cryptography/trc-signing-ceremony-phases-sensitive.rst +++ b/doc/cryptography/trc-signing-ceremony-phases-sensitive.rst @@ -76,21 +76,51 @@ contained on the drive. For each certificate, the *ceremony administrator* displays the validity period and checks that they cover the previously agreed upon TRC validity. -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE display_validity START - :end-before: LITERALINCLUDE display_validity END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE display_validity_scion-pki START + :end-before: LITERALINCLUDE display_validity_scion-pki END + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE display_validity START + :end-before: LITERALINCLUDE display_validity END Further, checks that the signature algorithms are correct: -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE display_signature_algo START - :end-before: LITERALINCLUDE display_signature_algo END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE display_signature_algo_scion-pki START + :end-before: LITERALINCLUDE display_signature_algo_scion-pki END + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE display_signature_algo START + :end-before: LITERALINCLUDE display_signature_algo END And finally, checks that the certificates are of valid type: -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE validate_certificate_type START - :end-before: LITERALINCLUDE validate_certificate_type END +.. tab-set:: + + .. tab-item:: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE validate_certificate_type START + :end-before: LITERALINCLUDE validate_certificate_type END If the results of these checks are as expected, the *ceremony administrator* computes the SHA256 sum for each certificate: @@ -148,11 +178,11 @@ certificates in the predecessor TRC. To find the indices, you can use the ``scio trcs human`` command. Last, ask the *voting representatives* for the validity period of the new TRC. -The value will be used to fill in the ``{{.NotBefore}}`` and ``{{.Validity}}`` -variable below. The ``{{.NotBefore}}`` variable is represented as a UNIX -timestamp (seconds since Epoch January 1st, 1970 UTC, e.g. ``1621857600`` -equals May 24th, 2021 UTC at noon). Ensure that the selected validity -period overlaps with the one of the predecessor TRC. +The value will be used to fill in the ``{{.NotBefore}}`` and ``{{.NotAfter}}`` +variable below. The ``{{.NotBefore}}`` and ``{{.NotAfter}}`` variable are +represented as a `RFC3339 `__ timestamp. +Ensure that the selected validity period overlaps with the one of the +predecessor TRC. To highlight variable types, we include some examples. The format must include the part after the ``=`` sign exactly as it is written (i.e., with the exact @@ -164,6 +194,9 @@ same quoting, parentheses, etc.). .. note:: + Previous versions of ``scion-pki`` used UNIX timestamps for ``NotBefore`` and + and a time duration string for ``Validity``. + The UNIX timestamp can be displayed in human readable form using the ``date`` command:: @@ -186,9 +219,15 @@ correct. Once the data has been verified, compute the DER encoding of the TRC data: -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE create_payload START - :end-before: LITERALINCLUDE create_payload END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE create_payload START + :end-before: LITERALINCLUDE create_payload END Compute the SHA256 sum of the TRC payload file using: @@ -223,10 +262,24 @@ signatures onto the *USB flash drive*. As part of this phase, the *voting representatives* inspect the TRC payload. Display the TRC payload using: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE display_payload START - :end-before: LITERALINCLUDE display_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload_scion_pki START + :end-before: LITERALINCLUDE display_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload START + :end-before: LITERALINCLUDE display_payload END + :dedent: 4 Walk the *voting representatives* through the output and describe the meaning and implications of each part. @@ -259,15 +312,35 @@ at the following locations on the *USB flash drive*: To assemble the final TRC in a file, run the following command: -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE combine_payload START - :end-before: LITERALINCLUDE combine_payload END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE combine_payload START + :end-before: LITERALINCLUDE combine_payload END To check that the resulting TRC is correct, run: -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE verify_payload START - :end-before: LITERALINCLUDE verify_payload END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE verify_payload START + :end-before: LITERALINCLUDE verify_payload END + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE verify_trc START + :end-before: LITERALINCLUDE verify_trc END + :dedent: 4 Copy the signed TRC to the *USB flash drive* in the root directory. Disconnect the *USB flash drive*. @@ -288,9 +361,15 @@ confirm that verification has finished successfully. If any verification fails, Furthermore, the *voting representatives* inspect that all signatures are present. Display the signed TRC with this command: -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE trc_content START - :end-before: LITERALINCLUDE trc_content END +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE trc_content START + :end-before: LITERALINCLUDE trc_content END Walk the *voting representatives* through the output and describe the meaning and implications of each part. @@ -339,7 +418,7 @@ put in the current working directory. .. important:: It is required that the machine used to execute the commands has openssl - version 1.1.1d or higher installed. + version 3.0.14 or higher installed. Phase 1 - Exchange of Certificates ---------------------------------- @@ -449,24 +528,66 @@ one using the *regular voting certificate* and one using the *sensitive voting c Before signing, check that the TRC payload is sound: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE display_payload START - :end-before: LITERALINCLUDE display_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload_scion_pki START + :end-before: LITERALINCLUDE display_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE display_payload START + :end-before: LITERALINCLUDE display_payload END + :dedent: 4 To compute the proof-of-possession signatures, run: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE sign_payload START - :end-before: LITERALINCLUDE sign_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sign_payload_scion_pki START + :end-before: LITERALINCLUDE sign_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sign_payload START + :end-before: LITERALINCLUDE sign_payload END + :dedent: 4 To compute the vote, run: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE sensitive_vote START - :end-before: LITERALINCLUDE sensitive_vote END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sensitive_vote_scion_pki START + :end-before: LITERALINCLUDE sensitive_vote_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sensitive_vote START + :end-before: LITERALINCLUDE sensitive_vote END + :dedent: 4 .. Warning:: @@ -475,17 +596,45 @@ To compute the vote, run: To sanity check that the proof-of-possession signatures were created correctly, run: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_signed_payload START - :end-before: LITERALINCLUDE check_signed_payload END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_signed_payload_scion_pki START + :end-before: LITERALINCLUDE check_signed_payload_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_signed_payload START + :end-before: LITERALINCLUDE check_signed_payload END + :dedent: 4 To sanity check that the vote was cast correctly, run: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_sensitive_vote START - :end-before: LITERALINCLUDE check_sensitive_vote END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_sensitive_vote_scion_pki START + :end-before: LITERALINCLUDE check_sensitive_vote_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_sensitive_vote START + :end-before: LITERALINCLUDE check_sensitive_vote END + :dedent: 4 Connect the *USB flash drive* to the *device*, and copy ``$TRCID.regular.trc``, ``$TRCID.sensitive.trc``, and ``$TRCID.sensitive.vote.trc`` to the folder named @@ -516,10 +665,16 @@ If the sum differs, then **Phase 3** and **Phase 4** need to be repeated. Next, check that all the fields are consistent with earlier choices. To print the fields that are present in the TRC, run: -.. literalinclude:: trc_ceremony_sensitive.sh - :start-after: LITERALINCLUDE trc_content_rep START - :end-before: LITERALINCLUDE trc_content_rep END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: trc_ceremony_sensitive.sh + :start-after: LITERALINCLUDE trc_content_rep START + :end-before: LITERALINCLUDE trc_content_rep END + :dedent: 4 If there is a mismatch between any of the fields and the desired policy, then **Phase 3** and **Phase 4** need to be repeated. @@ -538,7 +693,7 @@ Inform the *ceremony administrator* of the outcome of the verification. format instead of the raw ASN.1 DER encoding. You can do so by running the following command: - .. literalinclude:: trc_ceremony.sh + .. literalinclude:: trc_ceremony_sensitive.sh :start-after: LITERALINCLUDE format_trc START :end-before: LITERALINCLUDE format_trc END :dedent: 4 diff --git a/doc/cryptography/trc-signing-ceremony-preparations.rst b/doc/cryptography/trc-signing-ceremony-preparations.rst index cf49ec49a5..8f2be2ab79 100644 --- a/doc/cryptography/trc-signing-ceremony-preparations.rst +++ b/doc/cryptography/trc-signing-ceremony-preparations.rst @@ -10,7 +10,7 @@ preparation for the ceremony. This document outlines these steps. .. important:: It is required that the machine used to execute the commands has openssl - version 1.1.1d or higher installed. + version 3.0.14 or higher installed. .. note:: @@ -83,29 +83,58 @@ Navigate to the public directory: :end-before: LITERALINCLUDE navigate_pubdir END :dedent: 4 -This directory stores the openssl configurations, the CSRs and the created -certificates. To avoid duplicated information, create a ``basic.cnf`` that can -be imported from the sensitive voting, regular voting and root certificate -configuration files: +This directory stores the necessary configurations and created certificates. +Private keys are kept in a separate directory to avoid accidental disclosure. -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE basic_conf START - :end-before: LITERALINCLUDE basic_conf END +.. tab-set:: + :sync-group: tool -Fill in the required fields. + .. tab-item:: scion-pki + :sync: scion-pki -.. note:: + To avoid duplicated information, create a ``subject.tmpl`` that can + be reused for the sensitive voting, regular voting and root certificate: - The ``{{.Country}}`` must be replaced with an ISO 3166-1 alpha-2 code. - Switzerland, for example, has the code ``CH``. + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE basic_conf_scion_pki START + :end-before: LITERALINCLUDE basic_conf_scion_pki END -To set the start and end time of a X509 certificate using openssl, the ``ca`` -command is necessary. The directory needs to be prepared: + Fill in the required fields. -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE prepare_ca START - :end-before: LITERALINCLUDE prepare_ca END - :dedent: 4 + .. note:: + + The ``{{.Country}}`` must be replaced with an ISO 3166-1 alpha-2 code. + Switzerland, for example, has the code ``CH``. + + The ``{{.ShortOrg}}`` must be replaced with a short name for the + organization that will be used in the certificate common name. + + .. tab-item:: openssl + :sync: openssl + + + To avoid duplicated information, create a ``basic.cnf`` that can + be imported from the sensitive voting, regular voting and root certificate + configuration files: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE basic_conf START + :end-before: LITERALINCLUDE basic_conf END + + Fill in the required fields. + + .. note:: + + The ``{{.Country}}`` must be replaced with an ISO 3166-1 alpha-2 code. + Switzerland, for example, has the code ``CH``. + + To set the start and end time of a X509 certificate using openssl, the ``ca`` + command is necessary. The directory needs to be prepared: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE prepare_ca START + :end-before: LITERALINCLUDE prepare_ca END + :dedent: 4 Sensitive voting @@ -119,12 +148,27 @@ This step creates a sensitive voting key and certificate. party has an AS identifier, the ISD number must match with the TRC this certificate will be used in. -First, create the sensitive voting certificate configuration. In the file, -replace ``{{.ShortOrg}}`` with the name of your organization: +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE sensitive_conf START - :end-before: LITERALINCLUDE sensitive_conf END + .. tab-item:: scion-pki + :sync: scion-pki + + First, export the sensitive voting certificate common name. + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sensitive_cn START + :end-before: LITERALINCLUDE sensitive_cn END + + .. tab-item:: openssl + :sync: openssl + + First, create the sensitive voting certificate configuration. In the file, + replace ``{{.ShortOrg}}`` with the name of your organization: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE sensitive_conf START + :end-before: LITERALINCLUDE sensitive_conf END .. note:: @@ -145,33 +189,57 @@ replace ``{{.ShortOrg}}`` with the name of your organization: :end-before: LITERALINCLUDE version_sensitive END :dedent: 4 +.. tab-set:: + :sync-group: tool -Using this configuration, create the sensitive voting key and certificate. The -start and end date need to be replaced with the time when the certificate -becomes valid, and the time when it expires. The format is ``YYYYMMDDHHMMSSZ``. -For example, June 24th, 2020 UTC at noon, is formatted as ``20200624120000Z``. -The required commands are: + .. tab-item:: scion-pki + :sync: scion-pki -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE gen_sensitive START - :end-before: LITERALINCLUDE gen_sensitive END - :dedent: 4 + Using the subject template, create the sensitive voting key and certificate. The + start and end date need to be replaced with the time when the certificate + becomes valid, and the time when it expires. The format is RFC3339 compliant. + For example, June 24th, 2020 UTC at noon, is formatted as ``2020-06-24T12:00:00Z``. -After generating the certificate, check that the output is reasonable: + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_sensitive_scion_pki START + :end-before: LITERALINCLUDE gen_sensitive_scion_pki END + :dedent: 4 -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_sensitive START - :end-before: LITERALINCLUDE check_sensitive END - :dedent: 4 + .. tab-item:: openssl + :sync: openssl + + Using this configuration, create the sensitive voting key and certificate. The + start and end date need to be replaced with the time when the certificate + becomes valid, and the time when it expires. The format is ``YYYYMMDDHHMMSSZ``. + For example, June 24th, 2020 UTC at noon, is formatted as ``20200624120000Z``. + The required commands are: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_sensitive START + :end-before: LITERALINCLUDE gen_sensitive END + :dedent: 4 + + After generating the certificate, check that the output is reasonable: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_sensitive START + :end-before: LITERALINCLUDE check_sensitive END + :dedent: 4 The validity time must cover the agreed upon TRC validity period. The certificate can be validated with with the ``scion-pki`` binary: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_sensitive_type START - :end-before: LITERALINCLUDE check_sensitive_type END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_sensitive_type START + :end-before: LITERALINCLUDE check_sensitive_type END + :dedent: 4 Regular voting -------------- @@ -184,11 +252,26 @@ This step creates a regular voting key and certificate. party has an AS identifier, the ISD number must match with the TRC this certificate will be used in. -Create the regular voting certificate configuration: +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE regular_conf START - :end-before: LITERALINCLUDE regular_conf END + .. tab-item:: scion-pki + :sync: scion-pki + + First, export the regular voting certificate common name. + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE regular_cn START + :end-before: LITERALINCLUDE regular_cn END + + .. tab-item:: openssl + :sync: openssl + + Create the regular voting certificate configuration: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE regular_conf START + :end-before: LITERALINCLUDE regular_conf END .. note:: @@ -209,32 +292,57 @@ Create the regular voting certificate configuration: :end-before: LITERALINCLUDE version_regular END :dedent: 4 -Using this configuration, create the regular voting key and certificate. The -start and end date need to be replaced with the time when the certificate -becomes valid, and the time when it expires. The format is ``YYYYMMDDHHMMSSZ``. -For example, June 24th, 2020 UTC at noon, is formatted as ``20200624120000Z``. -The required commands are: +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE gen_regular START - :end-before: LITERALINCLUDE gen_regular END - :dedent: 4 + .. tab-item:: scion-pki + :sync: scion-pki -After generating the certificate, check that the output is reasonable: + Using the subject template, create the regular voting key and certificate. The + start and end date need to be replaced with the time when the certificate + becomes valid, and the time when it expires. The format is RFC3339 compliant. + For example, June 24th, 2020 UTC at noon, is formatted as ``2020-06-24T12:00:00Z``. -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_regular START - :end-before: LITERALINCLUDE check_regular END - :dedent: 4 + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_regular_scion_pki START + :end-before: LITERALINCLUDE gen_regular_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + Using this configuration, create the regular voting key and certificate. The + start and end date need to be replaced with the time when the certificate + becomes valid, and the time when it expires. The format is ``YYYYMMDDHHMMSSZ``. + For example, June 24th, 2020 UTC at noon, is formatted as ``20200624120000Z``. + The required commands are: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_regular START + :end-before: LITERALINCLUDE gen_regular END + :dedent: 4 + + After generating the certificate, check that the output is reasonable: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_regular START + :end-before: LITERALINCLUDE check_regular END + :dedent: 4 The validity time must cover the agreed upon TRC validity period. The certificate can be validated with with the ``scion-pki`` binary: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_regular_type START - :end-before: LITERALINCLUDE check_regular_type END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_regular_type START + :end-before: LITERALINCLUDE check_regular_type END + :dedent: 4 CP Root ------- @@ -245,11 +353,26 @@ This step creates a CP root key and certificate. This step only has to be executed by issuing ASes. -Create the CP root certificate configuration: +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE root_conf START - :end-before: LITERALINCLUDE root_conf END + .. tab-item:: scion-pki + :sync: scion-pki + + First, export the root certificate common name. + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE root_cn START + :end-before: LITERALINCLUDE root_cn END + + .. tab-item:: openssl + :sync: openssl + + Create the CP root certificate configuration: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE root_conf START + :end-before: LITERALINCLUDE root_conf END .. note:: @@ -270,29 +393,54 @@ Create the CP root certificate configuration: :end-before: LITERALINCLUDE version_regular END :dedent: 4 -Using this configuration, create the CP root key and certificate. The start and -end date need to be replaced with the time when the certificate becomes valid, -and the time when it expires. The format is ``YYYYMMDDHHMMSSZ``. For example, -June 24th, 2020 UTC at noon, is formatted as ``20200624120000Z``. The required -commands are: +.. tab-set:: + :sync-group: tool -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE gen_root START - :end-before: LITERALINCLUDE gen_root END - :dedent: 4 + .. tab-item:: scion-pki + :sync: scion-pki -After generating the certificate, check that the output is reasonable: + Using the subject template, create the root key and certificate. The + start and end date need to be replaced with the time when the certificate + becomes valid, and the time when it expires. The format is RFC3339 compliant. + For example, June 24th, 2020 UTC at noon, is formatted as ``2020-06-24T12:00:00Z``. -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_root START - :end-before: LITERALINCLUDE check_root END - :dedent: 4 + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_root_scion_pki START + :end-before: LITERALINCLUDE gen_root_scion_pki END + :dedent: 4 + + .. tab-item:: openssl + :sync: openssl + + Using this configuration, create the CP root key and certificate. The start and + end date need to be replaced with the time when the certificate becomes valid, + and the time when it expires. The format is ``YYYYMMDDHHMMSSZ``. For example, + June 24th, 2020 UTC at noon, is formatted as ``20200624120000Z``. The required + commands are: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE gen_root START + :end-before: LITERALINCLUDE gen_root END + :dedent: 4 + + After generating the certificate, check that the output is reasonable: + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_root START + :end-before: LITERALINCLUDE check_root END + :dedent: 4 The validity time must cover the agreed upon TRC validity period. The certificate can be validated with with the ``scion-pki`` binary: -.. literalinclude:: crypto_lib.sh - :start-after: LITERALINCLUDE check_root_type START - :end-before: LITERALINCLUDE check_root_type END - :dedent: 4 +.. tab-set:: + :sync-group: tool + + .. tab-item:: scion-pki + :sync: scion-pki + + .. literalinclude:: crypto_lib.sh + :start-after: LITERALINCLUDE check_root_type START + :end-before: LITERALINCLUDE check_root_type END + :dedent: 4 diff --git a/doc/requirements.in b/doc/requirements.in index 3e47a367e5..2d5b3ab025 100644 --- a/doc/requirements.in +++ b/doc/requirements.in @@ -1,7 +1,8 @@ -Sphinx recommonmark -sphinx-autobuild -sphinx-rtd-theme -sphinxcontrib-openapi +Sphinx sphinx_copybutton +sphinx_design +sphinx-autobuild sphinx-lint +sphinx-rtd-theme +sphinxcontrib-openapi \ No newline at end of file diff --git a/doc/requirements.txt b/doc/requirements.txt index 092c61e704..b0635d6957 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -314,7 +314,7 @@ pyyaml==6.0.1 \ recommonmark==0.7.1 \ --hash=sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f \ --hash=sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67 - # via -r requirements.in + # via -r doc/requirements.in referencing==0.34.0 \ --hash=sha256:5773bd84ef41799a5a8ca72dc34590c041eb01bf9aa02632b4a973fb0181a844 \ --hash=sha256:d53ae300ceddd3169f1ffa9caf2cb7b769e92657e4fafb23d34b93679116dfd4 @@ -539,10 +539,11 @@ sphinx==7.3.7 \ --hash=sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3 \ --hash=sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc # via - # -r requirements.in + # -r doc/requirements.in # recommonmark # sphinx-autobuild # sphinx-copybutton + # sphinx-design # sphinx-rtd-theme # sphinxcontrib-httpdomain # sphinxcontrib-jquery @@ -550,15 +551,19 @@ sphinx==7.3.7 \ sphinx-autobuild==2024.4.16 \ --hash=sha256:1c0ed37a1970eed197f9c5a66d65759e7c4e4cba7b5a5d77940752bf1a59f2c7 \ --hash=sha256:f2522779d30fcbf0253e09714f274ce8c608cb6ebcd67922b1c54de59faba702 - # via -r requirements.in + # via -r doc/requirements.in sphinx-copybutton==0.5.2 \ --hash=sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd \ --hash=sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e - # via -r requirements.in + # via -r doc/requirements.in +sphinx-design==0.6.0 \ + --hash=sha256:e9bd07eecec82eb07ff72cb50fc3624e186b04f5661270bc7b62db86c7546e95 \ + --hash=sha256:ec8e3c5c59fed4049b3a5a2e209360feab31829346b5f6a0c7c342b894082192 + # via -r doc/requirements.in sphinx-lint==0.9.1 \ --hash=sha256:185cee19ff1129549c45e15a3b25404daeb47c54d15112dda589cedad82957aa \ --hash=sha256:df34271ab65ce43676cbd90726f4dea5cd200b43b01448b2aee8f06e609edcbb - # via -r requirements.in + # via -r doc/requirements.in sphinx-mdinclude==0.6.0 \ --hash=sha256:764b6aeee28002b9d02060758266761a2c724805594d264b19e6ceeaa3bad393 \ --hash=sha256:b1cb4dfa22ce17ca20e90e34d4349d8a97c5052709d9c4eed051cdabb615b20b @@ -566,7 +571,7 @@ sphinx-mdinclude==0.6.0 \ sphinx-rtd-theme==2.0.0 \ --hash=sha256:bd5d7b80622406762073a04ef8fadc5f9151261563d47027de09910ce03afe6b \ --hash=sha256:ec93d0856dc280cf3aee9a4c9807c60e027c7f7b461b77aeffed682e68f0e586 - # via -r requirements.in + # via -r doc/requirements.in sphinxcontrib-applehelp==1.0.8 \ --hash=sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619 \ --hash=sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4 @@ -594,7 +599,7 @@ sphinxcontrib-jsmath==1.0.1 \ sphinxcontrib-openapi==0.8.4 \ --hash=sha256:50911c18d452d9390ee3a384ef8dc8bde6135f542ba55691f81e1fbc0b71014e \ --hash=sha256:df883808a5b5e4b4113ad697185c43a3f42df3dce70453af78ba7076907e9a20 - # via -r requirements.in + # via -r doc/requirements.in sphinxcontrib-qthelp==1.0.7 \ --hash=sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6 \ --hash=sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182 diff --git a/pkg/scrypto/cppki/trc.go b/pkg/scrypto/cppki/trc.go index a2398bdeb0..fc300d8c39 100644 --- a/pkg/scrypto/cppki/trc.go +++ b/pkg/scrypto/cppki/trc.go @@ -153,7 +153,11 @@ func (trc *TRC) Validate() error { } if !(Validity{NotBefore: cert.NotBefore, NotAfter: cert.NotAfter}).Covers(trc.Validity) { return serrors.JoinNoStack(ErrTRCValidityNotCovered, nil, - "subject", cert.Subject, "index", i) + "cert.subject", cert.Subject, + "cert.index", i, + "cert.validity", Validity{NotBefore: cert.NotBefore, NotAfter: cert.NotAfter}, + "trc.validity", trc.Validity, + ) } } // Check that issuer-SN pair is unique. diff --git a/scion-pki/cmd/scion-pki/version.go b/scion-pki/cmd/scion-pki/version.go index 32cde37061..06b8a80152 100644 --- a/scion-pki/cmd/scion-pki/version.go +++ b/scion-pki/cmd/scion-pki/version.go @@ -23,7 +23,7 @@ import ( ) func newVersion() *cobra.Command { - major, minor, patch := 0, 5, 0 + major, minor, patch := 0, 6, 0 cmd := &cobra.Command{ Use: "version", Short: "Show the scion-pki version information", diff --git a/scion-pki/conf/testdata/testcfg.rfc3339.toml b/scion-pki/conf/testdata/testcfg.rfc3339.toml new file mode 100644 index 0000000000..98dfdaea58 --- /dev/null +++ b/scion-pki/conf/testdata/testcfg.rfc3339.toml @@ -0,0 +1,13 @@ +isd = 1 +description = "test config" +serial_version = 1 +base_version = 1 +voting_quorum = 1 +no_trust_reset = false +core_ases = ["ff00:0:110"] +authoritative_ases = ["ff00:0:120"] +cert_files = ["regular-voting.crt", "sensitive-voting.crt"] + +[validity] + not_before = "2024-06-24T12:13:14+02:00" + validity = "1h" diff --git a/scion-pki/conf/testdata/testcfg.unix.toml b/scion-pki/conf/testdata/testcfg.unix.toml new file mode 100644 index 0000000000..a13860f8f1 --- /dev/null +++ b/scion-pki/conf/testdata/testcfg.unix.toml @@ -0,0 +1,13 @@ +isd = 1 +description = "test config" +serial_version = 1 +base_version = 1 +voting_quorum = 1 +no_trust_reset = false +core_ases = ["ff00:0:110"] +authoritative_ases = ["ff00:0:120"] +cert_files = ["regular-voting.crt", "sensitive-voting.crt"] + +[validity] + not_before = 1719223994 + validity = "1h" diff --git a/scion-pki/conf/trc.go b/scion-pki/conf/trc.go index 6c62bcf01b..dd059f2550 100644 --- a/scion-pki/conf/trc.go +++ b/scion-pki/conf/trc.go @@ -51,6 +51,9 @@ func LoadTRC(file string) (TRC, error) { if err := config.LoadFile(file, &cfg); err != nil { return TRC{}, serrors.Wrap("unable to load TRC config from file", err, "file", file) } + if err := cfg.Validity.Validate(); err != nil { + return TRC{}, serrors.Wrap("validating 'validity' section", err) + } cfg.relPath = filepath.Dir(file) return cfg, nil } diff --git a/scion-pki/conf/trc_test.go b/scion-pki/conf/trc_test.go index b97dcdd566..6af098ee08 100644 --- a/scion-pki/conf/trc_test.go +++ b/scion-pki/conf/trc_test.go @@ -63,6 +63,7 @@ func TestLoadTRC(t *testing.T) { file string cfg conf.TRC assertErr assert.ErrorAssertionFunc + check func(*conf.TRC) }{ "file not found": { file: "notfound.404", @@ -71,14 +72,33 @@ func TestLoadTRC(t *testing.T) { "valid": { file: "testdata/testcfg.toml", assertErr: assert.NoError, - cfg: *createTRC(t), + check: func(cfg *conf.TRC) { + assert.Equal(t, createTRC(t), cfg) + assert.True(t, cfg.Validity.NotBefore.Time().IsZero()) + }, + }, + "unix": { + file: "testdata/testcfg.unix.toml", + assertErr: assert.NoError, + check: func(cfg *conf.TRC) { + assert.Equal(t, int64(1719223994), cfg.Validity.NotBefore.Time().Unix()) + }, + }, + "rfc3339": { + file: "testdata/testcfg.rfc3339.toml", + assertErr: assert.NoError, + check: func(cfg *conf.TRC) { + assert.Equal(t, int64(1719223994), cfg.Validity.NotBefore.Time().Unix()) + }, }, } for name, tc := range testCases { t.Run(name, func(t *testing.T) { cfg, err := conf.LoadTRC(tc.file) tc.assertErr(t, err) - assert.Equal(t, tc.cfg, cfg) + if tc.check != nil { + tc.check(&cfg) + } }) } } diff --git a/scion-pki/conf/validity.go b/scion-pki/conf/validity.go index 838ea40fe5..c9fc1cc1f7 100644 --- a/scion-pki/conf/validity.go +++ b/scion-pki/conf/validity.go @@ -15,6 +15,7 @@ package conf import ( + "strconv" "time" "github.com/scionproto/scion/pkg/private/serrors" @@ -22,16 +23,42 @@ import ( "github.com/scionproto/scion/pkg/scrypto/cppki" ) +type Time time.Time + +func (t Time) Time() time.Time { + return time.Time(t) +} + +func (t *Time) UnmarshalText(b []byte) error { + unix, err := strconv.ParseUint(string(b), 10, 32) + if err == nil { + if unix == 0 { + *t = Time{} + return nil + } + *t = Time(util.SecsToTime(uint32(unix))) + return nil + } + + parsed, err := time.Parse(time.RFC3339, string(b)) + if err != nil { + return serrors.Wrap("unable to parse time", err) + } + *t = Time(parsed) + return nil +} + // Validity defines a validity period. type Validity struct { - NotBefore uint32 `toml:"not_before"` + NotBefore Time `toml:"not_before"` + NotAfter Time `toml:"not_after"` Validity util.DurWrap `toml:"validity"` } // Validate checks that the validity is set. -func (v Validity) Validate() error { - if v.Validity.Duration == 0 { - return serrors.New("validity period not set") +func (v *Validity) Validate() error { + if (v.Validity.Duration == 0) == (v.NotAfter.Time().IsZero()) { + return serrors.New("exactly one of 'validity' or 'not_after' must be set") } return nil } @@ -39,11 +66,16 @@ func (v Validity) Validate() error { // Eval returns the validity period. The not before parameter is only used if // the struct's not before field value is zero. func (v Validity) Eval(notBefore time.Time) cppki.Validity { - if v.NotBefore != 0 { - notBefore = util.SecsToTime(v.NotBefore) + if nb := time.Time(v.NotBefore); !nb.IsZero() { + notBefore = nb } return cppki.Validity{ NotBefore: notBefore, - NotAfter: notBefore.Add(v.Validity.Duration), + NotAfter: func() time.Time { + if !v.NotAfter.Time().IsZero() { + return v.NotAfter.Time() + } + return notBefore.Add(v.Validity.Duration) + }(), } } diff --git a/scion-pki/testcrypto/testcrypto.go b/scion-pki/testcrypto/testcrypto.go index f852998775..0a819333fe 100644 --- a/scion-pki/testcrypto/testcrypto.go +++ b/scion-pki/testcrypto/testcrypto.go @@ -313,7 +313,7 @@ func createTRCs(cfg config) error { BaseVersion: 1, VotingQuorum: uint8(len(voters[isd])/2 + 1), Validity: conf.Validity{ - NotBefore: uint32(cfg.now.UTC().Unix()), + NotBefore: conf.Time(cfg.now.UTC()), Validity: util.DurWrap{Duration: 450 * 24 * time.Hour}, }, CoreASes: cores[isd], diff --git a/scion-pki/trcs/BUILD.bazel b/scion-pki/trcs/BUILD.bazel index e995b0dd9e..832d1f4090 100644 --- a/scion-pki/trcs/BUILD.bazel +++ b/scion-pki/trcs/BUILD.bazel @@ -7,7 +7,7 @@ go_library( "decode.go", "extract.go", "format.go", - "human.go", + "inspect.go", "payload.go", "sign.go", "toasn.go", @@ -40,7 +40,7 @@ go_test( "decoded_test.go", "export_test.go", "format_test.go", - "human_test.go", + "inspect_test.go", "sign_test.go", "toasn_test.go", "verify_test.go", @@ -69,7 +69,7 @@ go_test( "decoded_test.go", "export_test.go", "format_test.go", - "human_test.go", + "inspect_test.go", "sign_test.go", "toasn_test.go", "verify_test.go", diff --git a/scion-pki/trcs/human.go b/scion-pki/trcs/inspect.go similarity index 97% rename from scion-pki/trcs/human.go rename to scion-pki/trcs/inspect.go index 17f12384ea..a46153206c 100644 --- a/scion-pki/trcs/human.go +++ b/scion-pki/trcs/inspect.go @@ -51,10 +51,10 @@ func newHuman(pather command.Pather) *cobra.Command { cmd := &cobra.Command{ Use: "inspect", Aliases: []string{"human"}, - Short: "Represent TRC in a human readable form", - Example: fmt.Sprintf(` %[1]s human ISD1-B1-S1.pld.der - %[1]s human ISD1-B1-S1.trc`, pather.CommandPath()), - Long: `'human' outputs the TRC contents in a human readable form. + Short: "Print TRC details in a human readable format", + Example: fmt.Sprintf(` %[1]s inspect ISD1-B1-S1.pld.der + %[1]s inspect ISD1-B1-S1.trc`, pather.CommandPath()), + Long: `'inspect' prints the details of a TRC a human-readable fromat. The input file can either be a TRC payload, or a signed TRC. The output can either be in yaml, or json. diff --git a/scion-pki/trcs/human_test.go b/scion-pki/trcs/inspect_test.go similarity index 100% rename from scion-pki/trcs/human_test.go rename to scion-pki/trcs/inspect_test.go diff --git a/tools/buildrill/_check_gazelle_mode b/tools/buildrill/_check_gazelle_mode new file mode 100755 index 0000000000..84083e1645 --- /dev/null +++ b/tools/buildrill/_check_gazelle_mode @@ -0,0 +1,12 @@ +#! /bin/bash + +# In diff mode, we expect no changes (exit code 3) +if [[ "$GAZELLE_MODE" == "diff" ]]; then + test $ret -eq 3 && exit 0 + exit 1 +fi + +# In fix mode, we succeed even if there are changes. +test $ret -eq 0 && exit 0 +test $ret -eq 3 && exit 0 +exit 1 diff --git a/tools/buildrill/go_integration_test_sync b/tools/buildrill/go_integration_test_sync new file mode 100755 index 0000000000..791be4a688 --- /dev/null +++ b/tools/buildrill/go_integration_test_sync @@ -0,0 +1,15 @@ +#!/bin/bash + +GAZELLE_MODE="${GAZELLE_MODE:-fix}" + +bazel run @com_github_bazelbuild_buildtools//buildozer -- \ + --root_dir $PWD \ + "copy deps go_default_test" \ + "copy srcs go_default_test" \ + "add tags integration" \ + $(bazel query 'attr(name, "go_integration_test$", //...)' | tr '\n' ' ') + +ret=$? + +script_path=$(dirname "$0") +. "${script_path}/_check_gazelle_mode" diff --git a/tools/cryptoplayground/BUILD.bazel b/tools/cryptoplayground/BUILD.bazel index 8e23fc87a6..c2a69d910d 100644 --- a/tools/cryptoplayground/BUILD.bazel +++ b/tools/cryptoplayground/BUILD.bazel @@ -18,6 +18,23 @@ sh_test( ], ) +sh_test( + name = "trc_ceremony_scion_pki_test", + srcs = ["trc_ceremony.sh"], + data = [ + ":crypto_lib.sh", + "//scion-pki/cmd/scion-pki", + ], + env = { + "SCION_PKI_BIN": "$(location //scion-pki/cmd/scion-pki)", + "USE_SCION_PKI_SIGN": "1", + }, + tags = [ + "exclusive", + "integration", + ], +) + sh_test( name = "trc_ceremony_sensitive_test", srcs = ["trc_ceremony_sensitive.sh"], @@ -34,3 +51,21 @@ sh_test( "integration", ], ) + +sh_test( + name = "trc_ceremony_sensitive_scion_pki_test", + srcs = ["trc_ceremony_sensitive.sh"], + data = [ + "trc_ceremony.sh", + ":crypto_lib.sh", + "//scion-pki/cmd/scion-pki", + ], + env = { + "SCION_PKI_BIN": "$(location //scion-pki/cmd/scion-pki)", + "USE_SCION_PKI_SIGN": "1", + }, + tags = [ + "exclusive", + "integration", + ], +) diff --git a/tools/cryptoplayground/crypto_lib.sh b/tools/cryptoplayground/crypto_lib.sh index bce3f54f9f..6bdb1e0dd9 100644 --- a/tools/cryptoplayground/crypto_lib.sh +++ b/tools/cryptoplayground/crypto_lib.sh @@ -91,7 +91,7 @@ in_docker() { -e ENDDATE=$ENDDATE \ -e TRCID=$TRCID \ -e PREDID=$PREDID \ - emberstack/openssl \ + nginx:1.27.1 \ sh -c "set -e && . /scripts/crypto_lib.sh && $@" } @@ -106,8 +106,8 @@ PAYLOAD_CONF_SAMPLE=$(cat <<-END {{.VotingQuorum}} = 2 {{.CoreASes}} = ["ff00:0:110", "ff00:0:111"] {{.AuthoritativeASes}} = ["ff00:0:110", "ff00:0:111"] -{{.NotBefore}} = 1593000000 # Seconds since UNIX Epoch -{{.Validity}} = "365d" +{{.NotBefore}} = "2020-06-24T14:00:00+02:00" # RFC3339 +{{.NotAfter}} = "2021-06-24T14:00:00+02:00" {{.CertFiles}} = [ "bern/sensitive-voting.crt", "bern/regular-voting.crt", @@ -136,7 +136,7 @@ no_trust_reset = false [validity] not_before = {{.NotBefore}} -validity = {{.Validity}} +not_after = {{.NotAfter}} EOF # LITERALINCLUDE payload_conf END } @@ -151,8 +151,8 @@ SENSITIVE_PAYLOAD_CONF_SAMPLE=$(cat <<-END {{.Votes}} = [0, 3, 5] {{.CoreASes}} = ["ff00:0:110", "ff00:0:111"] {{.AuthoritativeASes}} = ["ff00:0:110", "ff00:0:111"] -{{.NotBefore}} = 1621857600 # Seconds since UNIX Epoch -{{.Validity}} = "365d" +{{.NotBefore}} = "2021-05-24T14:00:00+02:00" # RFC3339 +{{.NotAfter}} = "2022-05-24T14:00:00+02:00" {{.CertFiles}} = [ "bern/sensitive-voting.crt", "bern/regular-voting.crt", @@ -183,7 +183,7 @@ no_trust_reset = false [validity] not_before = {{.NotBefore}} -validity = {{.Validity}} +not_after = {{.NotAfter}} EOF # LITERALINCLUDE sensitive_payload_conf END } @@ -237,6 +237,23 @@ EOF # LITERALINCLUDE basic_conf END } +basic_conf_scion_pki() { +# LITERALINCLUDE basic_conf_scion_pki START +cat << EOF > subject.tmpl +{ + "country": "{{.Country}}", + "state": "{{.State}}", + "locality": "{{.Location}}", + "organization": "{{.Organization}}", + "organizational_unit": "{{.OrganizationalUnit}}", + "isd_as": "{{.ISDAS}}" +} +EOF + +export ORG="{{.ShortOrg}}" +# LITERALINCLUDE basic_conf_scion_pki END +} + prepare_ca() { # LITERALINCLUDE prepare_ca START mkdir -p database @@ -266,6 +283,12 @@ EOF # LITERALINCLUDE sensitive_conf END } +sensitive_cn() { +# LITERALINCLUDE sensitive_cn START +export CN_SENSITIVE="$ORG High Security Voting Certificate" +# LITERALINCLUDE sensitive_cn END +} + regular_conf() { # LITERALINCLUDE regular_conf START cat << EOF > regular-voting.cnf @@ -287,6 +310,12 @@ EOF # LITERALINCLUDE regular_conf END } +regular_cn() { +# LITERALINCLUDE regular_cn START +export CN_REGULAR="$ORG Regular Voting Certificate" +# LITERALINCLUDE regular_cn END +} + root_conf() { # LITERALINCLUDE root_conf START cat << EOF > cp-root.cnf @@ -310,6 +339,12 @@ EOF # LITERALINCLUDE root_conf END } +root_cn() { +# LITERALINCLUDE root_cn START +export CN_ROOT="$ORG High Security Root Certificate" +# LITERALINCLUDE root_cn END +} + ca_conf() { # LITERALINCLUDE ca_conf START cat << EOF > cp-ca.cnf @@ -392,6 +427,25 @@ gen_sensitive() { # LITERALINCLUDE gen_sensitive END } +gen_sensitive_scion_pki() { +# LITERALINCLUDE gen_sensitive_scion_pki START + # Uncomment and set the appropriate values: + # + # STARTDATE="2020-06-24T14:00:00+02:00" + # ENDDATE="2021-06-24T14:00:00+02:00" + + scion-pki certificate create \ + --profile sensitive-voting \ + --not-before $STARTDATE \ + --not-after $ENDDATE \ + --common-name "$CN_SENSITIVE" \ + subject.tmpl \ + sensitive-voting.crt \ + $KEYDIR/sensitive-voting.key +# LITERALINCLUDE gen_sensitive_scion_pki END +} + + check_sensitive() { # LITERALINCLUDE check_sensitive START openssl x509 -in sensitive-voting.crt -noout -dates @@ -437,6 +491,24 @@ gen_regular() { # LITERALINCLUDE gen_regular END } +gen_regular_scion_pki() { +# LITERALINCLUDE gen_regular_scion_pki START + # Uncomment and set the appropriate values: + # + # STARTDATE="2020-06-24T14:00:00+02:00" + # ENDDATE="2021-06-24T14:00:00+02:00" + + scion-pki certificate create \ + --profile regular-voting \ + --not-before $STARTDATE \ + --not-after $ENDDATE \ + --common-name "$CN_REGULAR" \ + subject.tmpl \ + regular-voting.crt \ + $KEYDIR/regular-voting.key +# LITERALINCLUDE gen_regular_scion_pki END +} + check_regular() { # LITERALINCLUDE check_regular START openssl x509 -in regular-voting.crt -noout -dates @@ -482,6 +554,25 @@ gen_root() { # LITERALINCLUDE gen_root END } + +gen_root_scion_pki() { +# LITERALINCLUDE gen_root_scion_pki START + # Uncomment and set the appropriate values: + # + # STARTDATE="2020-06-24T14:00:00+02:00" + # ENDDATE="2021-06-24T14:00:00+02:00" + + scion-pki certificate create \ + --profile cp-root \ + --not-before $STARTDATE \ + --not-after $ENDDATE \ + --common-name "$CN_ROOT" \ + subject.tmpl \ + cp-root.crt \ + $KEYDIR/cp-root.key +# LITERALINCLUDE gen_root_scion_pki END +} + check_root() { # LITERALINCLUDE check_root START openssl x509 -in cp-root.crt -noout -dates @@ -527,6 +618,26 @@ gen_ca() { # LITERALINCLUDE gen_ca END } +gen_ca_scion_pki() { +# LITERALINCLUDE gen_ca_scion_pki START + # Uncomment and set the appropriate values: + # + # STARTDATE="2020-06-24T14:00:00+02:00" + # ENDDATE="2020-07-01T14:00:00+02:00" + + scion-pki certificate create \ + --ca cp-root.crt \ + --ca-key $KEYDIR/cp-root.key \ + --not-before $STARTDATE \ + --not-after $ENDDATE \ + --common-name "$ORG Secure CA Certificate" \ + --profile cp-ca \ + subject.tmpl \ + cp-ca.crt \ + $KEYDIR/cp-ca.key +# LITERALINCLUDE gen_ca_scion_pki END +} + check_ca() { # LITERALINCLUDE check_ca START openssl x509 -in cp-ca.crt -noout -dates @@ -569,6 +680,33 @@ gen_as_ca_steps() { # LITERALINCLUDE gen_as_ca_steps END } +gen_as_scion_pki() { +# LITERALINCLUDE gen_as_scion_pki_as_steps START + scion-pki certificate create \ + --profile cp-as \ + --common-name "$ORG AS Certificate" \ + --csr \ + subject.tmpl \ + cp-as.csr \ + $KEYDIR/cp-as.key +# LITERALINCLUDE gen_as_scion_pki_as_steps END +# LITERALINCLUDE gen_as_scion_pki_ca_steps START + # Uncomment and set the appropriate values: + # + # STARTDATE="2020-06-24T14:00:00+02:00" + # ENDDATE="2020-06-27T14:00:00+02:00" + + scion-pki certificate sign \ + --bundle \ + --ca cp-ca.crt \ + --ca-key $KEYDIR/cp-ca.key \ + --not-before $STARTDATE \ + --not-after $ENDDATE \ + cp-as.csr \ + > chain.pem +# LITERALINCLUDE gen_as_scion_pki_ca_steps END +} + check_as() { # LITERALINCLUDE check_as START openssl x509 -in cp-as.crt -noout -dates @@ -618,6 +756,19 @@ sign_payload() { # LITERALINCLUDE sign_payload END } +sign_payload_scion_pki() { +# LITERALINCLUDE sign_payload_scion_pki START + scion-pki trc sign $TRCID.pld.der \ + $PUBDIR/regular-voting.crt \ + $KEYDIR/regular-voting.key \ + -o $TRCID.regular.trc + scion-pki trc sign $TRCID.pld.der \ + $PUBDIR/sensitive-voting.crt \ + $KEYDIR/sensitive-voting.key \ + -o $TRCID.sensitive.trc +# LITERALINCLUDE sign_payload_scion_pki END +} + sensitive_vote() { # LITERALINCLUDE sensitive_vote START openssl cms -sign -in $TRCID.pld.der -inform der \ @@ -628,6 +779,15 @@ sensitive_vote() { # LITERALINCLUDE sensitive_vote END } +sensitive_vote_scion_pki() { +# LITERALINCLUDE sensitive_vote_scion_pki START + scion-pki trc sign $TRCID.pld.der \ + $PUBDIR/$PREDID/sensitive-voting.crt \ + $KEYDIR/$PREDID/sensitive-voting.key \ + -o $TRCID.sensitive.vote.trc +# LITERALINCLUDE sensitive_vote_scion_pki END +} + regular_vote() { # LITERALINCLUDE regular_vote START openssl cms -sign -in $TRCID.pld.der -inform der \ @@ -638,6 +798,13 @@ regular_vote() { # LITERALINCLUDE regular_vote END } +check_signed_payload_scion_pki() { +# LITERALINCLUDE check_signed_payload_scion_pki START + scion-pki trc inspect $TRCID.regular.trc + scion-pki trc inspect $TRCID.sensitive.trc +# LITERALINCLUDE check_signed_payload_scion_pki END +} + check_signed_payload() { # LITERALINCLUDE check_signed_payload START openssl cms -verify -in $TRCID.sensitive.trc -inform der \ @@ -681,6 +848,12 @@ check_sensitive_vote() { # LITERALINCLUDE check_sensitive_vote END } +check_sensitive_vote_scion_pki() { +# LITERALINCLUDE check_sensitive_vote_scion_pki START + scion-pki trc inspect $TRCID.sensitive.vote.trc +# LITERALINCLUDE check_sensitive_vote_scion_pki END +} + check_regular_vote() { # LITERALINCLUDE check_regular_vote START openssl cms -verify -in $TRCID.regular.vote.trc -inform der \ @@ -744,6 +917,12 @@ display_payload() { # LITERALINCLUDE display_payload END } +display_payload_scion_pki() { +# LITERALINCLUDE display_payload_scion_pki START + scion-pki trc inspect $TRCID.pld.der +# LITERALINCLUDE display_payload_scion_pki END +} + display_signatures() { # LITERALINCLUDE display_signatures START openssl pkcs7 -in $TRCID.trc -inform der -print -noout @@ -757,3 +936,11 @@ display_signatures() { # -noout: do not display the encoded structure. # LITERALINCLUDE display_signatures END } + +display_signatures_scion_pki() { +# LITERALINCLUDE display_signatures_scion_pki START + scion-pki trc inspect $TRCID.trc +# LITERALINCLUDE display_signatures_scion_pki END +} + + diff --git a/tools/cryptoplayground/trc_ceremony.sh b/tools/cryptoplayground/trc_ceremony.sh index 896c9bc400..7405ba550f 100755 --- a/tools/cryptoplayground/trc_ceremony.sh +++ b/tools/cryptoplayground/trc_ceremony.sh @@ -8,13 +8,19 @@ export PLAYGROUND=$(realpath "${PLAYGROUND:-$SCION_ROOT/tools/cryptoplayground}" export SAFEDIR=${SAFEDIR:-$(mktemp -d)} export SCION_PKI_BIN=${SCION_PKI_BIN:-$SCION_ROOT/bin/scion-pki} export PATH="$(realpath $(dirname "$SCION_PKI_BIN")):$PATH" +export USE_SCION_PKI_SIGN=${USE_SCION_PKI_SIGN:-} . $PLAYGROUND/crypto_lib.sh set -e -STARTDATE="20200624120000Z" -ENDDATE="20210624120000Z" +if [ -z "$USE_SCION_PKI_SIGN" ]; then + STARTDATE="20200624120000Z" + ENDDATE="20210624120000Z" +else + STARTDATE="2020-06-24T14:00:00+02:00" + ENDDATE="2021-06-24T14:00:00+02:00" +fi TRCID="ISD1-B1-S1" echo "#####################" @@ -36,27 +42,47 @@ do set_dirs # Generate configuration files navigate_pubdir - basic_conf && sensitive_conf && regular_conf && root_conf && ca_conf && as_conf - prepare_ca - sed -i \ - -e 's/{{.Country}}/CH/g' \ - -e "s/{{.State}}/$loc/g" \ - -e "s/{{.Location}}/$loc/g" \ - -e "s/{{.Organization}}/$loc/g" \ - -e "s/{{.OrganizationalUnit}}/$loc InfoSec Squad/g" \ - -e "s/{{.ISDAS}}/$IA/g" \ - basic.cnf - for cnf in *.cnf - do + + if [ -z "$USE_SCION_PKI_SIGN" ]; then + basic_conf && sensitive_conf && regular_conf && root_conf && ca_conf && as_conf + prepare_ca sed -i \ - -e "s/{{.ShortOrg}}/$loc/g" \ - $cnf - done - # Generate certificates - in_docker 'navigate_pubdir && gen_sensitive && check_sensitive && gen_regular && check_regular && gen_root && check_root' + -e 's/{{.Country}}/CH/g' \ + -e "s/{{.State}}/$loc/g" \ + -e "s/{{.Location}}/$loc/g" \ + -e "s/{{.Organization}}/$loc/g" \ + -e "s/{{.OrganizationalUnit}}/$loc InfoSec Squad/g" \ + -e "s/{{.ISDAS}}/$IA/g" \ + basic.cnf + for cnf in *.cnf + do + sed -i \ + -e "s/{{.ShortOrg}}/$loc/g" \ + $cnf + done + # Generate certificates + in_docker 'navigate_pubdir && gen_sensitive && check_sensitive && gen_regular && check_regular && gen_root && check_root' + else + basic_conf_scion_pki + sed -i \ + -e 's/{{.Country}}/CH/g' \ + -e "s/{{.State}}/$loc/g" \ + -e "s/{{.Location}}/$loc/g" \ + -e "s/{{.Organization}}/$loc/g" \ + -e "s/{{.OrganizationalUnit}}/$loc InfoSec Squad/g" \ + -e "s/{{.ISDAS}}/$IA/g" \ + subject.tmpl + export ORG=$loc + sensitive_cn && gen_sensitive_scion_pki + regular_cn && gen_regular_scion_pki + root_cn && gen_root_scion_pki + fi check_sensitive_type && check_regular_type && check_root_type done +echo "Openssl version" +in_docker "openssl version" + echo "###########" echo "# Phase 1 #" echo "###########" @@ -78,6 +104,13 @@ for cert in {bern,geneva,zürich}/*.crt; do done # LITERALINCLUDE display_validity END +# LITERALINCLUDE display_validity_scion-pki START +for cert in {bern,geneva,zürich}/*.crt; do + echo $cert + scion-pki certificate inspect $cert | grep Validity -A 2 +done +# LITERALINCLUDE display_validity_scion-pki END + # LITERALINCLUDE display_signature_algo START for cert in {bern,geneva,zürich}/*.crt; do echo $cert @@ -86,6 +119,13 @@ for cert in {bern,geneva,zürich}/*.crt; do done # LITERALINCLUDE display_signature_algo END +# LITERALINCLUDE display_signature_algo_scion-pki START +for cert in {bern,geneva,zürich}/*.crt; do + echo $cert + scion-pki certificate inspect $cert | grep -m 1 "Signature Algorithm" +done +# LITERALINCLUDE display_signature_algo_scion-pki END + # LITERALINCLUDE validate_certificate_type START for cert in {bern,geneva,zürich}/*.crt; do scion-pki certs validate --type $(basename $cert .crt) $cert @@ -140,8 +180,8 @@ sed -i \ -e 's/{{.VotingQuorum}}/2/g' \ -e 's/{{.CoreASes}}/["ff00:0:110", "ff00:0:111"]/g' \ -e 's/{{.AuthoritativeASes}}/["ff00:0:110", "ff00:0:111"]/g' \ - -e 's/{{.NotBefore}}/1593000000/g' \ - -e 's/{{.Validity}}/"365d"/g' \ + -e 's/{{.NotBefore}}/"2020-06-24T14:00:00+02:00"/g' \ + -e 's/{{.NotAfter}}/"2021-06-24T14:00:00+02:00"/g' \ -e "s/{{.CertFiles}}/[$files]/g" \ $TRCID.toml @@ -151,7 +191,7 @@ cat $TRCID.toml echo "-------------------------------" # LITERALINCLUDE create_payload START -scion-pki trcs payload -t $TRCID.toml -o $TRCID.pld.der +scion-pki trc payload -t $TRCID.toml -o $TRCID.pld.der # LITERALINCLUDE create_payload END echo "Phase 2: display payload digest" @@ -176,7 +216,13 @@ do cd $SAFEDIR/$loc set_dirs - in_docker "cd /workdir && display_payload && sign_payload && check_signed_payload" + display_payload_scion_pki + if [ -z "$USE_SCION_PKI_SIGN" ]; then + in_docker "cd /workdir && display_payload && sign_payload && check_signed_payload" + else + sign_payload_scion_pki + check_signed_payload_scion_pki + fi cp $TRCID.{regular,sensitive}.trc $SAFEDIR/admin/$loc done @@ -188,7 +234,7 @@ echo "Phase 4: combine TRC" cd $SAFEDIR/admin # LITERALINCLUDE combine_payload START -scion-pki trcs combine -p $TRCID.pld.der \ +scion-pki trc combine -p $TRCID.pld.der \ bern/$TRCID.sensitive.trc \ bern/$TRCID.regular.trc \ geneva/$TRCID.sensitive.trc \ @@ -199,7 +245,7 @@ scion-pki trcs combine -p $TRCID.pld.der \ # LITERALINCLUDE combine_payload END # LITERALINCLUDE verify_payload START -scion-pki trcs verify --anchor $TRCID.trc $TRCID.trc +scion-pki trc verify --anchor $TRCID.trc $TRCID.trc # LITERALINCLUDE verify_payload END in_docker "cd /workdir && verify_trc" @@ -238,14 +284,21 @@ do navigate_pubdir echo "Phase 5: $loc generate CA certificate" - in_docker "navigate_pubdir && gen_ca && check_ca" - check_ca_type - + if [ -z "$USE_SCION_PKI_SIGN" ]; then + in_docker "navigate_pubdir && gen_ca && check_ca" + check_ca_type + else + gen_ca_scion_pki + fi echo "Phase 5: $loc generate AS certificate" - in_docker "navigate_pubdir && gen_as && check_as" - check_as_type - cat cp-as.crt cp-ca.crt > chain.pem - scion-pki certs verify --trc ../$TRCID.trc --currenttime 1593000000 chain.pem + if [ -z "$USE_SCION_PKI_SIGN" ]; then + in_docker "navigate_pubdir && gen_as && check_as" + check_as_type + cat cp-as.crt cp-ca.crt > chain.pem + else + gen_as_scion_pki + fi + scion-pki certificate verify --trc ../$TRCID.trc --currenttime 1593000000 chain.pem done echo "###########" diff --git a/tools/cryptoplayground/trc_ceremony_sensitive.sh b/tools/cryptoplayground/trc_ceremony_sensitive.sh index b5fce6efea..23e6278859 100755 --- a/tools/cryptoplayground/trc_ceremony_sensitive.sh +++ b/tools/cryptoplayground/trc_ceremony_sensitive.sh @@ -8,6 +8,7 @@ export PLAYGROUND=$(realpath "${PLAYGROUND:-$SCION_ROOT/tools/cryptoplayground}" export SAFEDIR=${SAFEDIR:-$(mktemp -d)} export SCION_PKI_BIN=${SCION_PKI_BIN:-$SCION_ROOT/bin/scion-pki} export PATH="$(realpath $(dirname "$SCION_PKI_BIN")):$PATH" +export USE_SCION_PKI_SIGN=${USE_SCION_PKI_SIGN:-} . $PLAYGROUND/crypto_lib.sh @@ -27,8 +28,13 @@ if [ ! -d "$SAFEDIR/admin" ]; then echo "" fi -STARTDATE="20210524120000Z" -ENDDATE="20220524120000Z" +if [ -z "$USE_SCION_PKI_SIGN" ]; then + STARTDATE="20210524120000Z" + ENDDATE="20220524120000Z" +else + STARTDATE="2021-05-24T14:00:00+02:00" + ENDDATE="2022-05-24T14:00:00+02:00" +fi PREDID="ISD1-B1-S1" TRCID="ISD1-B1-S2" @@ -54,9 +60,20 @@ do TRCVERSION=$PREDID && version_sensitive && version_regular && version_root - # Generate certificates - in_docker 'navigate_pubdir && gen_sensitive && check_sensitive && gen_regular && check_regular && gen_root && check_root' + if [ -z "$USE_SCION_PKI_SIGN" ]; then + # Generate certificates + in_docker 'navigate_pubdir && gen_sensitive && check_sensitive && gen_regular && check_regular && gen_root && check_root' + else + # Clean up keys and certificates from base ceremony + rm $KEYDIR/cp-ca.key $KEYDIR/cp-as.key cp-ca.crt cp-as.csr chain.pem + + export ORG=$loc + sensitive_cn && gen_sensitive_scion_pki + regular_cn && gen_regular_scion_pki + root_cn && gen_root_scion_pki + fi check_sensitive_type && check_regular_type && check_root_type + done echo "###########" @@ -80,6 +97,13 @@ for cert in {bern,geneva,zürich}/*.crt; do done # LITERALINCLUDE display_validity END +# LITERALINCLUDE display_validity_scion-pki START +for cert in {bern,geneva,zürich}/*.crt; do + echo $cert + scion-pki certificate inspect $cert | grep Validity -A 2 +done +# LITERALINCLUDE display_validity_scion-pki END + # LITERALINCLUDE display_signature_algo START for cert in {bern,geneva,zürich}/*.crt; do echo $cert @@ -88,6 +112,13 @@ for cert in {bern,geneva,zürich}/*.crt; do done # LITERALINCLUDE display_signature_algo END +# LITERALINCLUDE display_signature_algo_scion-pki START +for cert in {bern,geneva,zürich}/*.crt; do + echo $cert + scion-pki certificate inspect $cert | grep -m 1 "Signature Algorithm" +done +# LITERALINCLUDE display_signature_algo_scion-pki END + # LITERALINCLUDE validate_certificate_type START for cert in {bern,geneva,zürich}/*.crt; do scion-pki certs validate --type $(basename $cert .crt) $cert @@ -145,8 +176,8 @@ sed -i \ -e 's/{{.Votes}}/[0, 3, 6]/g' \ -e 's/{{.CoreASes}}/["ff00:0:110", "ff00:0:111"]/g' \ -e 's/{{.AuthoritativeASes}}/["ff00:0:110", "ff00:0:111"]/g' \ - -e 's/{{.NotBefore}}/1621857600/g' \ - -e 's/{{.Validity}}/"365d"/g' \ + -e 's/{{.NotBefore}}/"2021-05-24T14:00:00+02:00"/g' \ + -e 's/{{.NotAfter}}/"2022-05-24T14:00:00+02:00"/g' \ -e "s/{{.CertFiles}}/[$files]/g" \ $TRCID.toml @@ -181,7 +212,14 @@ do cd $SAFEDIR/$loc set_dirs - in_docker "cd /workdir && display_payload && sign_payload && check_signed_payload && sensitive_vote && check_sensitive_vote" + display_payload_scion_pki + if [ -z "$USE_SCION_PKI_SIGN" ]; then + in_docker "cd /workdir && display_payload && sign_payload && check_signed_payload && sensitive_vote && check_sensitive_vote" + else + sign_payload_scion_pki + sensitive_vote_scion_pki + check_signed_payload_scion_pki + fi cp $TRCID.{regular,sensitive,sensitive.vote}.trc $SAFEDIR/admin/$loc done @@ -220,7 +258,7 @@ echo "---------------------------" echo "Phase 4: display trc contents" # LITERALINCLUDE trc_content START -scion-pki trcs human --predecessor $PREDID.trc $TRCID.trc +scion-pki trc inspect --predecessor $PREDID.trc $TRCID.trc # LITERALINCLUDE trc_content END for loc in {bern,geneva,zürich} @@ -232,8 +270,12 @@ do set_dirs scion-pki trcs verify --anchor $PREDID.trc $TRCID.trc # LITERALINCLUDE trc_content_rep START - scion-pki trcs human --predecessor $PREDID.trc $TRCID.trc + scion-pki trc inspect --predecessor $PREDID.trc $TRCID.trc # LITERALINCLUDE trc_content_rep END + + # LITERALINCLUDE format_trc START + scion-pki trc format --format pem $TRCID.trc + # LITERALINCLUDE format_trc END done echo "Phase 5: sanity check - generate CA and AS Certificates" @@ -248,13 +290,20 @@ do navigate_pubdir echo "Phase 5: $loc generate CA certificate" - in_docker "navigate_pubdir && gen_ca && check_ca" - check_ca_type - + if [ -z "$USE_SCION_PKI_SIGN" ]; then + in_docker "navigate_pubdir && gen_ca && check_ca" + check_ca_type + else + gen_ca_scion_pki + fi echo "Phase 5: $loc generate AS certificate" - in_docker "navigate_pubdir && gen_as && check_as" - check_as_type - cat cp-as.crt cp-ca.crt > chain.pem + if [ -z "$USE_SCION_PKI_SIGN" ]; then + in_docker "navigate_pubdir && gen_as && check_as" + check_as_type + cat cp-as.crt cp-ca.crt > chain.pem + else + gen_as_scion_pki + fi scion-pki certs verify --trc ../$TRCID.trc --currenttime 1621857600 chain.pem done From 24ec39d12315967a27c0a1634f72e2d62cac8411 Mon Sep 17 00:00:00 2001 From: thomasgruebl <60517996+thomasgruebl@users.noreply.github.com> Date: Tue, 17 Sep 2024 11:55:18 +0200 Subject: [PATCH 21/29] tutorial: topology source host missing causes scion-router@br.service to crash (#4619) Hi, I've tried to setup the freestanding SCION network as per the [tutorial](https://docs.scion.org/en/latest/tutorials/deploy.html) and ran into a few issues: Using the default topology files from the website, the scion-router service always crashes because of an invalid source IP (see screenshot below): ![image](https://github.com/user-attachments/assets/cef3fa72-a945-438f-ac31-1bc535da2a44) @tobiasmoldan realized that this can be resolved by adding the source IP (or host name) to the local field in the topology: `"underlay": { "local": "scion01:50012", "remote": "scion02:50012" },` Secondly, I was wondering if all ASes need to be up and running for the network to be fully functional? I have set up and configured scion01 and scion02 as per the tutorial. All services (daemon, router, control, dispatcher) are active and there is a direct link between the two VMs. The machines are pingable (via normal ICMP), however, there is no reachability via SCMP. I assume that, even without scion03-05, they should have connectivity? I got scion addresses for scion01 and scion02 respectively, `42-ffaa:1:1,127.0.0.1` `42-ffaa:1:2,127.0.0.1` and I have generated the certificate material on scion01 and shared it with scion02. Is there anything I'm missing - e.g., does path exploration need to be triggered somehow or should it happen automatically? Thanks a lot for your help on this! Best regards, Thomas --------- Co-authored-by: jiceatscion <139873336+jiceatscion@users.noreply.github.com> --- doc/tutorials/deploy.rst | 10 +++++----- doc/tutorials/deploy/topology1.json | 6 +++--- doc/tutorials/deploy/topology2.json | 6 +++--- doc/tutorials/deploy/topology3.json | 6 +++--- doc/tutorials/deploy/topology4.json | 4 ++-- doc/tutorials/deploy/topology5.json | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/doc/tutorials/deploy.rst b/doc/tutorials/deploy.rst index 8edf45cd92..e3dcdf2f31 100644 --- a/doc/tutorials/deploy.rst +++ b/doc/tutorials/deploy.rst @@ -86,11 +86,11 @@ OS Setup .. code-block:: sh # additions to /etc/hosts - 10.0.1.1 scion01 - 10.0.1.2 scion02 - 10.0.1.3 scion03 - 10.0.1.4 scion04 - 10.0.1.5 scion05 + 10.0.0.1 scion01 + 10.0.0.2 scion02 + 10.0.0.3 scion03 + 10.0.0.4 scion04 + 10.0.0.5 scion05 .. _step1: diff --git a/doc/tutorials/deploy/topology1.json b/doc/tutorials/deploy/topology1.json index 9f05ed5247..22e8ad252d 100644 --- a/doc/tutorials/deploy/topology1.json +++ b/doc/tutorials/deploy/topology1.json @@ -20,7 +20,7 @@ "interfaces": { "1": { "underlay": { - "local": ":50014", + "local": "scion01:50014", "remote": "scion04:50014" }, "isd_as": "42-ffaa:1:4", @@ -29,7 +29,7 @@ }, "2": { "underlay": { - "local": ":50012", + "local": "scion01:50012", "remote": "scion02:50012" }, "isd_as": "42-ffaa:1:2", @@ -38,7 +38,7 @@ }, "3": { "underlay": { - "local": ":50013", + "local": "scion01:50013", "remote": "scion03:50013" }, "isd_as": "42-ffaa:1:3", diff --git a/doc/tutorials/deploy/topology2.json b/doc/tutorials/deploy/topology2.json index 6b3dda3ad1..822d198199 100644 --- a/doc/tutorials/deploy/topology2.json +++ b/doc/tutorials/deploy/topology2.json @@ -20,7 +20,7 @@ "interfaces": { "1": { "underlay": { - "local": ":50012", + "local": "scion02:50012", "remote": "scion01:50012" }, "isd_as": "42-ffaa:1:1", @@ -29,7 +29,7 @@ }, "2": { "underlay": { - "local": ":50023", + "local": "scion02:50023", "remote": "scion03:50023" }, "isd_as": "42-ffaa:1:3", @@ -38,7 +38,7 @@ }, "3": { "underlay": { - "local": ":50025", + "local": "scion02:50025", "remote": "scion05:50025" }, "isd_as": "42-ffaa:1:5", diff --git a/doc/tutorials/deploy/topology3.json b/doc/tutorials/deploy/topology3.json index e414c520a9..2c922b3241 100644 --- a/doc/tutorials/deploy/topology3.json +++ b/doc/tutorials/deploy/topology3.json @@ -20,7 +20,7 @@ "interfaces": { "1": { "underlay": { - "local": ":50013", + "local": "scion03:50013", "remote": "scion01:50013" }, "isd_as": "42-ffaa:1:1", @@ -29,7 +29,7 @@ }, "2": { "underlay": { - "local": ":50023", + "local": "scion03:50023", "remote": "scion02:50023" }, "isd_as": "42-ffaa:1:2", @@ -38,7 +38,7 @@ }, "3": { "underlay": { - "local": ":50034", + "local": "scion03:50034", "remote": "scion04:50034" }, "isd_as": "42-ffaa:1:4", diff --git a/doc/tutorials/deploy/topology4.json b/doc/tutorials/deploy/topology4.json index 0ae79506cb..f1c13c1ff1 100644 --- a/doc/tutorials/deploy/topology4.json +++ b/doc/tutorials/deploy/topology4.json @@ -18,7 +18,7 @@ "interfaces": { "1": { "underlay": { - "local": ":50014", + "local": "scion04:50014", "remote": "scion01:50014" }, "isd_as": "42-ffaa:1:1", @@ -27,7 +27,7 @@ }, "2": { "underlay": { - "local": ":50034", + "local": "scion04:50034", "remote": "scion03:50034" }, "isd_as": "42-ffaa:1:3", diff --git a/doc/tutorials/deploy/topology5.json b/doc/tutorials/deploy/topology5.json index f32130cfec..d9852553ad 100644 --- a/doc/tutorials/deploy/topology5.json +++ b/doc/tutorials/deploy/topology5.json @@ -18,7 +18,7 @@ "interfaces": { "1": { "underlay": { - "local": ":50025", + "local": "scion05:50025", "remote": "scion02:50025" }, "isd_as": "42-ffaa:1:2", @@ -27,7 +27,7 @@ }, "2": { "underlay": { - "local": ":50035", + "local": "scion05:50035", "remote": "scion03:50035" }, "isd_as": "42-ffaa:1:3", From f16cdd6599b06700f440fa242c8d7dbbe1ade75c Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Tue, 17 Sep 2024 18:06:58 +0200 Subject: [PATCH 22/29] build: force old timer behavior (#4620) Until https://github.com/golang/go/issues/69312 is resolved, force the old timer behavior by specifying an older go version in the go.mod file. Fixes #4606 --- .buildkite/pipeline.yml | 6 +- WORKSPACE | 4 +- go.mod | 2 +- .../d3flamegraph/D3_FLAME_GRAPH_LICENSE | 201 ++++++++++++++++++ .../pprof/third_party/d3flamegraph/D3_LICENSE | 13 ++ .../src/cmd/vendor/golang.org/x/build/LICENSE | 27 --- .../cmd/vendor/golang.org/x/telemetry/LICENSE | 27 --- .../src/cmd/vendor/golang.org/x/text/LICENSE | 27 --- .../src/cmd/vendor/rsc.io/markdown/LICENSE | 27 --- tools/await-connectivity | 7 +- 10 files changed, 222 insertions(+), 119 deletions(-) create mode 100644 licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE create mode 100644 licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE delete mode 100644 licenses/data/go_sdk/src/cmd/vendor/golang.org/x/build/LICENSE delete mode 100644 licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE delete mode 100644 licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE delete mode 100644 licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 766833d3ce..72c9c14cdb 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -116,7 +116,7 @@ steps: - ./scion.sh run - tools/await-connectivity - ./bin/scion_integration || ( echo "^^^ +++" && false ) - - ./bin/end2end_integration --attempts=3 || ( echo "^^^ +++" && false ) + - ./bin/end2end_integration || ( echo "^^^ +++" && false ) plugins: &scion-run-hooks - scionproto/metahook#v0.3.0: pre-command: .buildkite/cleanup-leftovers.sh @@ -142,7 +142,7 @@ steps: - ./scion.sh topology -c topology/default-no-peers.topo - ./scion.sh run - tools/await-connectivity - - ./bin/end2end_integration --attempts=3 || ( echo "^^^ +++" && false ) + - ./bin/end2end_integration || ( echo "^^^ +++" && false ) - ./tools/integration/revocation_test.sh plugins: *scion-run-hooks artifact_paths: *scion-run-artifact-paths @@ -158,7 +158,7 @@ steps: - ./scion.sh run - tools/await-connectivity - echo "--- run tests" - - ./bin/end2end_integration -d --attempts=3 || ( echo "^^^ +++" && false ) + - ./bin/end2end_integration -d || ( echo "^^^ +++" && false ) plugins: *scion-run-hooks artifact_paths: *scion-run-artifact-paths timeout_in_minutes: 15 diff --git a/WORKSPACE b/WORKSPACE index d1f70c41ee..53b4207e4f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -59,7 +59,7 @@ go_rules_dependencies() go_register_toolchains( nogo = "@//:nogo", - version = "1.23.0", + version = "1.22.7", ) # Gazelle @@ -265,7 +265,7 @@ load("@aspect_rules_js//js:repositories.bzl", "rules_js_dependencies") rules_js_dependencies() -load("@rules_nodejs//nodejs:repositories.bzl", "DEFAULT_NODE_VERSION", "nodejs_register_toolchains") +load("@rules_nodejs//nodejs:repositories.bzl", "nodejs_register_toolchains") nodejs_register_toolchains( name = "nodejs", diff --git a/go.mod b/go.mod index 90fd42899a..b830145a55 100644 --- a/go.mod +++ b/go.mod @@ -128,4 +128,4 @@ require ( modernc.org/token v1.1.0 // indirect ) -go 1.23.0 +go 1.22.7 diff --git a/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE b/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE new file mode 100644 index 0000000000..8dada3edaf --- /dev/null +++ b/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_FLAME_GRAPH_LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. diff --git a/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE b/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE new file mode 100644 index 0000000000..b0145150fd --- /dev/null +++ b/licenses/data/go_sdk/src/cmd/vendor/github.com/google/pprof/third_party/d3flamegraph/D3_LICENSE @@ -0,0 +1,13 @@ +Copyright 2010-2021 Mike Bostock + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted, provided that the above copyright notice +and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. diff --git a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/build/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/build/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/build/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE deleted file mode 100644 index 2a7cf70da6..0000000000 --- a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/telemetry/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright 2009 The Go Authors. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google LLC nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/licenses/data/go_sdk/src/cmd/vendor/golang.org/x/text/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE b/licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/licenses/data/go_sdk/src/cmd/vendor/rsc.io/markdown/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tools/await-connectivity b/tools/await-connectivity index e0876f1509..9438ffeaf2 100755 --- a/tools/await-connectivity +++ b/tools/await-connectivity @@ -88,12 +88,12 @@ main() { local noncores=$(sed -n '/Non-core/,${s/^- //p}' gen/as_list.yml) for i in $(seq 1 "$QUIET"); do - check_connectivity "$cores" "$noncores" > /dev/null && return 0 + check_connectivity "$cores" "$noncores" > /dev/null && exit 0 sleep 1 done for i in $(seq "$QUIET" $((TIMEOUT-1))); do echo "Check after ${i}s" - check_connectivity "$cores" "$noncores" && return 0 + check_connectivity "$cores" "$noncores" && exit 0 sleep 1 done echo "Check after ${TIMEOUT}s" @@ -101,6 +101,3 @@ main() { } main "$@" - -# that is not enough. Down segment registrations don't seem to happen fast. -sleep 10 From f0d570b1cdf7cfd374abb5efc91aa68cc489ee0d Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Tue, 17 Sep 2024 18:29:23 +0200 Subject: [PATCH 23/29] scion-pki: show ISD-AS in distinguished name (#4611) Include the ISD-AS in the output of the distinguished name of the certificate. Previously, the output would show `UnknownOID=1.3.6.1.4.1.55324.1.2.1` instead of the ISD-AS. Furthemore, represent the extended key usage for sensitive voting, regular voting, and cppki root certificates as a human readable string. --- scion-pki/certs/certinfo.go | 15 ++++++++++++++- .../testdata/inspect/sample_certificate.golden | 8 ++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/scion-pki/certs/certinfo.go b/scion-pki/certs/certinfo.go index eab1755dcf..a8b5d7efaf 100644 --- a/scion-pki/certs/certinfo.go +++ b/scion-pki/certs/certinfo.go @@ -45,6 +45,8 @@ import ( "time" "github.com/pkg/errors" + + "github.com/scionproto/scion/pkg/scrypto/cppki" ) // Time formats used @@ -154,6 +156,8 @@ func printName(names []pkix.AttributeTypeAndValue, buf *bytes.Buffer) []string { values = append(values, fmt.Sprintf("DC=%s", name.Value)) } else if oid.Equal(oidUserID) { values = append(values, fmt.Sprintf("UID=%s", name.Value)) + } else if oid.Equal(cppki.OIDNameIA) { + values = append(values, fmt.Sprintf("ISD-AS=%s", name.Value)) } else { values = append(values, fmt.Sprintf("UnknownOID=%s", name.Type.String())) } @@ -628,7 +632,16 @@ func certificateText(cert *x509.Certificate) (string, error) { } } for _, oid := range cert.UnknownExtKeyUsage { - list = append(list, oid.String()) + switch { + case oid.Equal(cppki.OIDExtKeyUsageSensitive): + list = append(list, "Sensitive Voting") + case oid.Equal(cppki.OIDExtKeyUsageRegular): + list = append(list, "Regular Voting") + case oid.Equal(cppki.OIDExtKeyUsageRoot): + list = append(list, "CPPKI Root") + default: + list = append(list, oid.String()) + } } if len(list) > 0 { buf.WriteString(fmt.Sprintf("%16s%s", "", list[0])) diff --git a/scion-pki/certs/testdata/inspect/sample_certificate.golden b/scion-pki/certs/testdata/inspect/sample_certificate.golden index 788dc81544..22677ddcbd 100644 --- a/scion-pki/certs/testdata/inspect/sample_certificate.golden +++ b/scion-pki/certs/testdata/inspect/sample_certificate.golden @@ -3,11 +3,11 @@ Certificate: Version: 3 (0x2) Serial Number: 236926349964825539132366110936757753936879769458 (0x2980251cdc8ab9152895adda753f4865173f5772) Signature Algorithm: ECDSA-SHA512 - Issuer: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 Secure CA Certificate,UnknownOID=1.3.6.1.4.1.55324.1.2.1 + Issuer: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 Secure CA Certificate,ISD-AS=1-ff00:0:110 Validity Not Before: Mar 18 17:12:31 2021 UTC Not After : Mar 18 17:12:31 2022 UTC - Subject: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 AS Certificate,UnknownOID=1.3.6.1.4.1.55324.1.2.1 + Subject: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 AS Certificate,ISD-AS=1-ff00:0:110 Subject Public Key Info: Public Key Algorithm: ECDSA Public-Key: (256 bit) @@ -39,11 +39,11 @@ Certificate: Version: 3 (0x2) Serial Number: 667057667842995775975688328585225864023964590390 (0x74d7e67c8e2a0293b27d2b78b0e700eedc772136) Signature Algorithm: ECDSA-SHA512 - Issuer: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 High Security Root Certificate,UnknownOID=1.3.6.1.4.1.55324.1.2.1 + Issuer: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 High Security Root Certificate,ISD-AS=1-ff00:0:110 Validity Not Before: Mar 18 17:12:31 2021 UTC Not After : Mar 18 17:12:31 2023 UTC - Subject: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 Secure CA Certificate,UnknownOID=1.3.6.1.4.1.55324.1.2.1 + Subject: C=CH,ST=Zürich,L=Zürich,O=1-ff00:0:110,OU=1-ff00:0:110 InfoSec Squad,CN=1-ff00:0:110 Secure CA Certificate,ISD-AS=1-ff00:0:110 Subject Public Key Info: Public Key Algorithm: ECDSA Public-Key: (256 bit) From a83a906b71663c3db5a2e4aa22c23429428dead7 Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Wed, 18 Sep 2024 16:48:20 +0200 Subject: [PATCH 24/29] scion-pki: support dummy TRC payload (#4626) The dummy TRC payload allows to create a TRC payload without much setup. This is useful for testing access to the necessary cryptographic material, especially in preparation of a TRC ceremony. --- .../scion-pki/scion-pki_trc_payload.rst | 1 + .../scion-pki/scion-pki_trc_payload_dummy.rst | 37 +++++++++++++ doc/command/scion-pki/scion-pki_trc_sign.rst | 3 ++ scion-pki/trcs/BUILD.bazel | 2 + scion-pki/trcs/payload.go | 45 ++++++++++++++++ scion-pki/trcs/sign.go | 19 ++++++- tools/cryptoplayground/crypto_lib.sh | 54 +++++++++++++++++++ tools/cryptoplayground/trc_ceremony.sh | 1 + 8 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 doc/command/scion-pki/scion-pki_trc_payload_dummy.rst diff --git a/doc/command/scion-pki/scion-pki_trc_payload.rst b/doc/command/scion-pki/scion-pki_trc_payload.rst index 41dc186b43..99bbe07bd0 100644 --- a/doc/command/scion-pki/scion-pki_trc_payload.rst +++ b/doc/command/scion-pki/scion-pki_trc_payload.rst @@ -50,4 +50,5 @@ SEE ALSO ~~~~~~~~ * :ref:`scion-pki trc ` - Manage TRCs for the SCION control plane PKI +* :ref:`scion-pki trc payload dummy ` - Generate dummy TRC payload diff --git a/doc/command/scion-pki/scion-pki_trc_payload_dummy.rst b/doc/command/scion-pki/scion-pki_trc_payload_dummy.rst new file mode 100644 index 0000000000..d1398d7b75 --- /dev/null +++ b/doc/command/scion-pki/scion-pki_trc_payload_dummy.rst @@ -0,0 +1,37 @@ +:orphan: + +.. _scion-pki_trc_payload_dummy: + +scion-pki trc payload dummy +--------------------------- + +Generate dummy TRC payload + +Synopsis +~~~~~~~~ + + +'dummy' creates a dummy TRC payload. + +The output of this command can be used to test that you have access to the necessary +cryptographic material. This is especially useful when preparing for a TRC signing +ceremony. + + +:: + + scion-pki trc payload dummy [flags] + +Options +~~~~~~~ + +:: + + --format string Output format (der|pem) (default "pem") + -h, --help help for dummy + +SEE ALSO +~~~~~~~~ + +* :ref:`scion-pki trc payload ` - Generate new TRC payload + diff --git a/doc/command/scion-pki/scion-pki_trc_sign.rst b/doc/command/scion-pki/scion-pki_trc_sign.rst index e1b8e9b121..db160eddb0 100644 --- a/doc/command/scion-pki/scion-pki_trc_sign.rst +++ b/doc/command/scion-pki/scion-pki_trc_sign.rst @@ -23,6 +23,9 @@ naming pattern:: An alternative name can be specified with the \--out flag. +If 'dummy' is provided as the payload file, a dummy TRC payload is signed. This is useful for +testing access to the necessary cryptographic material, especially in preparation for +a TRC signing ceremony. :: diff --git a/scion-pki/trcs/BUILD.bazel b/scion-pki/trcs/BUILD.bazel index 832d1f4090..71af983a4d 100644 --- a/scion-pki/trcs/BUILD.bazel +++ b/scion-pki/trcs/BUILD.bazel @@ -14,6 +14,7 @@ go_library( "trcs.go", "verify.go", ], + embedsrcs = ["testdata/admin/ISD1-B1-S1.pld.der"], importpath = "github.com/scionproto/scion/scion-pki/trcs", visibility = ["//visibility:public"], deps = [ @@ -28,6 +29,7 @@ go_library( "//scion-pki/file:go_default_library", "//scion-pki/key:go_default_library", "@com_github_google_go_cmp//cmp:go_default_library", + "@com_github_mattn_go_isatty//:go_default_library", "@com_github_spf13_cobra//:go_default_library", "@in_gopkg_yaml_v2//:go_default_library", ], diff --git a/scion-pki/trcs/payload.go b/scion-pki/trcs/payload.go index c2ba9fc182..0fa2d7bc9d 100644 --- a/scion-pki/trcs/payload.go +++ b/scion-pki/trcs/payload.go @@ -16,11 +16,13 @@ package trcs import ( "crypto/x509" + _ "embed" "encoding/pem" "fmt" "os" "sort" + "github.com/mattn/go-isatty" "github.com/spf13/cobra" "gopkg.in/yaml.v2" @@ -103,6 +105,49 @@ To inspect the created asn.1 file you can use the openssl tool:: cmd.MarkFlagRequired("template") cmd.Flags().StringVarP(&flags.pred, "predecessor", "p", "", "Predecessor TRC") cmd.Flags().StringVar(&flags.format, "format", "der", "Output format (der|pem)") + + joined := command.Join(pather, cmd) + cmd.AddCommand( + newPayloadDummy(joined), + ) + + return cmd +} + +//go:embed testdata/admin/ISD1-B1-S1.pld.der +var dummyPayload []byte + +func newPayloadDummy(_ command.Pather) *cobra.Command { + var flags struct { + format string + } + + cmd := &cobra.Command{ + Use: "dummy", + Short: "Generate dummy TRC payload", + Long: `'dummy' creates a dummy TRC payload. + +The output of this command can be used to test that you have access to the necessary +cryptographic material. This is especially useful when preparing for a TRC signing +ceremony. +`, + RunE: func(cmd *cobra.Command, args []string) error { + if flags.format == "pem" { + raw := pem.EncodeToMemory(&pem.Block{ + Type: "TRC PAYLOAD", + Bytes: dummyPayload, + }) + _, err := fmt.Fprint(cmd.OutOrStdout(), string(raw)) + return err + } + if isatty.IsTerminal(os.Stdout.Fd()) { + return fmt.Errorf("refusing to write DER encoded bytes to tty") + } + _, err := fmt.Fprint(cmd.OutOrStdout(), string(dummyPayload)) + return err + }, + } + cmd.Flags().StringVar(&flags.format, "format", "pem", "Output format (der|pem)") return cmd } diff --git a/scion-pki/trcs/sign.go b/scion-pki/trcs/sign.go index 9da3246454..a0bb53a9f1 100644 --- a/scion-pki/trcs/sign.go +++ b/scion-pki/trcs/sign.go @@ -59,6 +59,9 @@ naming pattern:: An alternative name can be specified with the \--out flag. +If 'dummy' is provided as the payload file, a dummy TRC payload is signed. This is useful for +testing access to the necessary cryptographic material, especially in preparation for +a TRC signing ceremony. `, Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error { @@ -77,8 +80,15 @@ An alternative name can be specified with the \--out flag. } func RunSign(pld, certfile, keyfile, out, outDir string) error { + dummy := pld == "dummy" + // Read TRC payload - rawPld, err := os.ReadFile(pld) + rawPld, err := func() ([]byte, error) { + if !dummy { + return os.ReadFile(pld) + } + return dummyPayload, nil + }() if err != nil { return serrors.Wrap("error loading payload", err) } @@ -133,7 +143,12 @@ func RunSign(pld, certfile, keyfile, out, outDir string) error { if err := os.WriteFile(fname, signed, 0644); err != nil { return serrors.Wrap("error writing signed TRC paylod", err) } - fmt.Printf("Successfully signed TRC payload at %s\n", out) + + if !dummy { + fmt.Printf("Successfully signed TRC payload at %s\n", out) + } else { + fmt.Println("Successfully signed dummy TRC payload") + } return nil } diff --git a/tools/cryptoplayground/crypto_lib.sh b/tools/cryptoplayground/crypto_lib.sh index 6bdb1e0dd9..de3f7917f9 100644 --- a/tools/cryptoplayground/crypto_lib.sh +++ b/tools/cryptoplayground/crypto_lib.sh @@ -425,6 +425,19 @@ gen_sensitive() { -startdate $STARTDATE -enddate $ENDDATE -preserveDN \ -notext -batch -utf8 -out sensitive-voting.crt # LITERALINCLUDE gen_sensitive END +# LITERALINCLUDE gen_sensitive_dummy START + openssl cms -sign -in dummy.pld.der -inform der \ + -signer $PUBDIR/sensitive-voting.crt \ + -inkey $KEYDIR/sensitive-voting.key \ + -nodetach -nocerts -nosmimecap -binary -outform der \ + > $TRCID.sensitive.dummy.trc + + openssl cms -verify -in $TRCID.sensitive.dummy.trc -inform der \ + -certfile $PUBDIR/sensitive-voting.crt \ + -CAfile $PUBDIR/sensitive-voting.crt \ + -purpose any -no_check_time \ + > /dev/null +# LITERALINCLUDE gen_sensitive_dummy END } gen_sensitive_scion_pki() { @@ -443,6 +456,11 @@ gen_sensitive_scion_pki() { sensitive-voting.crt \ $KEYDIR/sensitive-voting.key # LITERALINCLUDE gen_sensitive_scion_pki END +# LITERALINCLUDE gen_sensitive_scion_pki_dummy START + scion-pki trc sign dummy \ + sensitive-voting.crt \ + $KEYDIR/sensitive-voting.key +# LITERALINCLUDE gen_sensitive_scion_pki_dummy START } @@ -489,6 +507,19 @@ gen_regular() { -startdate $STARTDATE -enddate $ENDDATE -preserveDN \ -notext -batch -utf8 -out regular-voting.crt # LITERALINCLUDE gen_regular END +# LITERALINCLUDE gen_regular_dummy START + openssl cms -sign -in dummy.pld.der -inform der \ + -signer $PUBDIR/regular-voting.crt \ + -inkey $KEYDIR/regular-voting.key \ + -nodetach -nocerts -nosmimecap -binary -outform der \ + > $TRCID.regular.dummy.trc + + openssl cms -verify -in $TRCID.regular.dummy.trc -inform der \ + -certfile $PUBDIR/regular-voting.crt \ + -CAfile $PUBDIR/regular-voting.crt \ + -purpose any -no_check_time \ + > /dev/null +# LITERALINCLUDE gen_regular_dummy END } gen_regular_scion_pki() { @@ -507,6 +538,11 @@ gen_regular_scion_pki() { regular-voting.crt \ $KEYDIR/regular-voting.key # LITERALINCLUDE gen_regular_scion_pki END +# LITERALINCLUDE gen_regular_scion_pki_dummy START + scion-pki trc sign dummy \ + regular-voting.crt \ + $KEYDIR/regular-voting.key +# LITERALINCLUDE gen_regular_scion_pki_dummy START } check_regular() { @@ -552,6 +588,19 @@ gen_root() { -startdate $STARTDATE -enddate $ENDDATE -preserveDN \ -notext -batch -utf8 -out cp-root.crt # LITERALINCLUDE gen_root END +# LITERALINCLUDE gen_root_dummy START + openssl cms -sign -in dummy.pld.der -inform der \ + -signer $PUBDIR/cp-root.crt \ + -inkey $KEYDIR/cp-root.key \ + -nodetach -nocerts -nosmimecap -binary -outform der \ + > $TRCID.root.dummy.trc + + openssl cms -verify -in $TRCID.root.dummy.trc -inform der \ + -certfile $PUBDIR/cp-root.crt \ + -CAfile $PUBDIR/cp-root.crt \ + -purpose any -no_check_time \ + > /dev/null +# LITERALINCLUDE gen_root_dummy END } @@ -571,6 +620,11 @@ gen_root_scion_pki() { cp-root.crt \ $KEYDIR/cp-root.key # LITERALINCLUDE gen_root_scion_pki END +# LITERALINCLUDE gen_root_scion_pki_dummy START + scion-pki trc sign dummy \ + cp-root.crt \ + $KEYDIR/cp-root.key +# LITERALINCLUDE gen_root_scion_pki_dummy START } check_root() { diff --git a/tools/cryptoplayground/trc_ceremony.sh b/tools/cryptoplayground/trc_ceremony.sh index 7405ba550f..7d3e8bd265 100755 --- a/tools/cryptoplayground/trc_ceremony.sh +++ b/tools/cryptoplayground/trc_ceremony.sh @@ -45,6 +45,7 @@ do if [ -z "$USE_SCION_PKI_SIGN" ]; then basic_conf && sensitive_conf && regular_conf && root_conf && ca_conf && as_conf + scion-pki trc payload dummy --format der > dummy.pld.der prepare_ca sed -i \ -e 's/{{.Country}}/CH/g' \ From 296ec950093cf86e194b919132f65888e0c987c7 Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Wed, 18 Sep 2024 22:53:35 +0200 Subject: [PATCH 25/29] scion-pki: allow referencing predecessor certificates in payload (#4625) When creating a TRC update, support referencing the predecessor certificates. This simplifies the TRC ceremony, as the already included certificates do not need to be redistributed in case they do not change. --- scion-pki/conf/trc.go | 20 +++++++++++++++++++- scion-pki/conf/trc_test.go | 12 +++++++++++- scion-pki/testcrypto/testcrypto.go | 2 +- scion-pki/trcs/payload.go | 2 +- scion-pki/trcs/toasn.go | 4 ++-- scion-pki/trcs/toasn_test.go | 2 +- 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/scion-pki/conf/trc.go b/scion-pki/conf/trc.go index dd059f2550..647d234f17 100644 --- a/scion-pki/conf/trc.go +++ b/scion-pki/conf/trc.go @@ -17,6 +17,7 @@ package conf import ( "crypto/x509" "path/filepath" + "strconv" "strings" "github.com/scionproto/scion/pkg/addr" @@ -59,12 +60,29 @@ func LoadTRC(file string) (TRC, error) { } // Certificates returns the specified certificates. -func (cfg *TRC) Certificates() ([]*x509.Certificate, error) { +func (cfg *TRC) Certificates(pred *cppki.TRC) ([]*x509.Certificate, error) { if len(cfg.CertificateFiles) == 0 { return nil, serrors.New("no cert_files specified") } + certs := make([]*x509.Certificate, 0, len(cfg.CertificateFiles)) for _, certFile := range cfg.CertificateFiles { + + if raw, ok := strings.CutPrefix(certFile, "predecessor:"); ok { + if pred == nil { + return nil, serrors.New("predecessor certificate requested on base TRC") + } + idx, err := strconv.Atoi(raw) + if err != nil { + return nil, serrors.Wrap("parsing predecessor index", err, "input", raw) + } + if idx < 0 || idx >= len(pred.Certificates) { + return nil, serrors.New("predecessor index out of bounds", "index", idx) + } + certs = append(certs, pred.Certificates[idx]) + continue + } + if !strings.HasPrefix(certFile, "/") { certFile = filepath.Join(cfg.relPath, certFile) } diff --git a/scion-pki/conf/trc_test.go b/scion-pki/conf/trc_test.go index 6af098ee08..1055239b08 100644 --- a/scion-pki/conf/trc_test.go +++ b/scion-pki/conf/trc_test.go @@ -114,11 +114,21 @@ func TestTRCCertificates(t *testing.T) { prepareCfg func(*conf.TRC) errMsg string expectedCrts []*x509.Certificate + pred *cppki.TRC }{ "valid": { prepareCfg: func(_ *conf.TRC) {}, expectedCrts: []*x509.Certificate{rVoting, sVoting}, }, + "load from predecessor": { + prepareCfg: func(cfg *conf.TRC) { + cfg.CertificateFiles[0] = "predecessor:4" + }, + expectedCrts: []*x509.Certificate{rVoting, sVoting}, + pred: &cppki.TRC{ + Certificates: []*x509.Certificate{4: rVoting}, + }, + }, "file not found": { prepareCfg: func(cfg *conf.TRC) { cfg.CertificateFiles = []string{"notfound"} }, errMsg: "no such file or directory", @@ -128,7 +138,7 @@ func TestTRCCertificates(t *testing.T) { t.Run(name, func(t *testing.T) { cfg := createTRC(t) tc.prepareCfg(cfg) - crts, err := cfg.Certificates() + crts, err := cfg.Certificates(tc.pred) if tc.errMsg != "" { assert.Error(t, err) assert.Contains(t, err.Error(), tc.errMsg) diff --git a/scion-pki/testcrypto/testcrypto.go b/scion-pki/testcrypto/testcrypto.go index 0a819333fe..a641ee813a 100644 --- a/scion-pki/testcrypto/testcrypto.go +++ b/scion-pki/testcrypto/testcrypto.go @@ -321,7 +321,7 @@ func createTRCs(cfg config) error { CertificateFiles: certFiles[isd], } sort.Strings(trcConf.CertificateFiles) - trc, err := trcs.CreatePayload(trcConf) + trc, err := trcs.CreatePayload(trcConf, nil) if err != nil { return serrors.Wrap("creating TRC payload", err, "isd", isd) } diff --git a/scion-pki/trcs/payload.go b/scion-pki/trcs/payload.go index 0fa2d7bc9d..056bcec422 100644 --- a/scion-pki/trcs/payload.go +++ b/scion-pki/trcs/payload.go @@ -70,7 +70,7 @@ To inspect the created asn.1 file you can use the openssl tool:: return err } prepareCfg(&cfg, pred) - trc, err := CreatePayload(cfg) + trc, err := CreatePayload(cfg, pred) if err != nil { return serrors.Wrap("failed to marshal TRC", err) } diff --git a/scion-pki/trcs/toasn.go b/scion-pki/trcs/toasn.go index d563f4ee59..3051e14515 100644 --- a/scion-pki/trcs/toasn.go +++ b/scion-pki/trcs/toasn.go @@ -23,8 +23,8 @@ import ( // CreatePayload creates the ASN.1 payload for the TRC from the given // configuration. -func CreatePayload(cfg conf.TRC) (*cppki.TRC, error) { - certs, err := cfg.Certificates() +func CreatePayload(cfg conf.TRC, pred *cppki.TRC) (*cppki.TRC, error) { + certs, err := cfg.Certificates(pred) if err != nil { return nil, err } diff --git a/scion-pki/trcs/toasn_test.go b/scion-pki/trcs/toasn_test.go index c12be71597..b245d4844a 100644 --- a/scion-pki/trcs/toasn_test.go +++ b/scion-pki/trcs/toasn_test.go @@ -27,7 +27,7 @@ import ( func TestMarshalPayload(t *testing.T) { cfg, err := conf.LoadTRC("testdata/admin/ISD1-B1-S1.toml") require.NoError(t, err) - trc, err := CreatePayload(cfg) + trc, err := CreatePayload(cfg, nil) require.NoError(t, err) raw, err := trc.Encode() require.NoError(t, err) From 20bba9f0c897db65f44172eae2c22bcc9a3528ae Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:05:01 +0200 Subject: [PATCH 26/29] test: await-connectivity is too optimistic (#4622) Found this in the wake of #4606 I believe that await-connectivity could mistake core segments for up segments (i.e. assuming that only up segments could be found). It still makes the optimistic assumption that down segments are registered immediately after up segments are obtained. We have to be content with that because in hidden paths test cases the down segments cannot all be found via a simple REST API query. --- tools/await-connectivity | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/await-connectivity b/tools/await-connectivity index 9438ffeaf2..8f8b7610b2 100755 --- a/tools/await-connectivity +++ b/tools/await-connectivity @@ -69,12 +69,13 @@ check_connectivity() { fi done - # non-core ASes: wait for at least one (up-)segment + # non-core ASes: wait for at least one up-segment. for as in $noncores; do - curl --connect-timeout 5 -sfS $(cs_api_url_segments "$as") | jq -e 'length > 0' > /dev/null || { - echo "$as waiting for up segment" - ret=1 - } + tops=$(curl --connect-timeout 5 -sfS $(cs_api_url_segments "$as") | jq -r '.[] | select(.end_isd_as =="'${as}'")') + if [ -z "$tops" ]; then + echo "$as: Waiting for Upsegs" + ret=1 + fi done return $ret } From 59c70dcadeed44a3b9acdc5c8a655cf256974987 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Thu, 19 Sep 2024 11:53:43 +0200 Subject: [PATCH 27/29] pkg/private/common: move IfIDType out of private/common and to its own package (#4604) Also renamed IfIDType to ID. Given that ID represents generic interface IDs as used in segments distributed by the control service, it seems that it shouldn't be private either, even if it currently can be. So the new package isn't private. Fixes #4584 --- control/beacon/beacondbtest/BUILD.bazel | 2 +- control/beacon/beacondbtest/beacondbtest.go | 8 +- control/beaconing/BUILD.bazel | 4 +- control/beaconing/export_test.go | 6 +- control/beaconing/staticinfo_config.go | 80 +++++------ control/beaconing/staticinfo_config_test.go | 136 +++++++++--------- control/beaconing/writer_test.go | 4 +- control/cmd/control/BUILD.bazel | 2 +- control/cmd/control/main.go | 4 +- daemon/internal/servers/BUILD.bazel | 2 +- daemon/internal/servers/grpc.go | 4 +- gateway/pathhealth/BUILD.bazel | 2 +- gateway/pathhealth/revocations_test.go | 6 +- pkg/daemon/BUILD.bazel | 2 +- pkg/daemon/grpc.go | 4 +- pkg/experimental/hiddenpath/BUILD.bazel | 2 +- .../hiddenpath/beaconwriter_test.go | 4 +- pkg/private/common/BUILD.bazel | 5 +- pkg/private/common/defs.go | 31 +--- pkg/private/common/defs_test.go | 29 ---- pkg/private/ctrl/path_mgmt/BUILD.bazel | 2 +- pkg/private/ctrl/path_mgmt/rev_info.go | 4 +- pkg/private/xtest/graph/BUILD.bazel | 2 +- pkg/private/xtest/graph/graph.go | 28 ++-- pkg/segment/extensions/staticinfo/BUILD.bazel | 4 +- .../extensions/staticinfo/staticinfo.go | 38 ++--- .../extensions/staticinfo/staticinfo_test.go | 12 +- pkg/segment/iface/BUILD.bazel | 18 +++ pkg/segment/iface/iface.go | 45 ++++++ pkg/segment/iface/iface_test.go | 52 +++++++ pkg/snet/BUILD.bazel | 1 + pkg/snet/path.go | 4 +- pkg/snet/scmp.go | 6 +- private/path/combinator/BUILD.bazel | 4 +- private/path/combinator/combinator_test.go | 22 +-- private/path/combinator/graph.go | 18 +-- .../path/combinator/staticinfo_accumulator.go | 8 +- .../combinator/staticinfo_accumulator_test.go | 46 +++--- private/path/pathpol/BUILD.bazel | 4 +- private/path/pathpol/acl_test.go | 10 +- private/path/pathpol/hop_pred.go | 12 +- private/path/pathpol/hop_pred_test.go | 26 ++-- private/path/pathpol/policy_test.go | 4 +- private/path/pathpol/sequence.go | 4 +- private/pathdb/query/BUILD.bazel | 2 +- private/pathdb/query/query.go | 4 +- private/revcache/BUILD.bazel | 4 +- private/revcache/revcache.go | 6 +- private/revcache/revcachetest/BUILD.bazel | 2 +- private/revcache/revcachetest/revcachetest.go | 12 +- private/revcache/util.go | 6 +- private/revcache/util_test.go | 7 +- private/segment/segfetcher/BUILD.bazel | 2 +- private/segment/segfetcher/resolver_test.go | 8 +- private/storage/beacon/sqlite/BUILD.bazel | 2 +- private/storage/beacon/sqlite/db.go | 4 +- private/storage/path/dbtest/BUILD.bazel | 2 +- private/storage/path/dbtest/dbtest.go | 4 +- private/topology/BUILD.bazel | 4 +- private/topology/interface.go | 12 +- private/topology/json/BUILD.bazel | 4 +- private/topology/json/json.go | 18 +-- private/topology/json/json_test.go | 6 +- private/topology/mock_topology/BUILD.bazel | 2 +- private/topology/mock_topology/mock.go | 8 +- private/topology/reload.go | 6 +- private/topology/topology.go | 18 +-- private/topology/topology_test.go | 12 +- router/BUILD.bazel | 2 +- router/connector.go | 4 +- router/control/BUILD.bazel | 2 +- router/control/conf.go | 8 +- router/control/internal/metrics/BUILD.bazel | 2 +- router/control/internal/metrics/metrics.go | 4 +- scion/cmd/scion/BUILD.bazel | 2 +- scion/cmd/scion/common.go | 6 +- scion/showpaths/BUILD.bazel | 2 +- scion/showpaths/showpaths.go | 6 +- 78 files changed, 480 insertions(+), 424 deletions(-) create mode 100644 pkg/segment/iface/BUILD.bazel create mode 100644 pkg/segment/iface/iface.go create mode 100644 pkg/segment/iface/iface_test.go diff --git a/control/beacon/beacondbtest/BUILD.bazel b/control/beacon/beacondbtest/BUILD.bazel index 602bd3962c..9190dcf17a 100644 --- a/control/beacon/beacondbtest/BUILD.bazel +++ b/control/beacon/beacondbtest/BUILD.bazel @@ -8,9 +8,9 @@ go_library( deps = [ "//control/beacon:go_default_library", "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/xtest/graph:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", "@com_github_stretchr_testify//require:go_default_library", diff --git a/control/beacon/beacondbtest/beacondbtest.go b/control/beacon/beacondbtest/beacondbtest.go index 4b3af82017..32e379b7ca 100644 --- a/control/beacon/beacondbtest/beacondbtest.go +++ b/control/beacon/beacondbtest/beacondbtest.go @@ -24,9 +24,9 @@ import ( "github.com/scionproto/scion/control/beacon" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/xtest/graph" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers/path" ) @@ -334,14 +334,14 @@ func InsertBeacon(t *testing.T, db beacon.DB, ases []IfInfo, type PeerEntry struct { IA addr.IA - Ingress common.IfIDType + Ingress iface.ID } type IfInfo struct { IA addr.IA Next addr.IA - Ingress common.IfIDType - Egress common.IfIDType + Ingress iface.ID + Egress iface.ID Peers []PeerEntry } diff --git a/control/beaconing/BUILD.bazel b/control/beaconing/BUILD.bazel index 2cae4b8238..5076ce08a4 100644 --- a/control/beaconing/BUILD.bazel +++ b/control/beaconing/BUILD.bazel @@ -21,7 +21,6 @@ go_library( "//pkg/addr:go_default_library", "//pkg/log:go_default_library", "//pkg/metrics:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/prom:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", @@ -31,6 +30,7 @@ go_library( "//pkg/segment/extensions/digest:go_default_library", "//pkg/segment/extensions/epic:go_default_library", "//pkg/segment/extensions/staticinfo:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "//pkg/snet:go_default_library", "//private/periodic:go_default_library", @@ -62,7 +62,6 @@ go_test( "//control/beaconing/mock_beaconing:go_default_library", "//control/ifstate:go_default_library", "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", "//pkg/private/xtest/graph:go_default_library", @@ -72,6 +71,7 @@ go_test( "//pkg/scrypto/signed:go_default_library", "//pkg/segment:go_default_library", "//pkg/segment/extensions/staticinfo:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "//pkg/slayers/path/scion:go_default_library", "//pkg/snet:go_default_library", diff --git a/control/beaconing/export_test.go b/control/beaconing/export_test.go index 76db29854c..12b0c76e8f 100644 --- a/control/beaconing/export_test.go +++ b/control/beaconing/export_test.go @@ -15,12 +15,12 @@ package beaconing import ( - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/segment/extensions/staticinfo" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/topology" ) -func (cfg StaticInfoCfg) TestGenerate(ifType map[common.IfIDType]topology.LinkType, - ingress, egress common.IfIDType) *staticinfo.Extension { +func (cfg StaticInfoCfg) TestGenerate(ifType map[iface.ID]topology.LinkType, + ingress, egress iface.ID) *staticinfo.Extension { return cfg.generate(ifType, ingress, egress) } diff --git a/control/beaconing/staticinfo_config.go b/control/beaconing/staticinfo_config.go index 34e485ad8a..fab14eb9ca 100644 --- a/control/beaconing/staticinfo_config.go +++ b/control/beaconing/staticinfo_config.go @@ -21,21 +21,21 @@ import ( "time" "github.com/scionproto/scion/control/ifstate" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/segment/extensions/staticinfo" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/topology" ) type InterfaceLatencies struct { - Inter util.DurWrap `json:"Inter"` - Intra map[common.IfIDType]util.DurWrap `json:"Intra"` + Inter util.DurWrap `json:"Inter"` + Intra map[iface.ID]util.DurWrap `json:"Intra"` } type InterfaceBandwidths struct { - Inter uint64 `json:"Inter"` - Intra map[common.IfIDType]uint64 `json:"Intra"` + Inter uint64 `json:"Inter"` + Intra map[iface.ID]uint64 `json:"Intra"` } type InterfaceGeodata struct { @@ -45,7 +45,7 @@ type InterfaceGeodata struct { } type InterfaceHops struct { - Intra map[common.IfIDType]uint32 `json:"Intra"` + Intra map[iface.ID]uint32 `json:"Intra"` } type LinkType staticinfo.LinkType @@ -79,12 +79,12 @@ func (l *LinkType) UnmarshalText(text []byte) error { // StaticInfoCfg is used to parse data from config.json. type StaticInfoCfg struct { - Latency map[common.IfIDType]InterfaceLatencies `json:"Latency"` - Bandwidth map[common.IfIDType]InterfaceBandwidths `json:"Bandwidth"` - LinkType map[common.IfIDType]LinkType `json:"LinkType"` - Geo map[common.IfIDType]InterfaceGeodata `json:"Geo"` - Hops map[common.IfIDType]InterfaceHops `json:"Hops"` - Note string `json:"Note"` + Latency map[iface.ID]InterfaceLatencies `json:"Latency"` + Bandwidth map[iface.ID]InterfaceBandwidths `json:"Bandwidth"` + LinkType map[iface.ID]LinkType `json:"LinkType"` + Geo map[iface.ID]InterfaceGeodata `json:"Geo"` + Hops map[iface.ID]InterfaceHops `json:"Hops"` + Note string `json:"Note"` } // ParseStaticInfoCfg parses data from a config file into a StaticInfoCfg struct. @@ -135,7 +135,7 @@ func (cfg *StaticInfoCfg) clean() { } // symmetrizeLatency makes the Intra latency values symmetric -func symmetrizeLatency(latency map[common.IfIDType]InterfaceLatencies) { +func symmetrizeLatency(latency map[iface.ID]InterfaceLatencies) { for i, sub := range latency { delete(sub.Intra, i) // Remove loopy entry for j, v := range sub.Intra { @@ -145,7 +145,7 @@ func symmetrizeLatency(latency map[common.IfIDType]InterfaceLatencies) { if latency[j].Intra == nil { latency[j] = InterfaceLatencies{ Inter: latency[j].Inter, - Intra: make(map[common.IfIDType]util.DurWrap), + Intra: make(map[iface.ID]util.DurWrap), } } vTransposed, ok := latency[j].Intra[i] @@ -158,7 +158,7 @@ func symmetrizeLatency(latency map[common.IfIDType]InterfaceLatencies) { } // symmetrizeBandwidth makes the Intra bandwidth values symmetric -func symmetrizeBandwidth(bandwidth map[common.IfIDType]InterfaceBandwidths) { +func symmetrizeBandwidth(bandwidth map[iface.ID]InterfaceBandwidths) { for i, sub := range bandwidth { delete(sub.Intra, i) // Remove loopy entry for j, v := range sub.Intra { @@ -168,7 +168,7 @@ func symmetrizeBandwidth(bandwidth map[common.IfIDType]InterfaceBandwidths) { if bandwidth[j].Intra == nil { bandwidth[j] = InterfaceBandwidths{ Inter: bandwidth[j].Inter, - Intra: make(map[common.IfIDType]uint64), + Intra: make(map[iface.ID]uint64), } } vTransposed, ok := bandwidth[j].Intra[i] @@ -181,13 +181,13 @@ func symmetrizeBandwidth(bandwidth map[common.IfIDType]InterfaceBandwidths) { } // symmetrizeHops makes the Intra hops values symmetric -func symmetrizeHops(hops map[common.IfIDType]InterfaceHops) { +func symmetrizeHops(hops map[iface.ID]InterfaceHops) { for i, sub := range hops { delete(sub.Intra, i) // Remove loopy entry for j, v := range sub.Intra { if _, ok := hops[j]; !ok { hops[j] = InterfaceHops{ - Intra: make(map[common.IfIDType]uint32), + Intra: make(map[iface.ID]uint32), } } vTransposed, ok := hops[j].Intra[i] @@ -205,11 +205,11 @@ func (cfg StaticInfoCfg) Generate(intfs *ifstate.Interfaces, ingress, egress uint16) *staticinfo.Extension { ifType := interfaceTypeTable(intfs) - return cfg.generate(ifType, common.IfIDType(ingress), common.IfIDType(egress)) + return cfg.generate(ifType, iface.ID(ingress), iface.ID(egress)) } -func (cfg StaticInfoCfg) generate(ifType map[common.IfIDType]topology.LinkType, - ingress, egress common.IfIDType) *staticinfo.Extension { +func (cfg StaticInfoCfg) generate(ifType map[iface.ID]topology.LinkType, + ingress, egress iface.ID) *staticinfo.Extension { return &staticinfo.Extension{ Latency: cfg.generateLatency(ifType, ingress, egress), @@ -223,12 +223,12 @@ func (cfg StaticInfoCfg) generate(ifType map[common.IfIDType]topology.LinkType, // generateLatency creates the LatencyInfo by extracting the relevant values from // the config. -func (cfg StaticInfoCfg) generateLatency(ifType map[common.IfIDType]topology.LinkType, - ingress, egress common.IfIDType) staticinfo.LatencyInfo { +func (cfg StaticInfoCfg) generateLatency(ifType map[iface.ID]topology.LinkType, + ingress, egress iface.ID) staticinfo.LatencyInfo { l := staticinfo.LatencyInfo{ - Intra: make(map[common.IfIDType]time.Duration), - Inter: make(map[common.IfIDType]time.Duration), + Intra: make(map[iface.ID]time.Duration), + Inter: make(map[iface.ID]time.Duration), } for ifID, v := range cfg.Latency[egress].Intra { if includeIntraInfo(ifType, ifID, ingress, egress) { @@ -246,12 +246,12 @@ func (cfg StaticInfoCfg) generateLatency(ifType map[common.IfIDType]topology.Lin // generateBandwidth creates the BandwidthInfo by extracting the relevant values // from the config. -func (cfg StaticInfoCfg) generateBandwidth(ifType map[common.IfIDType]topology.LinkType, - ingress, egress common.IfIDType) staticinfo.BandwidthInfo { +func (cfg StaticInfoCfg) generateBandwidth(ifType map[iface.ID]topology.LinkType, + ingress, egress iface.ID) staticinfo.BandwidthInfo { bw := staticinfo.BandwidthInfo{ - Intra: make(map[common.IfIDType]uint64), - Inter: make(map[common.IfIDType]uint64), + Intra: make(map[iface.ID]uint64), + Inter: make(map[iface.ID]uint64), } for ifID, v := range cfg.Bandwidth[egress].Intra { if includeIntraInfo(ifType, ifID, ingress, egress) { @@ -269,8 +269,8 @@ func (cfg StaticInfoCfg) generateBandwidth(ifType map[common.IfIDType]topology.L // generateLinkType creates the LinkTypeInfo by extracting the relevant values from // the config. -func (cfg StaticInfoCfg) generateLinkType(ifType map[common.IfIDType]topology.LinkType, - egress common.IfIDType) staticinfo.LinkTypeInfo { +func (cfg StaticInfoCfg) generateLinkType(ifType map[iface.ID]topology.LinkType, + egress iface.ID) staticinfo.LinkTypeInfo { lt := make(staticinfo.LinkTypeInfo) for ifID, intfLT := range cfg.LinkType { @@ -284,8 +284,8 @@ func (cfg StaticInfoCfg) generateLinkType(ifType map[common.IfIDType]topology.Li // generateInternalHops creates the InternalHopsInfo by extracting the relevant // values from the config. -func (cfg StaticInfoCfg) generateInternalHops(ifType map[common.IfIDType]topology.LinkType, - ingress, egress common.IfIDType) staticinfo.InternalHopsInfo { +func (cfg StaticInfoCfg) generateInternalHops(ifType map[iface.ID]topology.LinkType, + ingress, egress iface.ID) staticinfo.InternalHopsInfo { ihi := make(staticinfo.InternalHopsInfo) for ifID, v := range cfg.Hops[egress].Intra { @@ -298,8 +298,8 @@ func (cfg StaticInfoCfg) generateInternalHops(ifType map[common.IfIDType]topolog // generateGeo creates the GeoInfo by extracting the relevant values from // the config. -func (cfg StaticInfoCfg) generateGeo(ifType map[common.IfIDType]topology.LinkType, - ingress, egress common.IfIDType) staticinfo.GeoInfo { +func (cfg StaticInfoCfg) generateGeo(ifType map[iface.ID]topology.LinkType, + ingress, egress iface.ID) staticinfo.GeoInfo { gi := staticinfo.GeoInfo{} for ifID, loc := range cfg.Geo { @@ -331,8 +331,8 @@ func (cfg StaticInfoCfg) generateGeo(ifType map[common.IfIDType]topology.LinkTyp // AS needs to pick one consistently (or decide to just include the full // information all the time), otherwise information for cross-overs may // be missing. -func includeIntraInfo(ifType map[common.IfIDType]topology.LinkType, - ifID, ingress, egress common.IfIDType) bool { +func includeIntraInfo(ifType map[iface.ID]topology.LinkType, + ifID, ingress, egress iface.ID) bool { isCoreIngress := (ifType[ingress] == topology.Core || ingress == 0) isCoreEgress := (ifType[egress] == topology.Core || egress == 0) @@ -347,11 +347,11 @@ func includeIntraInfo(ifType map[common.IfIDType]topology.LinkType, t == topology.Peer } -func interfaceTypeTable(intfs *ifstate.Interfaces) map[common.IfIDType]topology.LinkType { +func interfaceTypeTable(intfs *ifstate.Interfaces) map[iface.ID]topology.LinkType { ifMap := intfs.All() - ifTypes := make(map[common.IfIDType]topology.LinkType, len(ifMap)) + ifTypes := make(map[iface.ID]topology.LinkType, len(ifMap)) for ifID, ifInfo := range ifMap { - ifTypes[common.IfIDType(ifID)] = ifInfo.TopoInfo().LinkType + ifTypes[iface.ID(ifID)] = ifInfo.TopoInfo().LinkType } return ifTypes } diff --git a/control/beaconing/staticinfo_config_test.go b/control/beaconing/staticinfo_config_test.go index 50dc57f9a1..a95775a097 100644 --- a/control/beaconing/staticinfo_config_test.go +++ b/control/beaconing/staticinfo_config_test.go @@ -21,9 +21,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/scionproto/scion/control/beaconing" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/segment/extensions/staticinfo" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/topology" ) @@ -95,10 +95,10 @@ func getTestConfigData() *beaconing.StaticInfoCfg { } return &beaconing.StaticInfoCfg{ - Latency: map[common.IfIDType]beaconing.InterfaceLatencies{ + Latency: map[iface.ID]beaconing.InterfaceLatencies{ 1: { Inter: w(latency_inter_1), - Intra: map[common.IfIDType]util.DurWrap{ + Intra: map[iface.ID]util.DurWrap{ 2: w(latency_intra_1_2), 3: w(latency_intra_1_3), 5: w(latency_intra_1_5), @@ -106,7 +106,7 @@ func getTestConfigData() *beaconing.StaticInfoCfg { }, 2: { Inter: w(latency_inter_2), - Intra: map[common.IfIDType]util.DurWrap{ + Intra: map[iface.ID]util.DurWrap{ 1: w(latency_intra_1_2), 3: w(latency_intra_2_3), 5: w(latency_intra_2_5), @@ -114,7 +114,7 @@ func getTestConfigData() *beaconing.StaticInfoCfg { }, 3: { Inter: w(latency_inter_3), - Intra: map[common.IfIDType]util.DurWrap{ + Intra: map[iface.ID]util.DurWrap{ 1: w(latency_intra_1_3), 2: w(latency_intra_2_3), 5: w(latency_intra_3_5), @@ -122,17 +122,17 @@ func getTestConfigData() *beaconing.StaticInfoCfg { }, 5: { Inter: w(latency_inter_5), - Intra: map[common.IfIDType]util.DurWrap{ + Intra: map[iface.ID]util.DurWrap{ 1: w(latency_intra_1_5), 2: w(latency_intra_2_5), 3: w(latency_intra_3_5), }, }, }, - Bandwidth: map[common.IfIDType]beaconing.InterfaceBandwidths{ + Bandwidth: map[iface.ID]beaconing.InterfaceBandwidths{ 1: { Inter: bandwidth_inter_1, - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 2: bandwidth_intra_1_2, 3: bandwidth_intra_1_3, 5: bandwidth_intra_1_5, @@ -140,7 +140,7 @@ func getTestConfigData() *beaconing.StaticInfoCfg { }, 2: { Inter: bandwidth_inter_2, - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 1: bandwidth_intra_1_2, 3: bandwidth_intra_2_3, 5: bandwidth_intra_2_5, @@ -148,7 +148,7 @@ func getTestConfigData() *beaconing.StaticInfoCfg { }, 3: { Inter: bandwidth_inter_3, - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 1: bandwidth_intra_1_3, 2: bandwidth_intra_2_3, 5: bandwidth_intra_3_5, @@ -156,49 +156,49 @@ func getTestConfigData() *beaconing.StaticInfoCfg { }, 5: { Inter: bandwidth_inter_5, - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 1: bandwidth_intra_1_5, 2: bandwidth_intra_2_5, 3: bandwidth_intra_3_5, }, }, }, - LinkType: map[common.IfIDType]beaconing.LinkType{ + LinkType: map[iface.ID]beaconing.LinkType{ 1: beaconing.LinkType(link_type_1), 2: beaconing.LinkType(link_type_2), 3: beaconing.LinkType(link_type_3), 5: beaconing.LinkType(link_type_5), }, - Geo: map[common.IfIDType]beaconing.InterfaceGeodata{ + Geo: map[iface.ID]beaconing.InterfaceGeodata{ 1: {geo_1.Longitude, geo_1.Latitude, geo_1.Address}, 2: {geo_2.Longitude, geo_2.Latitude, geo_2.Address}, 3: {geo_3.Longitude, geo_3.Latitude, geo_3.Address}, 5: {geo_5.Longitude, geo_5.Latitude, geo_5.Address}, }, - Hops: map[common.IfIDType]beaconing.InterfaceHops{ + Hops: map[iface.ID]beaconing.InterfaceHops{ 1: { - Intra: map[common.IfIDType]uint32{ + Intra: map[iface.ID]uint32{ 2: hops_intra_1_2, 3: hops_intra_1_3, 5: hops_intra_1_5, }, }, 2: { - Intra: map[common.IfIDType]uint32{ + Intra: map[iface.ID]uint32{ 1: hops_intra_1_2, 3: hops_intra_2_3, 5: hops_intra_2_5, }, }, 3: { - Intra: map[common.IfIDType]uint32{ + Intra: map[iface.ID]uint32{ 1: hops_intra_1_3, 2: hops_intra_2_3, 5: hops_intra_3_5, }, }, 5: { - Intra: map[common.IfIDType]uint32{ + Intra: map[iface.ID]uint32{ 1: hops_intra_1_5, 2: hops_intra_2_5, 3: hops_intra_3_5, @@ -221,14 +221,14 @@ func TestGenerateStaticInfo(t *testing.T) { cfg := getTestConfigData() // "topology" information for a non-core AS: - ifTypeNoncore := map[common.IfIDType]topology.LinkType{ + ifTypeNoncore := map[iface.ID]topology.LinkType{ 1: topology.Child, 2: topology.Child, 3: topology.Parent, 5: topology.Peer, } // "topology" information for a core AS: - ifTypeCore := map[common.IfIDType]topology.LinkType{ + ifTypeCore := map[iface.ID]topology.LinkType{ 1: topology.Core, 2: topology.Child, 3: topology.Core, @@ -237,9 +237,9 @@ func TestGenerateStaticInfo(t *testing.T) { testCases := []struct { name string - ingress common.IfIDType - egress common.IfIDType - ifType map[common.IfIDType]topology.LinkType + ingress iface.ID + egress iface.ID + ifType map[iface.ID]topology.LinkType expected staticinfo.Extension }{ { @@ -249,23 +249,23 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeNoncore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{ 2: latency_intra_1_2, 3: latency_intra_1_3, 5: latency_intra_1_5, }, - Inter: map[common.IfIDType]time.Duration{ + Inter: map[iface.ID]time.Duration{ 1: latency_inter_1, 5: latency_inter_5, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 2: bandwidth_intra_1_2, 3: bandwidth_intra_1_3, 5: bandwidth_intra_1_5, }, - Inter: map[common.IfIDType]uint64{ + Inter: map[iface.ID]uint64{ 1: bandwidth_inter_1, 5: bandwidth_inter_5, }, @@ -279,7 +279,7 @@ func TestGenerateStaticInfo(t *testing.T) { 1: link_type_1, 5: link_type_5, }, - InternalHops: map[common.IfIDType]uint32{ + InternalHops: map[iface.ID]uint32{ 2: hops_intra_1_2, 3: hops_intra_1_3, 5: hops_intra_1_5, @@ -294,21 +294,21 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeNoncore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{ 3: latency_intra_2_3, 5: latency_intra_2_5, }, - Inter: map[common.IfIDType]time.Duration{ + Inter: map[iface.ID]time.Duration{ 2: latency_inter_2, 5: latency_inter_5, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 3: bandwidth_intra_2_3, 5: bandwidth_intra_2_5, }, - Inter: map[common.IfIDType]uint64{ + Inter: map[iface.ID]uint64{ 2: bandwidth_inter_2, 5: bandwidth_inter_5, }, @@ -322,7 +322,7 @@ func TestGenerateStaticInfo(t *testing.T) { 2: link_type_2, 5: link_type_5, }, - InternalHops: map[common.IfIDType]uint32{ + InternalHops: map[iface.ID]uint32{ 3: hops_intra_2_3, 5: hops_intra_2_5, }, @@ -336,14 +336,14 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeNoncore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{}, - Inter: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{}, + Inter: map[iface.ID]time.Duration{ 5: latency_inter_5, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{}, - Inter: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{}, + Inter: map[iface.ID]uint64{ 5: bandwidth_inter_5, }, }, @@ -354,7 +354,7 @@ func TestGenerateStaticInfo(t *testing.T) { LinkType: staticinfo.LinkTypeInfo{ 5: link_type_5, }, - InternalHops: map[common.IfIDType]uint32{}, + InternalHops: map[iface.ID]uint32{}, Note: note, }, }, @@ -365,21 +365,21 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeNoncore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{ 2: latency_intra_1_2, 5: latency_intra_1_5, }, - Inter: map[common.IfIDType]time.Duration{ + Inter: map[iface.ID]time.Duration{ 1: latency_inter_1, 5: latency_inter_5, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 2: bandwidth_intra_1_2, 5: bandwidth_intra_1_5, }, - Inter: map[common.IfIDType]uint64{ + Inter: map[iface.ID]uint64{ 1: bandwidth_inter_1, 5: bandwidth_inter_5, }, @@ -392,7 +392,7 @@ func TestGenerateStaticInfo(t *testing.T) { 1: link_type_1, 5: link_type_5, }, - InternalHops: map[common.IfIDType]uint32{ + InternalHops: map[iface.ID]uint32{ 2: hops_intra_1_2, 5: hops_intra_1_5, }, @@ -406,19 +406,19 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeNoncore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{ 5: latency_intra_2_5, }, - Inter: map[common.IfIDType]time.Duration{ + Inter: map[iface.ID]time.Duration{ 2: latency_inter_2, 5: latency_inter_5, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 5: bandwidth_intra_2_5, }, - Inter: map[common.IfIDType]uint64{ + Inter: map[iface.ID]uint64{ 2: bandwidth_inter_2, 5: bandwidth_inter_5, }, @@ -431,7 +431,7 @@ func TestGenerateStaticInfo(t *testing.T) { 2: link_type_2, 5: link_type_5, }, - InternalHops: map[common.IfIDType]uint32{ + InternalHops: map[iface.ID]uint32{ 5: hops_intra_2_5, }, Note: note, @@ -444,22 +444,22 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeCore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{ 1: latency_intra_1_2, 3: latency_intra_2_3, 5: latency_intra_2_5, }, - Inter: map[common.IfIDType]time.Duration{ + Inter: map[iface.ID]time.Duration{ 2: latency_inter_2, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 1: bandwidth_intra_1_2, 3: bandwidth_intra_2_3, 5: bandwidth_intra_2_5, }, - Inter: map[common.IfIDType]uint64{ + Inter: map[iface.ID]uint64{ 2: bandwidth_inter_2, }, }, @@ -469,7 +469,7 @@ func TestGenerateStaticInfo(t *testing.T) { LinkType: staticinfo.LinkTypeInfo{ 2: link_type_2, }, - InternalHops: map[common.IfIDType]uint32{ + InternalHops: map[iface.ID]uint32{ 1: hops_intra_1_2, 3: hops_intra_2_3, 5: hops_intra_2_5, @@ -484,14 +484,14 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeCore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{}, - Inter: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{}, + Inter: map[iface.ID]time.Duration{ 1: latency_inter_1, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{}, - Inter: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{}, + Inter: map[iface.ID]uint64{ 1: bandwidth_inter_1, }, }, @@ -501,7 +501,7 @@ func TestGenerateStaticInfo(t *testing.T) { LinkType: staticinfo.LinkTypeInfo{ 1: link_type_1, }, - InternalHops: map[common.IfIDType]uint32{}, + InternalHops: map[iface.ID]uint32{}, Note: note, }, }, @@ -512,18 +512,18 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeCore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{ 3: latency_intra_1_3, }, - Inter: map[common.IfIDType]time.Duration{ + Inter: map[iface.ID]time.Duration{ 1: latency_inter_1, }, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 3: bandwidth_intra_1_3, }, - Inter: map[common.IfIDType]uint64{ + Inter: map[iface.ID]uint64{ 1: bandwidth_inter_1, }, }, @@ -534,7 +534,7 @@ func TestGenerateStaticInfo(t *testing.T) { LinkType: staticinfo.LinkTypeInfo{ 1: link_type_1, }, - InternalHops: map[common.IfIDType]uint32{ + InternalHops: map[iface.ID]uint32{ 3: hops_intra_1_3, }, Note: note, @@ -547,18 +547,18 @@ func TestGenerateStaticInfo(t *testing.T) { ifType: ifTypeCore, expected: staticinfo.Extension{ Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{}, - Inter: map[common.IfIDType]time.Duration{}, + Intra: map[iface.ID]time.Duration{}, + Inter: map[iface.ID]time.Duration{}, }, Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{}, - Inter: map[common.IfIDType]uint64{}, + Intra: map[iface.ID]uint64{}, + Inter: map[iface.ID]uint64{}, }, Geo: staticinfo.GeoInfo{ 3: geo_3, }, LinkType: staticinfo.LinkTypeInfo{}, - InternalHops: map[common.IfIDType]uint32{}, + InternalHops: map[iface.ID]uint32{}, Note: note, }, }, diff --git a/control/beaconing/writer_test.go b/control/beaconing/writer_test.go index 508b00849c..5307ae857b 100644 --- a/control/beaconing/writer_test.go +++ b/control/beaconing/writer_test.go @@ -37,12 +37,12 @@ import ( "github.com/scionproto/scion/control/beaconing/mock_beaconing" "github.com/scionproto/scion/control/ifstate" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/xtest/graph" "github.com/scionproto/scion/pkg/scrypto" "github.com/scionproto/scion/pkg/scrypto/cppki" "github.com/scionproto/scion/pkg/scrypto/signed" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers/path/scion" "github.com/scionproto/scion/pkg/snet" "github.com/scionproto/scion/pkg/snet/addrutil" @@ -377,7 +377,7 @@ type topoWrap struct { } func (w topoWrap) UnderlayNextHop(id uint16) *net.UDPAddr { - a, _ := w.Topo.UnderlayNextHop(common.IfIDType(id)) + a, _ := w.Topo.UnderlayNextHop(iface.ID(id)) return a } diff --git a/control/cmd/control/BUILD.bazel b/control/cmd/control/BUILD.bazel index 9bf133cb52..88600bb13b 100644 --- a/control/cmd/control/BUILD.bazel +++ b/control/cmd/control/BUILD.bazel @@ -30,13 +30,13 @@ go_library( "//pkg/grpc:go_default_library", "//pkg/log:go_default_library", "//pkg/metrics:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/prom:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/proto/control_plane:go_default_library", "//pkg/proto/discovery:go_default_library", "//pkg/scrypto:go_default_library", "//pkg/scrypto/cppki:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//private/app:go_default_library", "//private/app/appnet:go_default_library", diff --git a/control/cmd/control/main.go b/control/cmd/control/main.go index 78be343ead..7168c789c9 100644 --- a/control/cmd/control/main.go +++ b/control/cmd/control/main.go @@ -56,13 +56,13 @@ import ( libgrpc "github.com/scionproto/scion/pkg/grpc" "github.com/scionproto/scion/pkg/log" libmetrics "github.com/scionproto/scion/pkg/metrics" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/prom" "github.com/scionproto/scion/pkg/private/serrors" cppb "github.com/scionproto/scion/pkg/proto/control_plane" dpb "github.com/scionproto/scion/pkg/proto/discovery" "github.com/scionproto/scion/pkg/scrypto" "github.com/scionproto/scion/pkg/scrypto/cppki" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" "github.com/scionproto/scion/private/app" infraenv "github.com/scionproto/scion/private/app/appnet" @@ -852,7 +852,7 @@ func createBeaconStore( return store, *policies.Prop.Filter.AllowIsdLoop, err } -func adaptInterfaceMap(in map[common.IfIDType]topology.IFInfo) map[uint16]ifstate.InterfaceInfo { +func adaptInterfaceMap(in map[iface.ID]topology.IFInfo) map[uint16]ifstate.InterfaceInfo { converted := make(map[uint16]ifstate.InterfaceInfo, len(in)) for id, info := range in { converted[uint16(id)] = ifstate.InterfaceInfo{ diff --git a/daemon/internal/servers/BUILD.bazel b/daemon/internal/servers/BUILD.bazel index 9bf6640324..df44d0fd83 100644 --- a/daemon/internal/servers/BUILD.bazel +++ b/daemon/internal/servers/BUILD.bazel @@ -15,13 +15,13 @@ go_library( "//pkg/drkey:go_default_library", "//pkg/log:go_default_library", "//pkg/metrics:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/private/ctrl/path_mgmt/proto:go_default_library", "//pkg/private/prom:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", "//pkg/proto/daemon:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//pkg/snet/path:go_default_library", "//private/revcache:go_default_library", diff --git a/daemon/internal/servers/grpc.go b/daemon/internal/servers/grpc.go index 58f8a59837..1caf06581f 100644 --- a/daemon/internal/servers/grpc.go +++ b/daemon/internal/servers/grpc.go @@ -31,7 +31,6 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" "github.com/scionproto/scion/pkg/log" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt/proto" "github.com/scionproto/scion/pkg/private/prom" @@ -39,6 +38,7 @@ import ( "github.com/scionproto/scion/pkg/private/util" pb_daemon "github.com/scionproto/scion/pkg/proto/daemon" sdpb "github.com/scionproto/scion/pkg/proto/daemon" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" snetpath "github.com/scionproto/scion/pkg/snet/path" "github.com/scionproto/scion/private/revcache" @@ -337,7 +337,7 @@ func (s *DaemonServer) notifyInterfaceDown(ctx context.Context, revInfo := &path_mgmt.RevInfo{ RawIsdas: addr.IA(req.IsdAs), - IfID: common.IfIDType(req.Id), + IfID: iface.ID(req.Id), LinkType: proto.LinkType_core, RawTTL: 10, RawTimestamp: util.TimeToSecs(time.Now()), diff --git a/gateway/pathhealth/BUILD.bazel b/gateway/pathhealth/BUILD.bazel index 96a0dc6a51..74062c75d0 100644 --- a/gateway/pathhealth/BUILD.bazel +++ b/gateway/pathhealth/BUILD.bazel @@ -33,9 +33,9 @@ go_test( deps = [ ":go_default_library", "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/private/util:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//pkg/snet/mock_snet:go_default_library", "@com_github_golang_mock//gomock:go_default_library", diff --git a/gateway/pathhealth/revocations_test.go b/gateway/pathhealth/revocations_test.go index 8698fe891f..0b2a518937 100644 --- a/gateway/pathhealth/revocations_test.go +++ b/gateway/pathhealth/revocations_test.go @@ -24,9 +24,9 @@ import ( "github.com/scionproto/scion/gateway/pathhealth" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/pkg/private/util" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" "github.com/scionproto/scion/pkg/snet/mock_snet" ) @@ -69,7 +69,7 @@ func TestExpiredRevocation(t *testing.T) { s.Cleanup(context.Background()) } -func createMockPath(ctrl *gomock.Controller, ia addr.IA, ifID common.IfIDType) snet.Path { +func createMockPath(ctrl *gomock.Controller, ia addr.IA, ifID iface.ID) snet.Path { path := mock_snet.NewMockPath(ctrl) path.EXPECT().Metadata().Return(&snet.PathMetadata{ Interfaces: []snet.PathInterface{{IA: ia, ID: ifID}}, @@ -77,7 +77,7 @@ func createMockPath(ctrl *gomock.Controller, ia addr.IA, ifID common.IfIDType) s return path } -func createRevInfo(ia addr.IA, ifID common.IfIDType, expired bool) *path_mgmt.RevInfo { +func createRevInfo(ia addr.IA, ifID iface.ID, expired bool) *path_mgmt.RevInfo { ri := &path_mgmt.RevInfo{ RawIsdas: ia, IfID: ifID, diff --git a/pkg/daemon/BUILD.bazel b/pkg/daemon/BUILD.bazel index 8a8ca23be8..ad0a44f9db 100644 --- a/pkg/daemon/BUILD.bazel +++ b/pkg/daemon/BUILD.bazel @@ -16,13 +16,13 @@ go_library( "//pkg/drkey:go_default_library", "//pkg/grpc:go_default_library", "//pkg/metrics:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/private/prom:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/proto/daemon:go_default_library", "//pkg/proto/drkey:go_default_library", "//pkg/scrypto/cppki:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//pkg/snet/path:go_default_library", "//private/topology:go_default_library", diff --git a/pkg/daemon/grpc.go b/pkg/daemon/grpc.go index 92e4bb7507..e501a5517d 100644 --- a/pkg/daemon/grpc.go +++ b/pkg/daemon/grpc.go @@ -27,12 +27,12 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/drkey" libgrpc "github.com/scionproto/scion/pkg/grpc" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/pkg/private/serrors" sdpb "github.com/scionproto/scion/pkg/proto/daemon" dkpb "github.com/scionproto/scion/pkg/proto/drkey" "github.com/scionproto/scion/pkg/scrypto/cppki" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" "github.com/scionproto/scion/pkg/snet/path" "github.com/scionproto/scion/private/topology" @@ -260,7 +260,7 @@ func convertPath(p *sdpb.Path, dst addr.IA) (path.Path, error) { interfaces := make([]snet.PathInterface, len(p.Interfaces)) for i, pi := range p.Interfaces { interfaces[i] = snet.PathInterface{ - ID: common.IfIDType(pi.Id), + ID: iface.ID(pi.Id), IA: addr.IA(pi.IsdAs), } } diff --git a/pkg/experimental/hiddenpath/BUILD.bazel b/pkg/experimental/hiddenpath/BUILD.bazel index 3962a4665e..1ff9dc2d72 100644 --- a/pkg/experimental/hiddenpath/BUILD.bazel +++ b/pkg/experimental/hiddenpath/BUILD.bazel @@ -55,7 +55,6 @@ go_test( "//control/ifstate:go_default_library", "//pkg/addr:go_default_library", "//pkg/experimental/hiddenpath/mock_hiddenpath:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/xtest:go_default_library", "//pkg/private/xtest/graph:go_default_library", @@ -64,6 +63,7 @@ go_test( "//pkg/scrypto/cppki:go_default_library", "//pkg/scrypto/signed:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "//pkg/slayers/path/scion:go_default_library", "//pkg/snet:go_default_library", diff --git a/pkg/experimental/hiddenpath/beaconwriter_test.go b/pkg/experimental/hiddenpath/beaconwriter_test.go index d68c0b19c0..ce44d72fce 100644 --- a/pkg/experimental/hiddenpath/beaconwriter_test.go +++ b/pkg/experimental/hiddenpath/beaconwriter_test.go @@ -37,7 +37,6 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/experimental/hiddenpath" "github.com/scionproto/scion/pkg/experimental/hiddenpath/mock_hiddenpath" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/private/xtest/graph" cryptopb "github.com/scionproto/scion/pkg/proto/crypto" @@ -45,6 +44,7 @@ import ( "github.com/scionproto/scion/pkg/scrypto/cppki" "github.com/scionproto/scion/pkg/scrypto/signed" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers/path/scion" "github.com/scionproto/scion/pkg/snet" "github.com/scionproto/scion/pkg/snet/addrutil" @@ -348,7 +348,7 @@ type topoWrap struct { } func (w topoWrap) UnderlayNextHop(id uint16) *net.UDPAddr { - a, _ := w.Topo.UnderlayNextHop(common.IfIDType(id)) + a, _ := w.Topo.UnderlayNextHop(iface.ID(id)) return a } diff --git a/pkg/private/common/BUILD.bazel b/pkg/private/common/BUILD.bazel index 36602cce10..5f6307f772 100644 --- a/pkg/private/common/BUILD.bazel +++ b/pkg/private/common/BUILD.bazel @@ -17,8 +17,5 @@ go_test( "errors_test.go", ], embed = [":go_default_library"], - deps = [ - "@com_github_stretchr_testify//assert:go_default_library", - "@com_github_stretchr_testify//require:go_default_library", - ], + deps = ["@com_github_stretchr_testify//assert:go_default_library"], ) diff --git a/pkg/private/common/defs.go b/pkg/private/common/defs.go index ae00ad94c7..59bf1e5f1d 100644 --- a/pkg/private/common/defs.go +++ b/pkg/private/common/defs.go @@ -15,11 +15,7 @@ package common -import ( - "reflect" - "strconv" - "strings" -) +import "reflect" const ( MinMTU = 1280 @@ -32,31 +28,6 @@ const ( TimeFmtSecs = "2006-01-02 15:04:05-0700" ) -// IfIDType is the type for interface IDs. -// -// Deprecated: with version 2 of the SCION header, there is no interface ID type anymore. -// Use the appropriate type depending on the path type. -type IfIDType uint64 - -func (ifID IfIDType) String() string { - return strconv.FormatUint(uint64(ifID), 10) -} - -// UnmarshalJSON unmarshals the JSON data into the IfID. -func (ifID *IfIDType) UnmarshalJSON(data []byte) error { - return ifID.UnmarshalText(data) -} - -// UnmarshalText unmarshals the text into the IfID. -func (ifID *IfIDType) UnmarshalText(text []byte) error { - i, err := strconv.ParseUint(strings.ReplaceAll(string(text), "\"", ""), 10, 64) - if err != nil { - return err - } - *ifID = IfIDType(i) - return nil -} - func TypeOf(v interface{}) string { t := reflect.TypeOf(v) if t != nil { diff --git a/pkg/private/common/defs_test.go b/pkg/private/common/defs_test.go index 218181b201..cd13c2fe65 100644 --- a/pkg/private/common/defs_test.go +++ b/pkg/private/common/defs_test.go @@ -15,11 +15,9 @@ package common_test import ( - "encoding/json" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/scionproto/scion/pkg/private/common" ) @@ -40,30 +38,3 @@ func TestTypeOf(t *testing.T) { }) } } - -func TestIfIDTypeUnmarshalJSON(t *testing.T) { - t.Run("Simple Value", func(t *testing.T) { - type exampleStruct struct { - IfID common.IfIDType `json:"if_id"` - } - j := `{"if_id": 5}` - var f exampleStruct - require.NoError(t, json.Unmarshal([]byte(j), &f)) - assert.Equal(t, exampleStruct{IfID: 5}, f) - }) - t.Run("Map keys", func(t *testing.T) { - type exampleStruct struct { - IfMap map[common.IfIDType]string `json:"if_map"` - } - j := `{"if_map": {"5": "foo"}}` - var f exampleStruct - require.NoError(t, json.Unmarshal([]byte(j), &f)) - assert.Equal(t, exampleStruct{IfMap: map[common.IfIDType]string{5: "foo"}}, f) - }) -} - -func TestIfIDTypeUnmarshalText(t *testing.T) { - var id common.IfIDType - assert.NoError(t, id.UnmarshalText([]byte("1"))) - assert.Equal(t, common.IfIDType(1), id) -} diff --git a/pkg/private/ctrl/path_mgmt/BUILD.bazel b/pkg/private/ctrl/path_mgmt/BUILD.bazel index 921b088259..98ccf0d48f 100644 --- a/pkg/private/ctrl/path_mgmt/BUILD.bazel +++ b/pkg/private/ctrl/path_mgmt/BUILD.bazel @@ -7,9 +7,9 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt/proto:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", + "//pkg/segment/iface:go_default_library", ], ) diff --git a/pkg/private/ctrl/path_mgmt/rev_info.go b/pkg/private/ctrl/path_mgmt/rev_info.go index 45b75ff82f..9b1c083dd2 100644 --- a/pkg/private/ctrl/path_mgmt/rev_info.go +++ b/pkg/private/ctrl/path_mgmt/rev_info.go @@ -22,10 +22,10 @@ import ( "time" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt/proto" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/private/util" + "github.com/scionproto/scion/pkg/segment/iface" ) const MinRevTTL = 10 * time.Second // MinRevTTL is the minimum lifetime of a revocation @@ -47,7 +47,7 @@ func (ee RevTimeError) Error() string { } type RevInfo struct { - IfID common.IfIDType + IfID iface.ID RawIsdas addr.IA // LinkType of revocation LinkType proto.LinkType diff --git a/pkg/private/xtest/graph/BUILD.bazel b/pkg/private/xtest/graph/BUILD.bazel index d5907cf9e5..521908ddbe 100644 --- a/pkg/private/xtest/graph/BUILD.bazel +++ b/pkg/private/xtest/graph/BUILD.bazel @@ -10,7 +10,6 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/proto/control_plane:go_default_library", "//pkg/proto/crypto:go_default_library", @@ -18,6 +17,7 @@ go_library( "//pkg/scrypto/signed:go_default_library", "//pkg/segment:go_default_library", "//pkg/segment/extensions/staticinfo:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "@com_github_golang_mock//gomock:go_default_library", "@org_golang_google_protobuf//proto:go_default_library", diff --git a/pkg/private/xtest/graph/graph.go b/pkg/private/xtest/graph/graph.go index a79a6063e4..a80b87baa6 100644 --- a/pkg/private/xtest/graph/graph.go +++ b/pkg/private/xtest/graph/graph.go @@ -37,7 +37,6 @@ import ( "google.golang.org/protobuf/proto" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" cppb "github.com/scionproto/scion/pkg/proto/control_plane" cryptopb "github.com/scionproto/scion/pkg/proto/crypto" @@ -45,6 +44,7 @@ import ( "github.com/scionproto/scion/pkg/scrypto/signed" seg "github.com/scionproto/scion/pkg/segment" "github.com/scionproto/scion/pkg/segment/extensions/staticinfo" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers/path" ) @@ -603,55 +603,55 @@ func generateStaticInfo(g *Graph, ia addr.IA, inIF, outIF uint16) *staticinfo.Ex latency := staticinfo.LatencyInfo{} if outIF != 0 { - latency.Intra = make(map[common.IfIDType]time.Duration) - latency.Inter = make(map[common.IfIDType]time.Duration) + latency.Intra = make(map[iface.ID]time.Duration) + latency.Inter = make(map[iface.ID]time.Duration) for ifID := range as.IfIDs { if ifID != outIF { // Note: the test graph does not distinguish between parent/child or // core interfaces. // Otherwise, we could skip the parent interfaces and half of the // sibling interfaces here. - latency.Intra[common.IfIDType(ifID)] = g.Latency(ifID, outIF) + latency.Intra[iface.ID(ifID)] = g.Latency(ifID, outIF) } if ifID == outIF || g.isPeer[ifID] { - latency.Inter[common.IfIDType(ifID)] = g.Latency(ifID, g.links[ifID]) + latency.Inter[iface.ID(ifID)] = g.Latency(ifID, g.links[ifID]) } } } bandwidth := staticinfo.BandwidthInfo{} if outIF != 0 { - bandwidth.Intra = make(map[common.IfIDType]uint64) - bandwidth.Inter = make(map[common.IfIDType]uint64) + bandwidth.Intra = make(map[iface.ID]uint64) + bandwidth.Inter = make(map[iface.ID]uint64) for ifID := range as.IfIDs { if ifID != outIF { - bandwidth.Intra[common.IfIDType(ifID)] = g.Bandwidth(ifID, outIF) + bandwidth.Intra[iface.ID(ifID)] = g.Bandwidth(ifID, outIF) } if ifID == outIF || g.isPeer[ifID] { - bandwidth.Inter[common.IfIDType(ifID)] = g.Bandwidth(ifID, g.links[ifID]) + bandwidth.Inter[iface.ID(ifID)] = g.Bandwidth(ifID, g.links[ifID]) } } } geo := make(staticinfo.GeoInfo) for ifID := range as.IfIDs { - geo[common.IfIDType(ifID)] = g.GeoCoordinates(ifID) + geo[iface.ID(ifID)] = g.GeoCoordinates(ifID) } linkType := make(staticinfo.LinkTypeInfo) for ifID := range as.IfIDs { - linkType[common.IfIDType(ifID)] = g.LinkType(ifID, g.links[ifID]) + linkType[iface.ID(ifID)] = g.LinkType(ifID, g.links[ifID]) } var internalHops staticinfo.InternalHopsInfo if outIF != 0 { - internalHops = make(map[common.IfIDType]uint32) + internalHops = make(map[iface.ID]uint32) if inIF != 0 { - internalHops[common.IfIDType(inIF)] = g.InternalHops(inIF, outIF) + internalHops[iface.ID(inIF)] = g.InternalHops(inIF, outIF) } for ifID := range as.IfIDs { if ifID != outIF && ifID != inIF { - internalHops[common.IfIDType(ifID)] = g.InternalHops(ifID, outIF) + internalHops[iface.ID(ifID)] = g.InternalHops(ifID, outIF) } } } diff --git a/pkg/segment/extensions/staticinfo/BUILD.bazel b/pkg/segment/extensions/staticinfo/BUILD.bazel index b41404d42e..f453b792bb 100644 --- a/pkg/segment/extensions/staticinfo/BUILD.bazel +++ b/pkg/segment/extensions/staticinfo/BUILD.bazel @@ -6,8 +6,8 @@ go_library( importpath = "github.com/scionproto/scion/pkg/segment/extensions/staticinfo", visibility = ["//visibility:public"], deps = [ - "//pkg/private/common:go_default_library", "//pkg/proto/control_plane:go_default_library", + "//pkg/segment/iface:go_default_library", ], ) @@ -16,7 +16,7 @@ go_test( srcs = ["staticinfo_test.go"], deps = [ ":go_default_library", - "//pkg/private/common:go_default_library", + "//pkg/segment/iface:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", ], ) diff --git a/pkg/segment/extensions/staticinfo/staticinfo.go b/pkg/segment/extensions/staticinfo/staticinfo.go index 83c7073151..6141441864 100644 --- a/pkg/segment/extensions/staticinfo/staticinfo.go +++ b/pkg/segment/extensions/staticinfo/staticinfo.go @@ -21,8 +21,8 @@ package staticinfo import ( "time" - "github.com/scionproto/scion/pkg/private/common" cppb "github.com/scionproto/scion/pkg/proto/control_plane" + "github.com/scionproto/scion/pkg/segment/iface" ) // Extension is the internal repesentation of the StaticInfoExtension path @@ -39,20 +39,20 @@ type Extension struct { // LatencyInfo is the internal repesentation of `latency` in the // StaticInfoExtension. type LatencyInfo struct { - Intra map[common.IfIDType]time.Duration - Inter map[common.IfIDType]time.Duration + Intra map[iface.ID]time.Duration + Inter map[iface.ID]time.Duration } // BandwidthInfo is the internal repesentation of `bandwidth` in the // StaticInfoExtension. type BandwidthInfo struct { - Intra map[common.IfIDType]uint64 - Inter map[common.IfIDType]uint64 + Intra map[iface.ID]uint64 + Inter map[iface.ID]uint64 } // GeoInfo is the internal repesentation of `geo` in the // StaticInfoExtension. -type GeoInfo map[common.IfIDType]GeoCoordinates +type GeoInfo map[iface.ID]GeoCoordinates // GeoCoordinates is the internal repesentation of the GeoCoordinates in the // StaticInfoExtension. @@ -76,11 +76,11 @@ const ( // LinkTypeInfo is the internal representation of `link_type` in the // StaticInfoExtension. -type LinkTypeInfo map[common.IfIDType]LinkType +type LinkTypeInfo map[iface.ID]LinkType // InternalHopsInfo is the internal representation of `internal_hops` in the // StaticInfoExtension. -type InternalHopsInfo map[common.IfIDType]uint32 +type InternalHopsInfo map[iface.ID]uint32 // FromPB creates the staticinfo Extension from the protobuf representation. func FromPB(pb *cppb.StaticInfoExtension) *Extension { @@ -101,13 +101,13 @@ func latencyInfoFromPB(pb *cppb.LatencyInfo) LatencyInfo { if pb == nil || len(pb.Intra) == 0 && len(pb.Inter) == 0 { return LatencyInfo{} } - intra := make(map[common.IfIDType]time.Duration, len(pb.Intra)) + intra := make(map[iface.ID]time.Duration, len(pb.Intra)) for ifID, v := range pb.Intra { - intra[common.IfIDType(ifID)] = time.Duration(v) * time.Microsecond + intra[iface.ID(ifID)] = time.Duration(v) * time.Microsecond } - inter := make(map[common.IfIDType]time.Duration, len(pb.Inter)) + inter := make(map[iface.ID]time.Duration, len(pb.Inter)) for ifID, v := range pb.Inter { - inter[common.IfIDType(ifID)] = time.Duration(v) * time.Microsecond + inter[iface.ID(ifID)] = time.Duration(v) * time.Microsecond } return LatencyInfo{ Intra: intra, @@ -119,13 +119,13 @@ func bandwidthInfoFromPB(pb *cppb.BandwidthInfo) BandwidthInfo { if pb == nil || len(pb.Intra) == 0 && len(pb.Inter) == 0 { return BandwidthInfo{} } - intra := make(map[common.IfIDType]uint64, len(pb.Intra)) + intra := make(map[iface.ID]uint64, len(pb.Intra)) for ifID, v := range pb.Intra { - intra[common.IfIDType(ifID)] = v + intra[iface.ID(ifID)] = v } - inter := make(map[common.IfIDType]uint64, len(pb.Inter)) + inter := make(map[iface.ID]uint64, len(pb.Inter)) for ifID, v := range pb.Inter { - inter[common.IfIDType(ifID)] = v + inter[iface.ID(ifID)] = v } return BandwidthInfo{ Intra: intra, @@ -139,7 +139,7 @@ func geoInfoFromPB(pb map[uint64]*cppb.GeoCoordinates) GeoInfo { } gi := make(GeoInfo, len(pb)) for ifID, v := range pb { - gi[common.IfIDType(ifID)] = GeoCoordinates{ + gi[iface.ID(ifID)] = GeoCoordinates{ Latitude: v.Latitude, Longitude: v.Longitude, Address: v.Address, @@ -167,7 +167,7 @@ func linkTypeInfoFromPB(pb map[uint64]cppb.LinkType) LinkTypeInfo { default: continue } - lti[common.IfIDType(ifID)] = v + lti[iface.ID(ifID)] = v } return lti } @@ -178,7 +178,7 @@ func internalHopsInfoFromPB(pb map[uint64]uint32) InternalHopsInfo { } ihi := make(InternalHopsInfo, len(pb)) for ifID, v := range pb { - ihi[common.IfIDType(ifID)] = v + ihi[iface.ID(ifID)] = v } return ihi } diff --git a/pkg/segment/extensions/staticinfo/staticinfo_test.go b/pkg/segment/extensions/staticinfo/staticinfo_test.go index 42c9bff6bf..42a2b1abf4 100644 --- a/pkg/segment/extensions/staticinfo/staticinfo_test.go +++ b/pkg/segment/extensions/staticinfo/staticinfo_test.go @@ -20,8 +20,8 @@ import ( "github.com/stretchr/testify/assert" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/segment/extensions/staticinfo" + "github.com/scionproto/scion/pkg/segment/iface" ) func TestRoundtripStaticInfoExtension(t *testing.T) { @@ -34,22 +34,22 @@ func TestRoundtripStaticInfoExtension(t *testing.T) { }, "latency": { Latency: staticinfo.LatencyInfo{ - Intra: map[common.IfIDType]time.Duration{ + Intra: map[iface.ID]time.Duration{ 10: 10 * time.Millisecond, 11: 11 * time.Millisecond, }, - Inter: map[common.IfIDType]time.Duration{ + Inter: map[iface.ID]time.Duration{ 11: 111 * time.Millisecond, }, }, }, "bandwidth": { Bandwidth: staticinfo.BandwidthInfo{ - Intra: map[common.IfIDType]uint64{ + Intra: map[iface.ID]uint64{ 10: 1, // 1Kbit/s 11: 10_000_000_000, // 10Tbit/s }, - Inter: map[common.IfIDType]uint64{ + Inter: map[iface.ID]uint64{ 11: 2_000_000, }, }, @@ -71,7 +71,7 @@ func TestRoundtripStaticInfoExtension(t *testing.T) { }, }, "internal_hops": { - InternalHops: map[common.IfIDType]uint32{ + InternalHops: map[iface.ID]uint32{ 10: 2, 11: 3, }, diff --git a/pkg/segment/iface/BUILD.bazel b/pkg/segment/iface/BUILD.bazel new file mode 100644 index 0000000000..d050cfa30f --- /dev/null +++ b/pkg/segment/iface/BUILD.bazel @@ -0,0 +1,18 @@ +load("//tools/lint:go.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = ["iface.go"], + importpath = "github.com/scionproto/scion/pkg/segment/iface", + visibility = ["//visibility:public"], +) + +go_test( + name = "go_default_test", + srcs = ["iface_test.go"], + deps = [ + ":go_default_library", + "@com_github_stretchr_testify//assert:go_default_library", + "@com_github_stretchr_testify//require:go_default_library", + ], +) diff --git a/pkg/segment/iface/iface.go b/pkg/segment/iface/iface.go new file mode 100644 index 0000000000..fc4186ae07 --- /dev/null +++ b/pkg/segment/iface/iface.go @@ -0,0 +1,45 @@ +// Copyright 2016 ETH Zurich +// Copyright 2018 ETH Zurich, Anapaya Systems +// +// 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 iface + +import ( + "strconv" + "strings" +) + +// IfIDType is the path-type-independent type for interface IDs. Interface IDs must fit in +// 64 bits. There is a lot of path-type-independent code that manipulates interface IDs without +// interpreting them. This type is a container for them. +type ID uint64 + +func (ifID ID) String() string { + return strconv.FormatUint(uint64(ifID), 10) +} + +// UnmarshalJSON unmarshals the JSON data into the IfID. +func (ifID *ID) UnmarshalJSON(data []byte) error { + return ifID.UnmarshalText(data) +} + +// UnmarshalText unmarshals the text into the IfID. +func (ifID *ID) UnmarshalText(text []byte) error { + i, err := strconv.ParseUint(strings.ReplaceAll(string(text), "\"", ""), 10, 64) + if err != nil { + return err + } + *ifID = ID(i) + return nil +} diff --git a/pkg/segment/iface/iface_test.go b/pkg/segment/iface/iface_test.go new file mode 100644 index 0000000000..12616e4a3f --- /dev/null +++ b/pkg/segment/iface/iface_test.go @@ -0,0 +1,52 @@ +// Copyright 2024 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 iface_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/scionproto/scion/pkg/segment/iface" +) + +func TestIfIDTypeUnmarshalJSON(t *testing.T) { + t.Run("Simple Value", func(t *testing.T) { + type exampleStruct struct { + IfID iface.ID `json:"if_id"` + } + j := `{"if_id": 5}` + var f exampleStruct + require.NoError(t, json.Unmarshal([]byte(j), &f)) + assert.Equal(t, exampleStruct{IfID: 5}, f) + }) + t.Run("Map keys", func(t *testing.T) { + type exampleStruct struct { + IfMap map[iface.ID]string `json:"if_map"` + } + j := `{"if_map": {"5": "foo"}}` + var f exampleStruct + require.NoError(t, json.Unmarshal([]byte(j), &f)) + assert.Equal(t, exampleStruct{IfMap: map[iface.ID]string{5: "foo"}}, f) + }) +} + +func TestIfIDTypeUnmarshalText(t *testing.T) { + var id iface.ID + assert.NoError(t, id.UnmarshalText([]byte("1"))) + assert.Equal(t, iface.ID(1), id) +} diff --git a/pkg/snet/BUILD.bazel b/pkg/snet/BUILD.bazel index 0c07539843..f0f8a2a654 100644 --- a/pkg/snet/BUILD.bazel +++ b/pkg/snet/BUILD.bazel @@ -27,6 +27,7 @@ go_library( "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers:go_default_library", "//pkg/slayers/path:go_default_library", "//pkg/slayers/path/empty:go_default_library", diff --git a/pkg/snet/path.go b/pkg/snet/path.go index b6c48df30f..37e00682eb 100644 --- a/pkg/snet/path.go +++ b/pkg/snet/path.go @@ -22,7 +22,7 @@ import ( "time" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers" ) @@ -70,7 +70,7 @@ type Path interface { // PathInterface is an interface of the path. type PathInterface struct { // ID is the ID of the interface. - ID common.IfIDType + ID iface.ID // IA is the ISD AS identifier of the interface. IA addr.IA } diff --git a/pkg/snet/scmp.go b/pkg/snet/scmp.go index e759d057c0..cc0f43d240 100644 --- a/pkg/snet/scmp.go +++ b/pkg/snet/scmp.go @@ -20,10 +20,10 @@ import ( "github.com/scionproto/scion/pkg/log" "github.com/scionproto/scion/pkg/metrics/v2" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/private/util" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers" ) @@ -73,7 +73,7 @@ func (h DefaultSCMPHandler) Handle(pkt *Packet) error { case slayers.SCMPTypeExternalInterfaceDown: msg := pkt.Payload.(SCMPExternalInterfaceDown) return h.handleSCMPRev(typeCode, &path_mgmt.RevInfo{ - IfID: common.IfIDType(msg.Interface), + IfID: iface.ID(msg.Interface), RawIsdas: msg.IA, RawTimestamp: util.TimeToSecs(time.Now()), RawTTL: 10, @@ -81,7 +81,7 @@ func (h DefaultSCMPHandler) Handle(pkt *Packet) error { case slayers.SCMPTypeInternalConnectivityDown: msg := pkt.Payload.(SCMPInternalConnectivityDown) return h.handleSCMPRev(typeCode, &path_mgmt.RevInfo{ - IfID: common.IfIDType(msg.Egress), + IfID: iface.ID(msg.Egress), RawIsdas: msg.IA, RawTimestamp: util.TimeToSecs(time.Now()), RawTTL: 10, diff --git a/private/path/combinator/BUILD.bazel b/private/path/combinator/BUILD.bazel index fdd55e4adf..19daa965fd 100644 --- a/private/path/combinator/BUILD.bazel +++ b/private/path/combinator/BUILD.bazel @@ -11,11 +11,11 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt/proto:go_default_library", "//pkg/private/util:go_default_library", "//pkg/segment:go_default_library", "//pkg/segment/extensions/staticinfo:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "//pkg/slayers/path/scion:go_default_library", "//pkg/snet:go_default_library", @@ -35,10 +35,10 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/xtest:go_default_library", "//pkg/private/xtest/graph:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "//pkg/slayers/path/scion:go_default_library", "//pkg/snet:go_default_library", diff --git a/private/path/combinator/combinator_test.go b/private/path/combinator/combinator_test.go index af67f0ebf4..f65e629986 100644 --- a/private/path/combinator/combinator_test.go +++ b/private/path/combinator/combinator_test.go @@ -28,10 +28,10 @@ import ( "github.com/stretchr/testify/require" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/xtest" "github.com/scionproto/scion/pkg/private/xtest/graph" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers/path" "github.com/scionproto/scion/pkg/slayers/path/scion" "github.com/scionproto/scion/pkg/snet" @@ -568,20 +568,20 @@ func TestFilterDuplicates(t *testing.T) { // These look somewhat valid, but that doesn't matter at all -- we only look // at the fingerprint anyway. path0 := []snet.PathInterface{ - {IA: addr.MustParseIA("1-ff00:0:110"), ID: common.IfIDType(10)}, - {IA: addr.MustParseIA("1-ff00:0:111"), ID: common.IfIDType(10)}, + {IA: addr.MustParseIA("1-ff00:0:110"), ID: iface.ID(10)}, + {IA: addr.MustParseIA("1-ff00:0:111"), ID: iface.ID(10)}, } path1 := []snet.PathInterface{ - {IA: addr.MustParseIA("1-ff00:0:110"), ID: common.IfIDType(11)}, - {IA: addr.MustParseIA("1-ff00:0:112"), ID: common.IfIDType(11)}, - {IA: addr.MustParseIA("1-ff00:0:112"), ID: common.IfIDType(12)}, - {IA: addr.MustParseIA("1-ff00:0:111"), ID: common.IfIDType(12)}, + {IA: addr.MustParseIA("1-ff00:0:110"), ID: iface.ID(11)}, + {IA: addr.MustParseIA("1-ff00:0:112"), ID: iface.ID(11)}, + {IA: addr.MustParseIA("1-ff00:0:112"), ID: iface.ID(12)}, + {IA: addr.MustParseIA("1-ff00:0:111"), ID: iface.ID(12)}, } path2 := []snet.PathInterface{ - {IA: addr.MustParseIA("1-ff00:0:110"), ID: common.IfIDType(11)}, - {IA: addr.MustParseIA("1-ff00:0:112"), ID: common.IfIDType(11)}, - {IA: addr.MustParseIA("1-ff00:0:112"), ID: common.IfIDType(22)}, - {IA: addr.MustParseIA("1-ff00:0:111"), ID: common.IfIDType(22)}, + {IA: addr.MustParseIA("1-ff00:0:110"), ID: iface.ID(11)}, + {IA: addr.MustParseIA("1-ff00:0:112"), ID: iface.ID(11)}, + {IA: addr.MustParseIA("1-ff00:0:112"), ID: iface.ID(22)}, + {IA: addr.MustParseIA("1-ff00:0:111"), ID: iface.ID(22)}, } // Define two expiry times for the paths: paths with latest expiry will be kept diff --git a/private/path/combinator/graph.go b/private/path/combinator/graph.go index 447c2a97bc..2531c77b78 100644 --- a/private/path/combinator/graph.go +++ b/private/path/combinator/graph.go @@ -23,10 +23,10 @@ import ( "time" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt/proto" "github.com/scionproto/scion/pkg/private/util" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers/path" "github.com/scionproto/scion/pkg/slayers/path/scion" "github.com/scionproto/scion/pkg/snet" @@ -146,8 +146,8 @@ func (g *dmg) traverseSegment(segment *inputSegment) { } for peerEntryIdx, peer := range asEntries[asEntryIndex].PeerEntries { - ingress := common.IfIDType(peer.HopField.ConsIngress) - remote := common.IfIDType(peer.PeerInterface) + ingress := iface.ID(peer.HopField.ConsIngress) + remote := iface.ID(peer.PeerInterface) tuples = append(tuples, Tuple{ Src: vertexFromIA(pinnedIA), Dst: vertexFromPeering(currentIA, ingress, peer.Peer, remote), @@ -259,17 +259,17 @@ func (s *inputSegment) IsDownSeg() bool { type vertex struct { IA addr.IA UpIA addr.IA - UpIfID common.IfIDType + UpIfID iface.ID DownIA addr.IA - DownIfID common.IfIDType + DownIfID iface.ID } func vertexFromIA(ia addr.IA) vertex { return vertex{IA: ia} } -func vertexFromPeering(upIA addr.IA, upIfID common.IfIDType, - downIA addr.IA, downIfID common.IfIDType) vertex { +func vertexFromPeering(upIA addr.IA, upIfID iface.ID, + downIA addr.IA, downIfID iface.ID) vertex { return vertex{UpIA: upIA, UpIfID: upIfID, DownIA: downIA, DownIfID: downIfID} } @@ -365,14 +365,14 @@ func (solution *pathSolution) Path() Path { if hopField.ConsEgress != 0 { intfs = append(intfs, snet.PathInterface{ IA: asEntry.Local, - ID: common.IfIDType(hopField.ConsEgress), + ID: iface.ID(hopField.ConsEgress), }) } // In a non-peer shortcut the AS is not traversed completely. if hopField.ConsIngress != 0 && (!isShortcut || isPeer) { intfs = append(intfs, snet.PathInterface{ IA: asEntry.Local, - ID: common.IfIDType(hopField.ConsIngress), + ID: iface.ID(hopField.ConsIngress), }) } hops = append(hops, hopField) diff --git a/private/path/combinator/staticinfo_accumulator.go b/private/path/combinator/staticinfo_accumulator.go index 383bead4e0..11ce952eb6 100644 --- a/private/path/combinator/staticinfo_accumulator.go +++ b/private/path/combinator/staticinfo_accumulator.go @@ -19,9 +19,9 @@ import ( "time" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" seg "github.com/scionproto/scion/pkg/segment" "github.com/scionproto/scion/pkg/segment/extensions/staticinfo" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" ) @@ -85,7 +85,7 @@ func collectLatency(p pathInfo) []time.Duration { } egIF := snet.PathInterface{ IA: asEntry.Local, - ID: common.IfIDType(asEntry.HopEntry.HopField.ConsEgress), + ID: iface.ID(asEntry.HopEntry.HopField.ConsEgress), } latency := staticInfo.Latency // Egress to sibling child, core or peer interfaces @@ -140,7 +140,7 @@ func collectBandwidth(p pathInfo) []uint64 { } egIF := snet.PathInterface{ IA: asEntry.Local, - ID: common.IfIDType(asEntry.HopEntry.HopField.ConsEgress), + ID: iface.ID(asEntry.HopEntry.HopField.ConsEgress), } bandwidth := staticInfo.Bandwidth // Egress to other local interfaces @@ -265,7 +265,7 @@ func collectInternalHops(p pathInfo) []uint32 { } egIF := snet.PathInterface{ IA: asEntry.Local, - ID: common.IfIDType(asEntry.HopEntry.HopField.ConsEgress), + ID: iface.ID(asEntry.HopEntry.HopField.ConsEgress), } internalHops := staticInfo.InternalHops for ifID, v := range internalHops { diff --git a/private/path/combinator/staticinfo_accumulator_test.go b/private/path/combinator/staticinfo_accumulator_test.go index 1bfe056356..ee144b708a 100644 --- a/private/path/combinator/staticinfo_accumulator_test.go +++ b/private/path/combinator/staticinfo_accumulator_test.go @@ -23,9 +23,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/xtest/graph" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" ) @@ -42,12 +42,12 @@ func TestStaticinfo(t *testing.T) { { Name: "#0 simple up-core-down", Path: []snet.PathInterface{ - {IA: addr.MustParseIA("1-ff00:0:131"), ID: common.IfIDType(graph.If_131_X_130_A)}, - {IA: addr.MustParseIA("1-ff00:0:130"), ID: common.IfIDType(graph.If_130_A_131_X)}, - {IA: addr.MustParseIA("1-ff00:0:130"), ID: common.IfIDType(graph.If_130_B_120_A)}, - {IA: addr.MustParseIA("1-ff00:0:120"), ID: common.IfIDType(graph.If_120_A_130_B)}, - {IA: addr.MustParseIA("1-ff00:0:120"), ID: common.IfIDType(graph.If_120_X_111_B)}, - {IA: addr.MustParseIA("1-ff00:0:111"), ID: common.IfIDType(graph.If_111_B_120_X)}, + {IA: addr.MustParseIA("1-ff00:0:131"), ID: iface.ID(graph.If_131_X_130_A)}, + {IA: addr.MustParseIA("1-ff00:0:130"), ID: iface.ID(graph.If_130_A_131_X)}, + {IA: addr.MustParseIA("1-ff00:0:130"), ID: iface.ID(graph.If_130_B_120_A)}, + {IA: addr.MustParseIA("1-ff00:0:120"), ID: iface.ID(graph.If_120_A_130_B)}, + {IA: addr.MustParseIA("1-ff00:0:120"), ID: iface.ID(graph.If_120_X_111_B)}, + {IA: addr.MustParseIA("1-ff00:0:111"), ID: iface.ID(graph.If_111_B_120_X)}, }, ASEntries: concatBeaconASEntries(g, []uint16{graph.If_130_A_131_X}, @@ -58,10 +58,10 @@ func TestStaticinfo(t *testing.T) { { Name: "#1 simple up-core", Path: []snet.PathInterface{ - {IA: addr.MustParseIA("1-ff00:0:131"), ID: common.IfIDType(graph.If_131_X_130_A)}, - {IA: addr.MustParseIA("1-ff00:0:130"), ID: common.IfIDType(graph.If_130_A_131_X)}, - {IA: addr.MustParseIA("1-ff00:0:130"), ID: common.IfIDType(graph.If_130_A_110_X)}, - {IA: addr.MustParseIA("1-ff00:0:110"), ID: common.IfIDType(graph.If_110_X_130_A)}, + {IA: addr.MustParseIA("1-ff00:0:131"), ID: iface.ID(graph.If_131_X_130_A)}, + {IA: addr.MustParseIA("1-ff00:0:130"), ID: iface.ID(graph.If_130_A_131_X)}, + {IA: addr.MustParseIA("1-ff00:0:130"), ID: iface.ID(graph.If_130_A_110_X)}, + {IA: addr.MustParseIA("1-ff00:0:110"), ID: iface.ID(graph.If_110_X_130_A)}, }, ASEntries: concatBeaconASEntries(g, []uint16{graph.If_130_A_131_X}, @@ -72,8 +72,8 @@ func TestStaticinfo(t *testing.T) { { Name: "#2 simple up only", Path: []snet.PathInterface{ - {IA: addr.MustParseIA("1-ff00:0:131"), ID: common.IfIDType(graph.If_131_X_130_A)}, - {IA: addr.MustParseIA("1-ff00:0:130"), ID: common.IfIDType(graph.If_130_A_131_X)}, + {IA: addr.MustParseIA("1-ff00:0:131"), ID: iface.ID(graph.If_131_X_130_A)}, + {IA: addr.MustParseIA("1-ff00:0:130"), ID: iface.ID(graph.If_130_A_131_X)}, }, ASEntries: concatBeaconASEntries(g, []uint16{graph.If_130_A_131_X}, @@ -84,10 +84,10 @@ func TestStaticinfo(t *testing.T) { { Name: "#14 shortcut, common upstream", Path: []snet.PathInterface{ - {IA: addr.MustParseIA("2-ff00:0:212"), ID: common.IfIDType(graph.If_212_X_211_A1)}, - {IA: addr.MustParseIA("2-ff00:0:211"), ID: common.IfIDType(graph.If_211_A1_212_X)}, - {IA: addr.MustParseIA("2-ff00:0:211"), ID: common.IfIDType(graph.If_211_A_222_X)}, - {IA: addr.MustParseIA("2-ff00:0:222"), ID: common.IfIDType(graph.If_222_X_211_A)}, + {IA: addr.MustParseIA("2-ff00:0:212"), ID: iface.ID(graph.If_212_X_211_A1)}, + {IA: addr.MustParseIA("2-ff00:0:211"), ID: iface.ID(graph.If_211_A1_212_X)}, + {IA: addr.MustParseIA("2-ff00:0:211"), ID: iface.ID(graph.If_211_A_222_X)}, + {IA: addr.MustParseIA("2-ff00:0:222"), ID: iface.ID(graph.If_222_X_211_A)}, }, ASEntries: concatBeaconASEntries(g, []uint16{graph.If_210_X1_211_A, graph.If_211_A1_212_X}, @@ -98,12 +98,12 @@ func TestStaticinfo(t *testing.T) { { Name: "#15 go through peer", Path: []snet.PathInterface{ - {IA: addr.MustParseIA("2-ff00:0:212"), ID: common.IfIDType(graph.If_212_X_211_A1)}, - {IA: addr.MustParseIA("2-ff00:0:211"), ID: common.IfIDType(graph.If_211_A1_212_X)}, - {IA: addr.MustParseIA("2-ff00:0:211"), ID: common.IfIDType(graph.If_211_A_221_X)}, - {IA: addr.MustParseIA("2-ff00:0:221"), ID: common.IfIDType(graph.If_221_X_211_A)}, - {IA: addr.MustParseIA("2-ff00:0:221"), ID: common.IfIDType(graph.If_221_X_222_X)}, - {IA: addr.MustParseIA("2-ff00:0:222"), ID: common.IfIDType(graph.If_222_X_221_X)}, + {IA: addr.MustParseIA("2-ff00:0:212"), ID: iface.ID(graph.If_212_X_211_A1)}, + {IA: addr.MustParseIA("2-ff00:0:211"), ID: iface.ID(graph.If_211_A1_212_X)}, + {IA: addr.MustParseIA("2-ff00:0:211"), ID: iface.ID(graph.If_211_A_221_X)}, + {IA: addr.MustParseIA("2-ff00:0:221"), ID: iface.ID(graph.If_221_X_211_A)}, + {IA: addr.MustParseIA("2-ff00:0:221"), ID: iface.ID(graph.If_221_X_222_X)}, + {IA: addr.MustParseIA("2-ff00:0:222"), ID: iface.ID(graph.If_222_X_221_X)}, }, ASEntries: concatBeaconASEntries(g, []uint16{graph.If_210_X1_211_A, graph.If_211_A1_212_X}, diff --git a/private/path/pathpol/BUILD.bazel b/private/path/pathpol/BUILD.bazel index a85b5f97a0..116d06a2c9 100644 --- a/private/path/pathpol/BUILD.bazel +++ b/private/path/pathpol/BUILD.bazel @@ -16,8 +16,8 @@ go_library( "//antlr/sequence:go_default_library", "//pkg/addr:go_default_library", "//pkg/log:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "@com_github_antlr_antlr4_runtime_go_antlr//:go_default_library", ], @@ -36,8 +36,8 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/xtest/graph:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//pkg/snet/mock_snet:go_default_library", "//pkg/snet/path:go_default_library", diff --git a/private/path/pathpol/acl_test.go b/private/path/pathpol/acl_test.go index 1bdb412832..3bf6d4db71 100644 --- a/private/path/pathpol/acl_test.go +++ b/private/path/pathpol/acl_test.go @@ -23,7 +23,7 @@ import ( "gopkg.in/yaml.v2" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" + "github.com/scionproto/scion/pkg/segment/iface" ) func TestNewACL(t *testing.T) { @@ -113,7 +113,7 @@ func TestACLEntryLoadFromString(t *testing.T) { String: "+ 0", ACLEntry: ACLEntry{ Action: Allow, - Rule: &HopPredicate{IfIDs: []common.IfIDType{0}}, + Rule: &HopPredicate{IfIDs: []iface.ID{0}}, }, ErrorAssertion: assert.NoError, }, @@ -121,7 +121,7 @@ func TestACLEntryLoadFromString(t *testing.T) { String: "+ 1-2#3", ACLEntry: ACLEntry{ Action: Allow, - Rule: &HopPredicate{ISD: 1, AS: 2, IfIDs: []common.IfIDType{3}}, + Rule: &HopPredicate{ISD: 1, AS: 2, IfIDs: []iface.ID{3}}, }, ErrorAssertion: assert.NoError, }, @@ -134,7 +134,7 @@ func TestACLEntryLoadFromString(t *testing.T) { String: "- 0", ACLEntry: ACLEntry{ Action: Deny, - Rule: &HopPredicate{IfIDs: []common.IfIDType{0}}, + Rule: &HopPredicate{IfIDs: []iface.ID{0}}, }, ErrorAssertion: assert.NoError, }, @@ -161,7 +161,7 @@ func TestACLEntryLoadFromString(t *testing.T) { func TestACLEntryString(t *testing.T) { aclEntryString := "+ 0-0#0" - aclEntry := &ACLEntry{Action: true, Rule: &HopPredicate{IfIDs: []common.IfIDType{0}}} + aclEntry := &ACLEntry{Action: true, Rule: &HopPredicate{IfIDs: []iface.ID{0}}} assert.Equal(t, aclEntryString, aclEntry.String()) } diff --git a/private/path/pathpol/hop_pred.go b/private/path/pathpol/hop_pred.go index 28980c8296..70904a29c6 100644 --- a/private/path/pathpol/hop_pred.go +++ b/private/path/pathpol/hop_pred.go @@ -22,8 +22,8 @@ import ( "strings" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" ) @@ -32,11 +32,11 @@ import ( type HopPredicate struct { ISD addr.ISD AS addr.AS - IfIDs []common.IfIDType + IfIDs []iface.ID } func NewHopPredicate() *HopPredicate { - return &HopPredicate{IfIDs: make([]common.IfIDType, 1)} + return &HopPredicate{IfIDs: make([]iface.ID, 1)} } func HopPredicateFromString(str string) (*HopPredicate, error) { @@ -44,7 +44,7 @@ func HopPredicateFromString(str string) (*HopPredicate, error) { if err = validateHopPredStr(str); err != nil { return &HopPredicate{}, err } - var ifIDs = make([]common.IfIDType, 1) + var ifIDs = make([]iface.ID, 1) // Parse ISD dashParts := strings.Split(str, "-") isd, err := addr.ParseISD(dashParts[0]) @@ -136,12 +136,12 @@ func (hp *HopPredicate) UnmarshalJSON(b []byte) error { return err } -func parseIfID(str string) (common.IfIDType, error) { +func parseIfID(str string) (iface.ID, error) { ifID, err := strconv.ParseUint(str, 10, 64) if err != nil { return 0, err } - return common.IfIDType(ifID), nil + return iface.ID(ifID), nil } // validateHopPredStr checks if str has the correct amount of delimiters diff --git a/private/path/pathpol/hop_pred_test.go b/private/path/pathpol/hop_pred_test.go index fa2cd76e70..6380b62071 100644 --- a/private/path/pathpol/hop_pred_test.go +++ b/private/path/pathpol/hop_pred_test.go @@ -21,7 +21,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/scionproto/scion/pkg/private/common" + "github.com/scionproto/scion/pkg/segment/iface" ) func TestNewHopPredicate(t *testing.T) { @@ -32,22 +32,22 @@ func TestNewHopPredicate(t *testing.T) { }{ "ISD wildcard": { In: "0", - HP: &HopPredicate{ISD: 0, AS: 0, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 0, AS: 0, IfIDs: []iface.ID{0}}, Valid: true, }, "AS, IF wildcard omitted": { In: "1", - HP: &HopPredicate{ISD: 1, AS: 0, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 1, AS: 0, IfIDs: []iface.ID{0}}, Valid: true, }, "IF wildcard omitted": { In: "1-0", - HP: &HopPredicate{ISD: 1, AS: 0, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 1, AS: 0, IfIDs: []iface.ID{0}}, Valid: true, }, "basic wildcard": { In: "1-0#0", - HP: &HopPredicate{ISD: 1, AS: 0, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 1, AS: 0, IfIDs: []iface.ID{0}}, Valid: true, }, "AS wildcard, interface set": { @@ -56,27 +56,27 @@ func TestNewHopPredicate(t *testing.T) { }, "ISD wildcard, AS set": { In: "0-1#0", - HP: &HopPredicate{ISD: 0, AS: 1, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 0, AS: 1, IfIDs: []iface.ID{0}}, Valid: true, }, "ISD wildcard, AS set, interface set": { In: "0-1#2", - HP: &HopPredicate{ISD: 0, AS: 1, IfIDs: []common.IfIDType{2}}, + HP: &HopPredicate{ISD: 0, AS: 1, IfIDs: []iface.ID{2}}, Valid: true, }, "ISD wildcard, AS set and interface omitted": { In: "0-1", - HP: &HopPredicate{ISD: 0, AS: 1, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 0, AS: 1, IfIDs: []iface.ID{0}}, Valid: true, }, "IF wildcard omitted, AS set": { In: "1-2", - HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []iface.ID{0}}, Valid: true, }, "two IfIDs": { In: "1-2#3,4", - HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []common.IfIDType{3, 4}}, + HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []iface.ID{3, 4}}, Valid: true, }, "three IfIDs": { @@ -140,13 +140,13 @@ func TestJsonConversion(t *testing.T) { HP *HopPredicate }{ "Normal predicate": { - HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []common.IfIDType{1, 2}}, + HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []iface.ID{1, 2}}, }, "wildcard predicate": { - HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{ISD: 1, AS: 2, IfIDs: []iface.ID{0}}, }, "only ifIDs": { - HP: &HopPredicate{IfIDs: []common.IfIDType{0}}, + HP: &HopPredicate{IfIDs: []iface.ID{0}}, }, } for name, test := range tests { diff --git a/private/path/pathpol/policy_test.go b/private/path/pathpol/policy_test.go index 5e07e38508..0251f062a7 100644 --- a/private/path/pathpol/policy_test.go +++ b/private/path/pathpol/policy_test.go @@ -24,8 +24,8 @@ import ( "github.com/stretchr/testify/require" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/xtest/graph" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" snetpath "github.com/scionproto/scion/pkg/snet/path" ) @@ -648,7 +648,7 @@ func (p PathProvider) GetPaths(src, dst addr.IA) []snet.Path { ia := p.g.GetParent(ifID) pathIntfs = append(pathIntfs, snet.PathInterface{ IA: ia, - ID: common.IfIDType(ifID), + ID: iface.ID(ifID), }) } var srcIA, dstIA addr.IA diff --git a/private/path/pathpol/sequence.go b/private/path/pathpol/sequence.go index ab178d87b4..a2bfc81ed0 100644 --- a/private/path/pathpol/sequence.go +++ b/private/path/pathpol/sequence.go @@ -28,8 +28,8 @@ import ( "github.com/scionproto/scion/antlr/sequence" "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/log" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" ) @@ -294,7 +294,7 @@ func (l *sequenceListener) ExitIFace(c *sequence.IFaceContext) { l.push(re) } -func hop(ia addr.IA, ingress, egress common.IfIDType) string { +func hop(ia addr.IA, ingress, egress iface.ID) string { return fmt.Sprintf("%s#%d,%d", ia, ingress, egress) } diff --git a/private/pathdb/query/BUILD.bazel b/private/pathdb/query/BUILD.bazel index 949c446ed2..73977233d1 100644 --- a/private/pathdb/query/BUILD.bazel +++ b/private/pathdb/query/BUILD.bazel @@ -7,7 +7,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", ], ) diff --git a/private/pathdb/query/query.go b/private/pathdb/query/query.go index d8013fb606..d8796a9c3c 100644 --- a/private/pathdb/query/query.go +++ b/private/pathdb/query/query.go @@ -20,13 +20,13 @@ import ( "time" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" ) type IntfSpec struct { IA addr.IA - IfID common.IfIDType + IfID iface.ID } type Params struct { diff --git a/private/revcache/BUILD.bazel b/private/revcache/BUILD.bazel index 99bea4419e..84940f9448 100644 --- a/private/revcache/BUILD.bazel +++ b/private/revcache/BUILD.bazel @@ -10,9 +10,9 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/storage/cleaner:go_default_library", "//private/storage/db:go_default_library", ], @@ -24,13 +24,13 @@ go_test( deps = [ ":go_default_library", "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/private/ctrl/path_mgmt/proto:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", "//pkg/private/xtest/graph:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/revcache/mock_revcache:go_default_library", "@com_github_golang_mock//gomock:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", diff --git a/private/revcache/revcache.go b/private/revcache/revcache.go index 0e5826990d..903f39d943 100644 --- a/private/revcache/revcache.go +++ b/private/revcache/revcache.go @@ -20,19 +20,19 @@ import ( "io" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/storage/db" ) // Key denotes the key for the revocation cache. type Key struct { IA addr.IA - IfID common.IfIDType + IfID iface.ID } // NewKey creates a new key for the revocation cache. -func NewKey(ia addr.IA, ifID common.IfIDType) Key { +func NewKey(ia addr.IA, ifID iface.ID) Key { return Key{ IA: ia, IfID: ifID, diff --git a/private/revcache/revcachetest/BUILD.bazel b/private/revcache/revcachetest/BUILD.bazel index 19a4187eee..48e153dde3 100644 --- a/private/revcache/revcachetest/BUILD.bazel +++ b/private/revcache/revcachetest/BUILD.bazel @@ -7,10 +7,10 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/private/ctrl/path_mgmt/proto:go_default_library", "//pkg/private/util:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/revcache:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", "@com_github_stretchr_testify//require:go_default_library", diff --git a/private/revcache/revcachetest/revcachetest.go b/private/revcache/revcachetest/revcachetest.go index c6d55efb80..042075742a 100644 --- a/private/revcache/revcachetest/revcachetest.go +++ b/private/revcache/revcachetest/revcachetest.go @@ -24,18 +24,18 @@ import ( "github.com/stretchr/testify/require" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt/proto" "github.com/scionproto/scion/pkg/private/util" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/revcache" ) var ( ia110 = addr.MustParseIA("1-ff00:0:110") ia120 = addr.MustParseIA("1-ff00:0:120") - ifID15 = common.IfIDType(15) - ifID19 = common.IfIDType(19) + ifID15 = iface.ID(15) + ifID19 = iface.ID(19) TimeOut = 5 * time.Second ) @@ -100,7 +100,7 @@ func testGetMultikey(t *testing.T, revCache TestableRevCache) { rev1 := defaultRevInfo(ia110, ifID15) rev2 := defaultRevInfo(ia110, ifID19) rev3 := defaultRevInfo(ia120, ifID15) - rev4 := defaultRevInfo(ia120, common.IfIDType(10)) + rev4 := defaultRevInfo(ia120, iface.ID(10)) ctx, cancelF := context.WithTimeout(context.Background(), TimeOut) defer cancelF() @@ -143,7 +143,7 @@ func testGetAll(t *testing.T, revCache TestableRevCache) { rev1 := defaultRevInfo(ia110, ifID15) rev2 := defaultRevInfo(ia110, ifID19) rev3 := defaultRevInfo(ia120, ifID15) - rev4 := defaultRevInfo(ia120, common.IfIDType(20)) + rev4 := defaultRevInfo(ia120, iface.ID(20)) _, err = revCache.Insert(ctx, rev1) require.NoError(t, err) _, err = revCache.Insert(ctx, rev2) @@ -298,7 +298,7 @@ func testDeleteExpired(t *testing.T, revCache TestableRevCache) { assert.EqualValues(t, 0, del, "DeleteExpired should delete 0 if entry is not expired") } -func defaultRevInfo(ia addr.IA, ifID common.IfIDType) *path_mgmt.RevInfo { +func defaultRevInfo(ia addr.IA, ifID iface.ID) *path_mgmt.RevInfo { return &path_mgmt.RevInfo{ IfID: ifID, RawIsdas: ia, diff --git a/private/revcache/util.go b/private/revcache/util.go index ded1166999..36f1b115c1 100644 --- a/private/revcache/util.go +++ b/private/revcache/util.go @@ -17,8 +17,8 @@ package revcache import ( "context" - "github.com/scionproto/scion/pkg/private/common" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/storage/cleaner" ) @@ -37,8 +37,8 @@ func NoRevokedHopIntf(ctx context.Context, revCache RevCache, for _, asEntry := range s.ASEntries { hop := asEntry.HopEntry.HopField for _, key := range [2]Key{ - {IA: asEntry.Local, IfID: common.IfIDType(hop.ConsIngress)}, - {IA: asEntry.Local, IfID: common.IfIDType(hop.ConsEgress)}, + {IA: asEntry.Local, IfID: iface.ID(hop.ConsIngress)}, + {IA: asEntry.Local, IfID: iface.ID(hop.ConsEgress)}, } { rev, err := revCache.Get(ctx, key) if err != nil || rev != nil { diff --git a/private/revcache/util_test.go b/private/revcache/util_test.go index 01f71672f3..3e73cf403f 100644 --- a/private/revcache/util_test.go +++ b/private/revcache/util_test.go @@ -23,13 +23,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt/proto" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest/graph" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/revcache" "github.com/scionproto/scion/private/revcache/mock_revcache" ) @@ -61,11 +61,12 @@ func TestNoRevokedHopIntf(t *testing.T) { func(_ context.Context, key revcache.Key) (*path_mgmt.RevInfo, error) { iaFmt := key.IA.String() _ = iaFmt - if key.IA == ia211 && key.IfID == common.IfIDType(graph.If_211_A_210_X) { + if key.IA == ia211 && key.IfID == iface.ID(graph.If_211_A_210_X) { return sRev, nil } return nil, nil }).AnyTimes() + noR, err := revcache.NoRevokedHopIntf(ctx, revCache, seg210_222_1) assert.NoError(t, err) assert.False(t, noR, "revocation expected") @@ -82,7 +83,7 @@ func TestNoRevokedHopIntf(t *testing.T) { func defaultRevInfo(ia addr.IA, ifID uint16, ts time.Time) *path_mgmt.RevInfo { return &path_mgmt.RevInfo{ - IfID: common.IfIDType(ifID), + IfID: iface.ID(ifID), RawIsdas: ia, LinkType: proto.LinkType_core, RawTimestamp: util.TimeToSecs(ts), diff --git a/private/segment/segfetcher/BUILD.bazel b/private/segment/segfetcher/BUILD.bazel index faf6e1c34d..21a22d4a67 100644 --- a/private/segment/segfetcher/BUILD.bazel +++ b/private/segment/segfetcher/BUILD.bazel @@ -49,12 +49,12 @@ go_test( embed = [":go_default_library"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/xtest/graph:go_default_library", "//pkg/private/xtest/matchers:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//private/pathdb/mock_pathdb:go_default_library", "//private/pathdb/query:go_default_library", diff --git a/private/segment/segfetcher/resolver_test.go b/private/segment/segfetcher/resolver_test.go index 06f27bdca1..85a00e03b4 100644 --- a/private/segment/segfetcher/resolver_test.go +++ b/private/segment/segfetcher/resolver_test.go @@ -23,11 +23,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/ctrl/path_mgmt" "github.com/scionproto/scion/pkg/private/xtest/graph" "github.com/scionproto/scion/pkg/private/xtest/matchers" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/pathdb/mock_pathdb" "github.com/scionproto/scion/private/pathdb/query" "github.com/scionproto/scion/private/revcache" @@ -409,11 +409,11 @@ func TestResolverWithRevocations(t *testing.T) { ExpectRevcache: func(t *testing.T, revCache *mock_revcache.MockRevCache) { key111_120 := revcache.Key{ IA: non_core_111, - IfID: common.IfIDType(graph.If_111_B_120_X), + IfID: iface.ID(graph.If_111_B_120_X), } key111_130 := revcache.Key{ IA: non_core_111, - IfID: common.IfIDType(graph.If_111_A_130_B), + IfID: iface.ID(graph.If_111_A_130_B), } revoke(t, revCache, key111_120) revoke(t, revCache, key111_130) @@ -444,7 +444,7 @@ func TestResolverWithRevocations(t *testing.T) { db.EXPECT().Get(gomock.Any(), gomock.Any()).Times(2) }, ExpectRevcache: func(t *testing.T, revCache *mock_revcache.MockRevCache) { - key110 := revcache.Key{IA: core_110, IfID: common.IfIDType(graph.If_110_X_130_A)} + key110 := revcache.Key{IA: core_110, IfID: iface.ID(graph.If_110_X_130_A)} rev := &path_mgmt.RevInfo{} revCache.EXPECT().Get(gomock.Any(), key110).Return(rev, nil) revCache.EXPECT().Get(gomock.Any(), gomock.Any()).AnyTimes() diff --git a/private/storage/beacon/sqlite/BUILD.bazel b/private/storage/beacon/sqlite/BUILD.bazel index eaf01f3a92..7820d33ccd 100644 --- a/private/storage/beacon/sqlite/BUILD.bazel +++ b/private/storage/beacon/sqlite/BUILD.bazel @@ -11,9 +11,9 @@ go_library( deps = [ "//control/beacon:go_default_library", "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/storage/beacon:go_default_library", "//private/storage/db:go_default_library", ], diff --git a/private/storage/beacon/sqlite/db.go b/private/storage/beacon/sqlite/db.go index dc92b5a7a9..69f90bfcea 100644 --- a/private/storage/beacon/sqlite/db.go +++ b/private/storage/beacon/sqlite/db.go @@ -24,9 +24,9 @@ import ( "github.com/scionproto/scion/control/beacon" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/private/util" + "github.com/scionproto/scion/pkg/segment/iface" storagebeacon "github.com/scionproto/scion/private/storage/beacon" "github.com/scionproto/scion/private/storage/db" ) @@ -140,7 +140,7 @@ func (e *executor) CandidateBeacons( beacons := make([]beacon.Beacon, 0, setSize) for rows.Next() { var rawBeacon sql.RawBytes - var inIfID common.IfIDType + var inIfID iface.ID if err = rows.Scan(&rawBeacon, &inIfID); err != nil { return nil, db.NewReadError(beacon.ErrReadingRows, err) } diff --git a/private/storage/path/dbtest/BUILD.bazel b/private/storage/path/dbtest/BUILD.bazel index dd03cd363a..54a02f46ee 100644 --- a/private/storage/path/dbtest/BUILD.bazel +++ b/private/storage/path/dbtest/BUILD.bazel @@ -7,9 +7,9 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/xtest/graph:go_default_library", "//pkg/segment:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers/path:go_default_library", "//private/pathdb:go_default_library", "//private/pathdb/query:go_default_library", diff --git a/private/storage/path/dbtest/dbtest.go b/private/storage/path/dbtest/dbtest.go index d8e474eca6..920cbe499e 100644 --- a/private/storage/path/dbtest/dbtest.go +++ b/private/storage/path/dbtest/dbtest.go @@ -27,9 +27,9 @@ import ( "github.com/stretchr/testify/require" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/xtest/graph" seg "github.com/scionproto/scion/pkg/segment" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/slayers/path" "github.com/scionproto/scion/private/pathdb" "github.com/scionproto/scion/private/pathdb/query" @@ -603,7 +603,7 @@ func checkInterface(t *testing.T, ctx context.Context, ia addr.IA, ifID uint16, Intfs: []*query.IntfSpec{ { IA: ia, - IfID: common.IfIDType(ifID), + IfID: iface.ID(ifID), }, }, }) diff --git a/private/topology/BUILD.bazel b/private/topology/BUILD.bazel index 685c2313a0..a8a38baf97 100644 --- a/private/topology/BUILD.bazel +++ b/private/topology/BUILD.bazel @@ -18,8 +18,8 @@ go_library( "//pkg/addr:go_default_library", "//pkg/log:go_default_library", "//pkg/metrics:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/topology/json:go_default_library", "//private/topology/underlay:go_default_library", ], @@ -41,9 +41,9 @@ go_test( deps = [ "//pkg/addr:go_default_library", "//pkg/metrics/mock_metrics:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/ctrl/path_mgmt/proto:go_default_library", "//pkg/private/xtest:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/topology/json:go_default_library", "//private/topology/mock_topology:go_default_library", "@com_github_golang_mock//gomock:go_default_library", diff --git a/private/topology/interface.go b/private/topology/interface.go index ca61eb1597..e5bb6f6984 100644 --- a/private/topology/interface.go +++ b/private/topology/interface.go @@ -22,8 +22,8 @@ import ( "sort" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" ) // Topology is the topology type for applications and libraries that only need read access to AS @@ -39,7 +39,7 @@ type Topology interface { // Core returns whether the local AS is core. Core() bool // InterfaceIDs returns all interface IDS from the local AS. - IfIDs() []common.IfIDType + IfIDs() []iface.ID // PortRange returns the first and last ports of the port range (both included), // in which endhost listen for SCION/UDP application using the UDP/IP underlay. PortRange() (uint16, uint16) @@ -59,7 +59,7 @@ type Topology interface { 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) + UnderlayNextHop(ifID iface.ID) (*net.UDPAddr, bool) // MakeHostInfos returns the underlay addresses of all services for the specified service type. MakeHostInfos(st ServiceType) ([]*net.UDPAddr, error) @@ -144,8 +144,8 @@ func (t *topologyS) MTU() uint16 { return uint16(t.Topology.MTU) } -func (t *topologyS) IfIDs() []common.IfIDType { - intfs := make([]common.IfIDType, 0, len(t.Topology.IFInfoMap)) +func (t *topologyS) IfIDs() []iface.ID { + intfs := make([]iface.ID, 0, len(t.Topology.IFInfoMap)) for ifID := range t.Topology.IFInfoMap { intfs = append(intfs, ifID) } @@ -156,7 +156,7 @@ func (t *topologyS) PortRange() (uint16, uint16) { return t.Topology.DispatchedPortStart, t.Topology.DispatchedPortEnd } -func (t *topologyS) UnderlayNextHop(ifID common.IfIDType) (*net.UDPAddr, bool) { +func (t *topologyS) UnderlayNextHop(ifID iface.ID) (*net.UDPAddr, bool) { ifInfo, ok := t.Topology.IFInfoMap[ifID] if !ok { return nil, false diff --git a/private/topology/json/BUILD.bazel b/private/topology/json/BUILD.bazel index 6c018fec49..98c4cfddbd 100644 --- a/private/topology/json/BUILD.bazel +++ b/private/topology/json/BUILD.bazel @@ -7,9 +7,9 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/log:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", + "//pkg/segment/iface:go_default_library", ], ) @@ -19,9 +19,9 @@ go_test( data = glob(["testdata/**"]), deps = [ ":go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/util:go_default_library", "//pkg/private/xtest:go_default_library", + "//pkg/segment/iface:go_default_library", "@com_github_stretchr_testify//assert:go_default_library", "@com_github_stretchr_testify//require:go_default_library", ], diff --git a/private/topology/json/json.go b/private/topology/json/json.go index f620d51e83..d0c68138dd 100644 --- a/private/topology/json/json.go +++ b/private/topology/json/json.go @@ -24,9 +24,9 @@ import ( "strings" "github.com/scionproto/scion/pkg/log" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" "github.com/scionproto/scion/pkg/private/util" + "github.com/scionproto/scion/pkg/segment/iface" ) // Attribute indicates the capability of a primary AS. @@ -93,8 +93,8 @@ type ServerInfo struct { // BRInfo contains Border Router specific information. type BRInfo struct { - InternalAddr string `json:"internal_addr"` - Interfaces map[common.IfIDType]*BRInterface `json:"interfaces"` + InternalAddr string `json:"internal_addr"` + Interfaces map[iface.ID]*BRInterface `json:"interfaces"` } // GatewayInfo contains SCION gateway information. @@ -108,12 +108,12 @@ type GatewayInfo struct { // BRInterface contains the information for an data-plane BR socket that is external (i.e., facing // the neighboring AS). type BRInterface struct { - Underlay Underlay `json:"underlay,omitempty"` - IA string `json:"isd_as"` - LinkTo string `json:"link_to"` - MTU int `json:"mtu"` - BFD *BFD `json:"bfd,omitempty"` - RemoteIfID common.IfIDType `json:"remote_interface_id,omitempty"` + Underlay Underlay `json:"underlay,omitempty"` + IA string `json:"isd_as"` + LinkTo string `json:"link_to"` + MTU int `json:"mtu"` + BFD *BFD `json:"bfd,omitempty"` + RemoteIfID iface.ID `json:"remote_interface_id,omitempty"` } // Underlay is the underlay information for a BR interface. diff --git a/private/topology/json/json_test.go b/private/topology/json/json_test.go index 25f590e771..43b77a41f8 100644 --- a/private/topology/json/json_test.go +++ b/private/topology/json/json_test.go @@ -25,9 +25,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/util" "github.com/scionproto/scion/pkg/private/xtest" + "github.com/scionproto/scion/pkg/segment/iface" jsontopo "github.com/scionproto/scion/private/topology/json" ) @@ -46,7 +46,7 @@ func TestLoadRawFromFile(t *testing.T) { BorderRouters: map[string]*jsontopo.BRInfo{ "borderrouter6-f00:0:362-1": { InternalAddr: "10.1.0.1:0", - Interfaces: map[common.IfIDType]*jsontopo.BRInterface{ + Interfaces: map[iface.ID]*jsontopo.BRInterface{ 91: { Underlay: jsontopo.Underlay{ Local: "192.0.2.1:4997", @@ -65,7 +65,7 @@ func TestLoadRawFromFile(t *testing.T) { }, "borderrouter6-f00:0:362-9": { InternalAddr: "[2001:db8:a0b:12f0::2]:0", - Interfaces: map[common.IfIDType]*jsontopo.BRInterface{ + Interfaces: map[iface.ID]*jsontopo.BRInterface{ 32: { Underlay: jsontopo.Underlay{ Local: "[2001:db8:a0b:12f0::1]:4997", diff --git a/private/topology/mock_topology/BUILD.bazel b/private/topology/mock_topology/BUILD.bazel index c211287a4f..07635fe2c7 100644 --- a/private/topology/mock_topology/BUILD.bazel +++ b/private/topology/mock_topology/BUILD.bazel @@ -19,7 +19,7 @@ go_library( visibility = ["//visibility:public"], deps = [ "//pkg/addr:go_default_library", - "//pkg/private/common:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/topology:go_default_library", "@com_github_golang_mock//gomock:go_default_library", ], diff --git a/private/topology/mock_topology/mock.go b/private/topology/mock_topology/mock.go index c141aaec03..c218327cf3 100644 --- a/private/topology/mock_topology/mock.go +++ b/private/topology/mock_topology/mock.go @@ -10,7 +10,7 @@ import ( gomock "github.com/golang/mock/gomock" addr "github.com/scionproto/scion/pkg/addr" - common "github.com/scionproto/scion/pkg/private/common" + iface "github.com/scionproto/scion/pkg/segment/iface" topology "github.com/scionproto/scion/private/topology" ) @@ -125,10 +125,10 @@ func (mr *MockTopologyMockRecorder) IFInfoMap() *gomock.Call { } // IfIDs mocks base method. -func (m *MockTopology) IfIDs() []common.IfIDType { +func (m *MockTopology) IfIDs() []iface.ID { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "IfIDs") - ret0, _ := ret[0].([]common.IfIDType) + ret0, _ := ret[0].([]iface.ID) return ret0 } @@ -256,7 +256,7 @@ func (mr *MockTopologyMockRecorder) UnderlayMulticast(arg0 interface{}) *gomock. } // UnderlayNextHop mocks base method. -func (m *MockTopology) UnderlayNextHop(arg0 common.IfIDType) (*net.UDPAddr, bool) { +func (m *MockTopology) UnderlayNextHop(arg0 iface.ID) (*net.UDPAddr, bool) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "UnderlayNextHop", arg0) ret0, _ := ret[0].(*net.UDPAddr) diff --git a/private/topology/reload.go b/private/topology/reload.go index e5ff58c2fc..5f794b44a1 100644 --- a/private/topology/reload.go +++ b/private/topology/reload.go @@ -26,8 +26,8 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/log" "github.com/scionproto/scion/pkg/metrics" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" ) // Validator is used to validate that the topology update is permissible. @@ -133,7 +133,7 @@ func (l *Loader) UnderlayNextHop(ifID uint16) *net.UDPAddr { l.mtx.Lock() defer l.mtx.Unlock() - addr, _ := l.topo.UnderlayNextHop(common.IfIDType(ifID)) + addr, _ := l.topo.UnderlayNextHop(iface.ID(ifID)) return addr } @@ -182,7 +182,7 @@ func (l *Loader) Gateways() ([]GatewayInfo, error) { return l.topo.Gateways() } -func (l *Loader) InterfaceInfoMap() map[common.IfIDType]IFInfo { +func (l *Loader) InterfaceInfoMap() map[iface.ID]IFInfo { l.mtx.Lock() defer l.mtx.Unlock() diff --git a/private/topology/topology.go b/private/topology/topology.go index 4677a61592..1d4a528dba 100644 --- a/private/topology/topology.go +++ b/private/topology/topology.go @@ -29,8 +29,8 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/log" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" jsontopo "github.com/scionproto/scion/private/topology/json" "github.com/scionproto/scion/private/topology/underlay" ) @@ -95,25 +95,25 @@ type ( // InternalAddr is the local data-plane address. InternalAddr netip.AddrPort // IfIDs is a sorted list of the interface IDs. - IfIDs []common.IfIDType + IfIDs []iface.ID // IFs is a map of interface IDs. - IFs map[common.IfIDType]*IFInfo + IFs map[iface.ID]*IFInfo } // IfInfoMap maps interface ids to the interface information. - IfInfoMap map[common.IfIDType]IFInfo + IfInfoMap map[iface.ID]IFInfo // IFInfo describes a border router link to another AS, including the internal data-plane // address applications should send traffic to and information about the link itself and the // remote side of it. IFInfo struct { // ID is the interface ID. It is unique per AS. - ID common.IfIDType + ID iface.ID BRName string InternalAddr netip.AddrPort Local netip.AddrPort Remote netip.AddrPort - RemoteIfID common.IfIDType + RemoteIfID iface.ID IA addr.IA LinkType LinkType MTU int @@ -267,7 +267,7 @@ func (t *RWTopology) populateBR(raw *jsontopo.Topology) error { brInfo := BRInfo{ Name: name, InternalAddr: intAddr, - IFs: make(map[common.IfIDType]*IFInfo), + IFs: make(map[iface.ID]*IFInfo), } for ifID, rawIntf := range rawBr.Interfaces { var err error @@ -474,11 +474,11 @@ func (i *BRInfo) copy() *BRInfo { } } -func copyIFsMap(m map[common.IfIDType]*IFInfo) map[common.IfIDType]*IFInfo { +func copyIFsMap(m map[iface.ID]*IFInfo) map[iface.ID]*IFInfo { if m == nil { return nil } - newM := make(map[common.IfIDType]*IFInfo) + newM := make(map[iface.ID]*IFInfo) for k, v := range m { newM[k] = v.copy() } diff --git a/private/topology/topology_test.go b/private/topology/topology_test.go index 5830dc9b39..65cfcbb632 100644 --- a/private/topology/topology_test.go +++ b/private/topology/topology_test.go @@ -25,7 +25,7 @@ import ( "github.com/stretchr/testify/require" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" + "github.com/scionproto/scion/pkg/segment/iface" jsontopo "github.com/scionproto/scion/private/topology/json" ) @@ -58,10 +58,10 @@ func TestBRs(t *testing.T) { brs := map[string]BRInfo{ "br1-ff00:0:311-1": { - IfIDs: []common.IfIDType{1, 3, 8}, + IfIDs: []iface.ID{1, 3, 8}, }, "br1-ff00:0:311-2": { - IfIDs: []common.IfIDType{11}, + IfIDs: []iface.ID{11}, }, } @@ -312,10 +312,10 @@ func TestBRsCoreAS(t *testing.T) { c := MustLoadTopo(t, "testdata/core.json") brCases := []struct { name string - interfaces []common.IfIDType + interfaces []iface.ID }{ - {name: "borderrouter6-ff00:0:362-1", interfaces: []common.IfIDType{91}}, - {name: "borderrouter6-ff00:0:362-9", interfaces: []common.IfIDType{32}}, + {name: "borderrouter6-ff00:0:362-1", interfaces: []iface.ID{91}}, + {name: "borderrouter6-ff00:0:362-9", interfaces: []iface.ID{32}}, } for _, test := range brCases { t.Run(test.name, func(t *testing.T) { diff --git a/router/BUILD.bazel b/router/BUILD.bazel index 332a12f3b5..caf311a7f1 100644 --- a/router/BUILD.bazel +++ b/router/BUILD.bazel @@ -16,11 +16,11 @@ go_library( "//pkg/drkey:go_default_library", "//pkg/experimental/epic:go_default_library", "//pkg/log:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/processmetrics:go_default_library", "//pkg/private/serrors:go_default_library", "//pkg/private/util:go_default_library", "//pkg/scrypto:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/slayers:go_default_library", "//pkg/slayers/path:go_default_library", "//pkg/slayers/path/empty:go_default_library", diff --git a/router/connector.go b/router/connector.go index e1b48efffa..36c610caa2 100644 --- a/router/connector.go +++ b/router/connector.go @@ -20,8 +20,8 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/log" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/underlay/conn" "github.com/scionproto/scion/router/config" "github.com/scionproto/scion/router/control" @@ -80,7 +80,7 @@ func (c *Connector) AddInternalInterface(ia addr.IA, local netip.AddrPort) error } // AddExternalInterface adds a link between the local and remote address. -func (c *Connector) AddExternalInterface(localIfID common.IfIDType, link control.LinkInfo, +func (c *Connector) AddExternalInterface(localIfID iface.ID, link control.LinkInfo, owned bool) error { c.mtx.Lock() diff --git a/router/control/BUILD.bazel b/router/control/BUILD.bazel index 5cd4a3bee5..18865cdb10 100644 --- a/router/control/BUILD.bazel +++ b/router/control/BUILD.bazel @@ -11,8 +11,8 @@ go_library( deps = [ "//pkg/addr:go_default_library", "//pkg/log:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", + "//pkg/segment/iface:go_default_library", "//private/keyconf:go_default_library", "//private/topology:go_default_library", "@org_golang_x_crypto//pbkdf2:go_default_library", diff --git a/router/control/conf.go b/router/control/conf.go index f9676c12ea..fc8c0520f9 100644 --- a/router/control/conf.go +++ b/router/control/conf.go @@ -22,8 +22,8 @@ import ( "golang.org/x/crypto/pbkdf2" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/private/topology" ) @@ -32,7 +32,7 @@ import ( type Dataplane interface { CreateIACtx(ia addr.IA) error AddInternalInterface(ia addr.IA, local netip.AddrPort) error - AddExternalInterface(localIfID common.IfIDType, info LinkInfo, owned bool) error + AddExternalInterface(localIfID iface.ID, info LinkInfo, owned bool) error AddSvc(ia addr.IA, svc addr.SVC, a netip.AddrPort) error DelSvc(ia addr.IA, svc addr.SVC, a netip.AddrPort) error SetKey(ia addr.IA, index int, key []byte) error @@ -57,7 +57,7 @@ type LinkInfo struct { type LinkEnd struct { IA addr.IA Addr netip.AddrPort - IfID common.IfIDType + IfID iface.ID } type ObservableDataplane interface { @@ -169,7 +169,7 @@ func confExternalInterfaces(dp Dataplane, cfg *Config) error { // nothing to do return nil } - ifIDs := []common.IfIDType{} + ifIDs := []iface.ID{} for k := range infoMap { ifIDs = append(ifIDs, k) } diff --git a/router/control/internal/metrics/BUILD.bazel b/router/control/internal/metrics/BUILD.bazel index a19d47f963..7839e0dcf3 100644 --- a/router/control/internal/metrics/BUILD.bazel +++ b/router/control/internal/metrics/BUILD.bazel @@ -9,8 +9,8 @@ go_library( importpath = "github.com/scionproto/scion/router/control/internal/metrics", visibility = ["//router/control:__subpackages__"], deps = [ - "//pkg/private/common:go_default_library", "//pkg/private/prom:go_default_library", + "//pkg/segment/iface:go_default_library", "@com_github_prometheus_client_golang//prometheus:go_default_library", ], ) diff --git a/router/control/internal/metrics/metrics.go b/router/control/internal/metrics/metrics.go index d33f57af83..ad4392749f 100644 --- a/router/control/internal/metrics/metrics.go +++ b/router/control/internal/metrics/metrics.go @@ -17,8 +17,8 @@ package metrics import ( - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/prom" + "github.com/scionproto/scion/pkg/segment/iface" ) const Namespace = "br" @@ -65,7 +65,7 @@ func (l IntfLabels) Values() []string { return []string{l.Intf, l.NeighIA} } -func IntfToLabel(ifID common.IfIDType) string { +func IntfToLabel(ifID iface.ID) string { if ifID == 0 { return "loc" } diff --git a/scion/cmd/scion/BUILD.bazel b/scion/cmd/scion/BUILD.bazel index db17255736..ad3d2d27d9 100644 --- a/scion/cmd/scion/BUILD.bazel +++ b/scion/cmd/scion/BUILD.bazel @@ -19,8 +19,8 @@ go_library( "//pkg/addr:go_default_library", "//pkg/daemon:go_default_library", "//pkg/log:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//pkg/snet/addrutil:go_default_library", "//pkg/snet/path:go_default_library", diff --git a/scion/cmd/scion/common.go b/scion/cmd/scion/common.go index edf290ed8d..48db32d300 100644 --- a/scion/cmd/scion/common.go +++ b/scion/cmd/scion/common.go @@ -23,8 +23,8 @@ import ( "time" "github.com/scionproto/scion/pkg/addr" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" ) @@ -43,8 +43,8 @@ type Path struct { // Hop represents an hop on the path. type Hop struct { - ID common.IfIDType `json:"interface" yaml:"interface"` - IA addr.IA `json:"isd_as" yaml:"isd_as"` + ID iface.ID `json:"interface" yaml:"interface"` + IA addr.IA `json:"isd_as" yaml:"isd_as"` } // getHops constructs a list of snet path interfaces from an snet path diff --git a/scion/showpaths/BUILD.bazel b/scion/showpaths/BUILD.bazel index 8f3139a275..a2367409aa 100644 --- a/scion/showpaths/BUILD.bazel +++ b/scion/showpaths/BUILD.bazel @@ -11,8 +11,8 @@ go_library( deps = [ "//pkg/addr:go_default_library", "//pkg/daemon:go_default_library", - "//pkg/private/common:go_default_library", "//pkg/private/serrors:go_default_library", + "//pkg/segment/iface:go_default_library", "//pkg/snet:go_default_library", "//private/app/path:go_default_library", "//private/app/path/pathprobe:go_default_library", diff --git a/scion/showpaths/showpaths.go b/scion/showpaths/showpaths.go index 7f5457279e..b0c301d378 100644 --- a/scion/showpaths/showpaths.go +++ b/scion/showpaths/showpaths.go @@ -26,8 +26,8 @@ import ( "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/daemon" - "github.com/scionproto/scion/pkg/private/common" "github.com/scionproto/scion/pkg/private/serrors" + "github.com/scionproto/scion/pkg/segment/iface" "github.com/scionproto/scion/pkg/snet" "github.com/scionproto/scion/private/app/path" "github.com/scionproto/scion/private/app/path/pathprobe" @@ -58,8 +58,8 @@ type Path struct { // Hop represents an hop on the path. type Hop struct { - IfID common.IfIDType `json:"interface"` - IA addr.IA `json:"isd_as"` + IfID iface.ID `json:"interface"` + IA addr.IA `json:"isd_as"` } // Human writes human readable output to the writer. From 07b6b156879370fa7f79a9aa424a2c5a91365896 Mon Sep 17 00:00:00 2001 From: jiceatscion <139873336+jiceatscion@users.noreply.github.com> Date: Thu, 19 Sep 2024 17:17:11 +0200 Subject: [PATCH 28/29] doc: heed RTD admonition regarding the deprecation of html_base_url (#4627) --- doc/conf.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/conf.py b/doc/conf.py index 9f26c8ac5d..a3532826b2 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -4,6 +4,7 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html import subprocess +import os # -- Project information ----------------------------------------------------- @@ -14,6 +15,14 @@ # -- General configuration --------------------------------------------------- +# Set canonical URL from the Read the Docs Domain +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "") + +# Tell Jinja2 templates the build is running on Read the Docs +html_context = {} +if os.environ.get("READTHEDOCS", "") == "True": + html_context["READTHEDOCS"] = True + # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. From 26103217c8074dba85330905ee7d4fae4127fb6f Mon Sep 17 00:00:00 2001 From: Dominik Roos Date: Thu, 19 Sep 2024 21:31:31 +0200 Subject: [PATCH 29/29] docs: add interactive TRC signing ceremony builder (#4624) And an interactive TRC signing ceremony builder. It supports all three types of TRC ceremony: base, regular, and sensitive. The user can select between scion-pki and openssl. Furthermore, support for pkcs11 is available for openssl. In a future iteration, support for scion-pki kms will be added. The builder is intended to be used by a voting (or root CA) participant. The adminstrator role is not supported in this version. (Administrators should be very knowledgable about the TRC ceremony anyway.) The builder is based on aplinejs and tailwindcss. This allows us to included it in our RTD page with zero dependency and build steps. ![image](https://github.com/user-attachments/assets/e02dc043-7233-4713-8267-fa67ce489b2d) [doc] --- doc/Makefile | 3 +- doc/conf.py | 5 + doc/cryptography/index.rst | 1 + .../trc-signing-ceremony-builder.rst | 1020 +++++++++++++++++ tools/cryptoplayground/crypto_lib.sh | 2 +- tools/cryptoplayground/trc_ceremony.sh | 2 +- 6 files changed, 1030 insertions(+), 3 deletions(-) create mode 100644 doc/cryptography/trc-signing-ceremony-builder.rst diff --git a/doc/Makefile b/doc/Makefile index 92fe92a6fa..4da3aebaeb 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -13,6 +13,7 @@ SPHINX_AUTOBUILD ?= bazel run //doc:sphinx-autobuild -- SPHINXOPTS ?= -W --keep-going # treat warnings as errors, but process all files when an error occurs SOURCEDIR = $(abspath .) BUILDDIR = $(abspath ./_build) +HOST ?= localhost # Build docs with Sphinx using the "make mode" option. # Explicitly list the main build targets so they auto-complete in shells. @@ -30,7 +31,7 @@ html latex latexpdf linkcheck help: # Note: most options are forwarded as-is to sphinx, but --keep-going is not understood and we explicitly drop it. .PHONY: autobuild autobuild: - $(SPHINX_AUTOBUILD) "$(SOURCEDIR)" "$(BUILDDIR)" $(filter-out --keep-going,$(SPHINXOPTS)) + $(SPHINX_AUTOBUILD) "--host=$(HOST)" "$(SOURCEDIR)" "$(BUILDDIR)" $(filter-out --keep-going,$(SPHINXOPTS)) .PHONY: clean clean: diff --git a/doc/conf.py b/doc/conf.py index a3532826b2..62230146ea 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -106,3 +106,8 @@ html_css_files = [ "css/custom.css", ] + +html_js_files = [ + "https://unpkg.com/@alpinejs/persist@3.14.1/dist/cdn.min.js", + "https://unpkg.com/alpinejs@3.14.1/dist/cdn.min.js", +] diff --git a/doc/cryptography/index.rst b/doc/cryptography/index.rst index 4945e66f1a..711a58b477 100644 --- a/doc/cryptography/index.rst +++ b/doc/cryptography/index.rst @@ -11,6 +11,7 @@ SCION Cryptography trc-signing-ceremony-preparations trc-signing-ceremony-phases-base trc-signing-ceremony-phases-sensitive + trc-signing-ceremony-builder ca-operations interactions drkey diff --git a/doc/cryptography/trc-signing-ceremony-builder.rst b/doc/cryptography/trc-signing-ceremony-builder.rst new file mode 100644 index 0000000000..d009955111 --- /dev/null +++ b/doc/cryptography/trc-signing-ceremony-builder.rst @@ -0,0 +1,1020 @@ +.. _trc-signing-ceremony-builder: + +.. raw:: html + + + + + +.. raw:: html + + + +
+ + +
+

TRC Ceremony Builder

+ +
+

TRC

+ + + + + + + + + + + + + + + + + + + +
Ceremony Type + +
ISD + +
ISD required
+
Base Number + +
Serial Number + +
+
+ + +
+

Actions

+ + + + + + + + + + + + + + + + + + + + + + + + + +
SelectAction
+ + New sensitive voting certificate
+ + New regular voting certificate
+ + New root certificate
+ + Cast a vote
+
+ + +
+

General Settings

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Working Directory + +
Signing Tool + +
Short ID + +
Short Identifier required
+
Exchange Mechanism + +
Shared Drive + +
Skip Preparation + +
Skip Certificate Exchange + +
Show Expected Output Hints + +
+
+ + +
+

Certificate Subject

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
ISD-AS + +
ISD-AS required
+
Country + +
State + +
Locality + +
Organization + +
Organizational Unit + +
+
+ + + + + + + + + + +
+ + +
+
+ + + + + + + + + + + +
+
+

Phase 2: Creation of Payload

+
+ Follow the instructions of the TRC ceremony adminstrator to + receive the TRC payload. +
+
+ + + + + +
+

2. Check TRC Payload

+
sha256sum
+ + +
+ +
+

3. Inspect TRC Payload

+
scion-pki trc inspect
+ + +
+
+ + +
+
+

Phase 3: Signing of the TRC Payload

+
+ Follow the instructions of the TRC ceremony adminstrator and + create the required signatures. +
+
+ + + + + + + + +
+ + +
+
+

Phase 4: Assembly of the TRC

+
+ Follow the instructions of the TRC ceremony adminstrator to + recieve the signed TRC. This step concludes the ceremony. +
+
+ + + + + +
+

2. Check TRC

+
sha256sum .trc
+ + +
+ +
+

3. Inspect TRC

+
scion-pki trc inspect --predecessor
+ + +
+ +
+

4. Format TRC

+
+ The output of the TRC ceremony is a DER encoded TRC. To convert + it to a more ergonomic PEM format, use the following command. +
+
scion-pki trc format --format pem
+ + +
+
+ +
+ diff --git a/tools/cryptoplayground/crypto_lib.sh b/tools/cryptoplayground/crypto_lib.sh index de3f7917f9..01e225acef 100644 --- a/tools/cryptoplayground/crypto_lib.sh +++ b/tools/cryptoplayground/crypto_lib.sh @@ -92,7 +92,7 @@ in_docker() { -e TRCID=$TRCID \ -e PREDID=$PREDID \ nginx:1.27.1 \ - sh -c "set -e && . /scripts/crypto_lib.sh && $@" + sh -c "set -ex && . /scripts/crypto_lib.sh && $@" } ###################### diff --git a/tools/cryptoplayground/trc_ceremony.sh b/tools/cryptoplayground/trc_ceremony.sh index 7d3e8bd265..6415707094 100755 --- a/tools/cryptoplayground/trc_ceremony.sh +++ b/tools/cryptoplayground/trc_ceremony.sh @@ -12,7 +12,7 @@ export USE_SCION_PKI_SIGN=${USE_SCION_PKI_SIGN:-} . $PLAYGROUND/crypto_lib.sh -set -e +set -ex if [ -z "$USE_SCION_PKI_SIGN" ]; then STARTDATE="20200624120000Z"