diff --git a/.golangcilint.yml b/.golangcilint.yml index 1d87b2c2c1..ddc7b4fa7e 100644 --- a/.golangcilint.yml +++ b/.golangcilint.yml @@ -19,6 +19,7 @@ linters: - lll - misspell - goheader + - contextcheck linters-settings: # ... forbidigo: diff --git a/control/beaconing/originator_test.go b/control/beaconing/originator_test.go index 93147bb778..44d04d0d7e 100644 --- a/control/beaconing/originator_test.go +++ b/control/beaconing/originator_test.go @@ -1,4 +1,5 @@ // Copyright 2019 Anapaya Systems +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -94,10 +95,10 @@ func TestOriginatorRun(t *testing.T) { sender := mock_beaconing.NewMockSender(mctrl) sender.EXPECT().Send(gomock.Any(), gomock.Any()).Times(1).DoAndReturn( - func(_ context.Context, b *seg.PathSegment) error { + func(ctx context.Context, b *seg.PathSegment) error { // Check the beacon is valid and verifiable. assert.NoError(t, b.Validate(seg.ValidateBeacon)) - assert.NoError(t, b.VerifyASEntry(context.Background(), + assert.NoError(t, b.VerifyASEntry(ctx, segVerifier{pubKey: pub}, b.MaxIdx())) // Extract the hop field from the current AS entry to compare. hopF := b.ASEntries[b.MaxIdx()].HopEntry.HopField diff --git a/control/drkey/grpc/drkey_service.go b/control/drkey/grpc/drkey_service.go index 5821722025..e91840031e 100644 --- a/control/drkey/grpc/drkey_service.go +++ b/control/drkey/grpc/drkey_service.go @@ -1,4 +1,5 @@ // Copyright 2022 ETH Zurich +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -41,7 +42,7 @@ type Engine interface { GetSecretValue(ctx context.Context, meta drkey.SecretValueMeta) (drkey.SecretValue, error) GetLevel1Key(ctx context.Context, meta drkey.Level1Meta) (drkey.Level1Key, error) - DeriveLevel1(meta drkey.Level1Meta) (drkey.Level1Key, error) + DeriveLevel1(ctx context.Context, meta drkey.Level1Meta) (drkey.Level1Key, error) DeriveASHost(ctx context.Context, meta drkey.ASHostMeta) (drkey.ASHostKey, error) DeriveHostAS(ctx context.Context, meta drkey.HostASMeta) (drkey.HostASKey, error) DeriveHostHost(ctx context.Context, meta drkey.HostHostMeta) (drkey.HostHostKey, error) @@ -66,7 +67,6 @@ func (d *Server) DRKeyLevel1( ctx context.Context, req *cppb.DRKeyLevel1Request, ) (*cppb.DRKeyLevel1Response, error) { - peer, ok := peer.FromContext(ctx) if !ok { return nil, serrors.New("cannot retrieve peer information from ctx") @@ -87,7 +87,7 @@ func (d *Server) DRKeyLevel1( "proto_id", lvl1Meta.ProtoId) } - lvl1Key, err := d.Engine.DeriveLevel1(lvl1Meta) + lvl1Key, err := d.Engine.DeriveLevel1(ctx, lvl1Meta) if err != nil { return nil, serrors.Wrap("deriving level 1 key", err) } @@ -100,7 +100,6 @@ func (d *Server) DRKeyIntraLevel1( ctx context.Context, req *cppb.DRKeyIntraLevel1Request, ) (*cppb.DRKeyIntraLevel1Response, error) { - peer, ok := peer.FromContext(ctx) if !ok { return nil, serrors.New("cannot retrieve peer information from ctx") @@ -132,7 +131,6 @@ func (d *Server) DRKeyASHost( ctx context.Context, req *cppb.DRKeyASHostRequest, ) (*cppb.DRKeyASHostResponse, error) { - peer, ok := peer.FromContext(ctx) if !ok { return nil, serrors.New("cannot retrieve peer information from ctx") @@ -160,7 +158,6 @@ func (d *Server) DRKeyHostAS( ctx context.Context, req *cppb.DRKeyHostASRequest, ) (*cppb.DRKeyHostASResponse, error) { - peer, ok := peer.FromContext(ctx) if !ok { return nil, serrors.New("cannot retrieve peer information from ctx") @@ -187,7 +184,6 @@ func (d *Server) DRKeyHostHost( ctx context.Context, req *cppb.DRKeyHostHostRequest, ) (*cppb.DRKeyHostHostResponse, error) { - peer, ok := peer.FromContext(ctx) if !ok { return nil, serrors.New("cannot retrieve peer information from ctx") @@ -215,7 +211,6 @@ func (d *Server) DRKeySecretValue( ctx context.Context, req *cppb.DRKeySecretValueRequest, ) (*cppb.DRKeySecretValueResponse, error) { - peer, ok := peer.FromContext(ctx) if !ok { return nil, serrors.New("cannot retrieve peer information from ctx") @@ -363,7 +358,8 @@ func hostAddrFromPeer(peerAddr net.Addr) (net.IP, error) { } func getMeta(protoId drkeypb.Protocol, ts *timestamppb.Timestamp, srcIA, - dstIA addr.IA) (drkey.Level1Meta, error) { + dstIA addr.IA, +) (drkey.Level1Meta, error) { err := ts.CheckValid() if err != nil { return drkey.Level1Meta{}, serrors.Wrap("invalid valTime from pb req", err) diff --git a/control/drkey/grpc/fetcher_test.go b/control/drkey/grpc/fetcher_test.go index 9b2593b7fe..c440b1f59a 100644 --- a/control/drkey/grpc/fetcher_test.go +++ b/control/drkey/grpc/fetcher_test.go @@ -1,4 +1,5 @@ // Copyright 2022 ETH Zurich +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -62,7 +63,7 @@ func TestLevel1KeyFetching(t *testing.T) { ctrl := gomock.NewController(t) lvl1db := mock_grpc.NewMockEngine(ctrl) - lvl1db.EXPECT().DeriveLevel1(gomock.Any()).AnyTimes().Return(drkey.Level1Key{}, nil) + lvl1db.EXPECT().DeriveLevel1(gomock.Any(), gomock.Any()).AnyTimes().Return(drkey.Level1Key{}, nil) db := mock_trust.NewMockDB(ctrl) db.EXPECT().SignedTRC(gomock.Any(), gomock.Any()).AnyTimes().Return(trc, nil) @@ -94,7 +95,6 @@ func TestLevel1KeyFetching(t *testing.T) { for name, tc := range testCases { t.Run(name, func(t *testing.T) { - // TODO(matzf): change xtest library to allow specifying the client // credentials for individual calls so that server does not need to be // recreated here. diff --git a/control/drkey/grpc/mock_grpc/mock.go b/control/drkey/grpc/mock_grpc/mock.go index d1643e24b2..629eed9329 100644 --- a/control/drkey/grpc/mock_grpc/mock.go +++ b/control/drkey/grpc/mock_grpc/mock.go @@ -81,18 +81,18 @@ func (mr *MockEngineMockRecorder) DeriveHostHost(arg0, arg1 interface{}) *gomock } // DeriveLevel1 mocks base method. -func (m *MockEngine) DeriveLevel1(arg0 drkey.Level1Meta) (drkey.Level1Key, error) { +func (m *MockEngine) DeriveLevel1(arg0 context.Context, arg1 drkey.Level1Meta) (drkey.Level1Key, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeriveLevel1", arg0) + ret := m.ctrl.Call(m, "DeriveLevel1", arg0, arg1) ret0, _ := ret[0].(drkey.Level1Key) ret1, _ := ret[1].(error) return ret0, ret1 } // DeriveLevel1 indicates an expected call of DeriveLevel1. -func (mr *MockEngineMockRecorder) DeriveLevel1(arg0 interface{}) *gomock.Call { +func (mr *MockEngineMockRecorder) DeriveLevel1(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeriveLevel1", reflect.TypeOf((*MockEngine)(nil).DeriveLevel1), arg0) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeriveLevel1", reflect.TypeOf((*MockEngine)(nil).DeriveLevel1), arg0, arg1) } // GetLevel1Key mocks base method. diff --git a/control/drkey/service_engine.go b/control/drkey/service_engine.go index c9c0641b06..084e641c54 100644 --- a/control/drkey/service_engine.go +++ b/control/drkey/service_engine.go @@ -1,4 +1,5 @@ // Copyright 2022 ETH Zurich +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,7 +35,7 @@ type Fetcher interface { // Level1PrefetchListKeeper maintains a list for those level1 keys // that are recently/frequently used. type Level1PrefetchListKeeper interface { - //Update updates the keys in Level1Cache based on the Level1Key metadata. + // Update updates the keys in Level1Cache based on the Level1Key metadata. Update(key Level1PrefetchInfo) // GetLevel1InfoArray retrieves an array whose members contains information regarding // level1 keys to prefetch. @@ -63,7 +64,6 @@ func (s *ServiceEngine) GetSecretValue( ctx context.Context, meta drkey.SecretValueMeta, ) (drkey.SecretValue, error) { - return s.SecretBackend.getSecretValue(ctx, meta) } @@ -73,7 +73,6 @@ func (s *ServiceEngine) GetLevel1Key( ctx context.Context, meta drkey.Level1Meta, ) (drkey.Level1Key, error) { - key, err := s.getLevel1Key(ctx, meta) if err == nil && ctx.Value(fromPrefetcher{}) == nil && meta.SrcIA != s.LocalIA { keyInfo := Level1PrefetchInfo{ @@ -91,8 +90,8 @@ func (s *ServiceEngine) GetLevel1PrefetchInfo() []Level1PrefetchInfo { } // DeriveLevel1 returns a Level1 key based on the presented information. -func (s *ServiceEngine) DeriveLevel1(meta drkey.Level1Meta) (drkey.Level1Key, error) { - sv, err := s.GetSecretValue(context.Background(), drkey.SecretValueMeta{ +func (s *ServiceEngine) DeriveLevel1(ctx context.Context, meta drkey.Level1Meta) (drkey.Level1Key, error) { + sv, err := s.GetSecretValue(ctx, drkey.SecretValueMeta{ ProtoId: meta.ProtoId, Validity: meta.Validity, }) @@ -111,7 +110,6 @@ func (s *ServiceEngine) DeriveASHost( ctx context.Context, meta drkey.ASHostMeta, ) (drkey.ASHostKey, error) { - var key drkey.Key var err error @@ -146,7 +144,6 @@ func (s *ServiceEngine) DeriveHostAS( ctx context.Context, meta drkey.HostASMeta, ) (drkey.HostASKey, error) { - var key drkey.Key var err error @@ -182,7 +179,6 @@ func (s *ServiceEngine) DeriveHostHost( ctx context.Context, meta drkey.HostHostMeta, ) (drkey.HostHostKey, error) { - hostASMeta := drkey.HostASMeta{ ProtoId: meta.ProtoId, Validity: meta.Validity, @@ -238,9 +234,8 @@ func (s *ServiceEngine) getLevel1Key( ctx context.Context, meta drkey.Level1Meta, ) (drkey.Level1Key, error) { - if meta.SrcIA == s.LocalIA { - return s.DeriveLevel1(meta) + return s.DeriveLevel1(ctx, meta) } if meta.DstIA != s.LocalIA { @@ -278,7 +273,6 @@ func (s *ServiceEngine) obtainLevel1Key( srcIA addr.IA, dstIA addr.IA, ) (drkey.Level1Key, error) { - if !proto.IsPredefined() { proto = drkey.Generic } @@ -289,7 +283,6 @@ func (s *ServiceEngine) obtainLevel1Key( ProtoId: proto, } return s.GetLevel1Key(ctx, level1Meta) - } type fromPrefetcher struct{} diff --git a/control/drkey/service_engine_test.go b/control/drkey/service_engine_test.go index b524a0a834..8905aefd87 100644 --- a/control/drkey/service_engine_test.go +++ b/control/drkey/service_engine_test.go @@ -1,4 +1,5 @@ // Copyright 2022 ETH Zurich +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -89,7 +90,7 @@ func TestDeriveLevel1Key(t *testing.T) { Validity: time.Now(), } - key, err := store.DeriveLevel1(meta) + key, err := store.DeriveLevel1(context.Background(), meta) assert.NoError(t, err) assert.Equal(t, meta.DstIA, key.DstIA) assert.Equal(t, meta.ProtoId, key.ProtoId) @@ -135,7 +136,7 @@ func TestDeriveHostAS(t *testing.T) { PrefetchKeeper: cache, } - var tests = []drkey.Protocol{ + tests := []drkey.Protocol{ drkey.SCMP, drkey.Protocol(7), } @@ -231,7 +232,7 @@ func TestGetLevel1Key(t *testing.T) { }) assert.NoError(t, err) assert.Equal(t, secondLevel1Key, rcvKey3) - //Simulate a call coming from the prefetcher, it must not update cache + // Simulate a call coming from the prefetcher, it must not update cache pref_ctx := context.WithValue(context.Background(), cs_drkey.FromPrefetcher(), true) rcvKey4, err := store.GetLevel1Key(pref_ctx, drkey.Level1Meta{ ProtoId: firstLevel1Key.ProtoId, @@ -258,7 +259,6 @@ func TestGetLevel1Key(t *testing.T) { } _, err = store.GetLevel1Key(context.Background(), locallvl1Meta) assert.NoError(t, err) - } func newLevel1Database(t *testing.T) *level1_sql.Backend { diff --git a/control/trust.go b/control/trust.go index cff947de3d..6308d98832 100644 --- a/control/trust.go +++ b/control/trust.go @@ -1,4 +1,5 @@ // Copyright 2020 Anapaya Systems +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -33,7 +34,7 @@ import ( func LoadTrustMaterial(ctx context.Context, configDir string, db trust.DB) error { logger := log.FromCtx(ctx) certsDir := filepath.Join(configDir, "certs") - loaded, err := trust.LoadTRCs(context.Background(), certsDir, db) + loaded, err := trust.LoadTRCs(ctx, certsDir, db) if err != nil { return serrors.Wrap("loading TRCs from disk", err) } @@ -46,7 +47,7 @@ func LoadTrustMaterial(ctx context.Context, configDir string, db trust.DB) error logger.Info("Ignoring non-TRC", "file", f, "reason", r) } localCertsDir := filepath.Join(configDir, "crypto/as") - loaded, err = trust.LoadChains(context.Background(), localCertsDir, db) + loaded, err = trust.LoadChains(ctx, localCertsDir, db) if err != nil { return serrors.Wrap("loading certificate chains from disk", err) } @@ -71,7 +72,6 @@ func NewTLSCertificateLoader( db trust.DB, cfgDir string, ) cstrust.TLSCertificateLoader { - return cstrust.TLSCertificateLoader{ SignerGen: newCachingSignerGen(ia, extKeyUsage, db, cfgDir), } @@ -100,7 +100,6 @@ func newCachingSignerGen( db trust.DB, cfgDir string, ) *cstrust.CachingSignerGen { - gen := trust.SignerGen{ IA: ia, DB: &cstrust.CryptoLoader{ diff --git a/daemon/cmd/daemon/main.go b/daemon/cmd/daemon/main.go index 03c984190b..abed31690e 100644 --- a/daemon/cmd/daemon/main.go +++ b/daemon/cmd/daemon/main.go @@ -1,4 +1,5 @@ // Copyright 2020 Anapaya Systems +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -151,7 +152,7 @@ func realMain(ctx context.Context) error { []string{"driver", "operation", prom.LabelResult}, ), }) - engine, err := daemon.TrustEngine(globalCfg.General.ConfigDir, topo.IA(), trustDB, dialer) + engine, err := daemon.TrustEngine(ctx, globalCfg.General.ConfigDir, topo.IA(), trustDB, dialer) if err != nil { return serrors.Wrap("creating trust engine", err) } @@ -361,8 +362,8 @@ func realMain(ctx context.Context) error { type acceptAllVerifier struct{} func (acceptAllVerifier) Verify(ctx context.Context, signedMsg *cryptopb.SignedMessage, - associatedData ...[]byte) (*signed.Message, error) { - + associatedData ...[]byte, +) (*signed.Message, error) { return nil, nil } diff --git a/daemon/daemon.go b/daemon/daemon.go index aa9476fca9..37bbe95b3e 100644 --- a/daemon/daemon.go +++ b/daemon/daemon.go @@ -1,4 +1,5 @@ // Copyright 2018 ETH Zurich, Anapaya Systems +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -54,13 +55,14 @@ func InitTracer(tracing env.Tracing, id string) (io.Closer, error) { // TrustEngine builds the trust engine backed by the trust database. func TrustEngine( + ctx context.Context, cfgDir string, ia addr.IA, db trust.DB, dialer libgrpc.Dialer, ) (trust.Engine, error) { certsDir := filepath.Join(cfgDir, "certs") - loaded, err := trust.LoadTRCs(context.Background(), certsDir, db) + loaded, err := trust.LoadTRCs(ctx, certsDir, db) if err != nil { return trust.Engine{}, serrors.Wrap("loading TRCs", err) } @@ -72,11 +74,10 @@ func TrustEngine( } log.Info("Ignoring non-TRC", "file", f, "reason", r) } - loaded, err = trust.LoadChains(context.Background(), certsDir, db) + loaded, err = trust.LoadChains(ctx, certsDir, db) if err != nil { 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/gateway/control/remotemonitor.go b/gateway/control/remotemonitor.go index 57ddd15666..473bf9cd87 100644 --- a/gateway/control/remotemonitor.go +++ b/gateway/control/remotemonitor.go @@ -1,4 +1,5 @@ // Copyright 2020 Anapaya Systems +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -106,7 +107,7 @@ func (rm *RemoteMonitor) run(ctx context.Context) error { for { select { case ias := <-rm.IAs: - rm.process(ctx, ias) + rm.process(log.FromCtx(ctx), ias) case <-rm.workerBase.GetDoneChan(): rm.cancel() return nil @@ -114,10 +115,10 @@ func (rm *RemoteMonitor) run(ctx context.Context) error { } } -func (rm *RemoteMonitor) process(ctx context.Context, ias []addr.IA) { +//nolint:contextcheck // Providing a context is not necessary in this case. +func (rm *RemoteMonitor) process(logger log.Logger, ias []addr.IA) { rm.stateMtx.Lock() defer rm.stateMtx.Unlock() - logger := log.FromCtx(ctx) newWatchers := make(map[addr.IA]watcherEntry) for _, ia := range ias { we, ok := rm.currentWatchers[ia] diff --git a/private/periodic/periodic.go b/private/periodic/periodic.go index 52a1ca368f..b520c41d0f 100644 --- a/private/periodic/periodic.go +++ b/private/periodic/periodic.go @@ -1,4 +1,5 @@ // Copyright 2018 Anapaya Systems +// Copyright 2025 SCION Association // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -115,6 +116,8 @@ func Start(task Task, period, timeout time.Duration) *Runner { // StartWithMetrics is identical to Start but allows the caller to // specify the metric or no metric at all to be used. +// +//nolint:contextcheck // Providing a context is not necessary in this case. func StartWithMetrics(task Task, metric *Metrics, period, timeout time.Duration) *Runner { ctx, cancelF := context.WithCancel(context.Background()) logger := log.New("debug_id", log.NewDebugID())