From 61176af14eff830a2c23b1a3cb96180b6f631804 Mon Sep 17 00:00:00 2001
From: Patrick Pacher <patrick.pacher@gmail.com>
Date: Wed, 27 Mar 2024 16:17:58 +0100
Subject: [PATCH] Fix linting errors

---
 .golangci.yml                                 |  3 +++
 assets/icons_default.go                       |  5 ++--
 cmds/notifier/http_api.go                     | 18 +++++++-------
 cmds/notifier/icons.go                        |  2 +-
 cmds/notifier/main.go                         |  2 ++
 cmds/notifier/notification.go                 |  7 +++---
 cmds/notifier/notify.go                       |  1 -
 cmds/notifier/notify_linux.go                 | 12 +++++++---
 cmds/notifier/spn.go                          |  7 +++---
 cmds/notifier/subsystems.go                   |  5 ++--
 cmds/notifier/tray.go                         |  3 +--
 cmds/portmaster-start/lock.go                 |  2 +-
 service/core/api.go                           | 11 +++++----
 .../firewall/interception/nfq/conntrack.go    |  5 ++--
 service/firewall/packet_handler.go            | 12 ----------
 service/intel/entity.go                       |  4 ++--
 service/intel/filterlists/decoder.go          | 14 ++++++-----
 service/intel/geoip/lookup.go                 |  4 ++--
 service/nameserver/module.go                  |  4 +---
 service/nameserver/nameserver.go              | 16 +++++++------
 service/netquery/active_chart_handler.go      |  4 ++--
 service/netquery/bandwidth_chart_handler.go   |  4 ++--
 service/netquery/manager.go                   |  8 +++----
 service/netquery/orm/decoder.go               | 18 +++++++-------
 service/netquery/orm/encoder.go               |  3 ++-
 service/netquery/orm/encoder_test.go          |  5 ++--
 service/netquery/orm/schema_builder.go        |  2 +-
 service/netquery/orm/schema_builder_test.go   |  3 ++-
 service/netquery/query_handler.go             |  6 +++--
 service/netquery/query_test.go                |  4 ++--
 service/network/api.go                        |  8 +++----
 service/network/connection.go                 |  2 ++
 service/network/packet/packet.go              | 13 +++++-----
 service/network/socket/socket.go              |  2 +-
 service/process/api.go                        |  3 +--
 service/process/database.go                   |  3 ++-
 service/status/module.go                      |  2 +-
 service/updates/helper/indexes.go             | 10 ++++----
 service/updates/main.go                       |  4 ++--
 spn/access/api.go                             |  5 ++--
 spn/captain/navigation.go                     |  4 ++--
 spn/crew/connect.go                           |  4 ++--
 spn/hub/format_test.go                        | 24 +++++++++----------
 spn/hub/transport_test.go                     |  9 +++----
 spn/navigator/optimize_region.go              |  4 ++--
 spn/navigator/update.go                       |  6 ++---
 spn/ships/http_shared_test.go                 | 21 ++++++++--------
 spn/sluice/sluice.go                          |  2 +-
 48 files changed, 167 insertions(+), 153 deletions(-)

diff --git a/.golangci.yml b/.golangci.yml
index 9893ff74..d6892cbc 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -38,6 +38,9 @@ linters:
     - whitespace
     - wrapcheck
     - wsl
+    - perfsprint # TODO(ppacher): we should re-enanble this one to avoid costly fmt.* calls in the hot-path
+    - testifylint
+    - gomoddirectives
 
 linters-settings:
   revive:
diff --git a/assets/icons_default.go b/assets/icons_default.go
index 2c1b6eb1..2530f309 100644
--- a/assets/icons_default.go
+++ b/assets/icons_default.go
@@ -9,8 +9,9 @@ import (
 	"image"
 	"image/png"
 
-	"github.com/safing/portbase/log"
 	"golang.org/x/image/draw"
+
+	"github.com/safing/portbase/log"
 )
 
 // Colored Icon IDs.
@@ -35,7 +36,7 @@ var (
 	//go:embed data/icons/pm_light_blue_512.png
 	BluePNG []byte
 
-	// ColoredIcons holds all the icons as .PNGs
+	// ColoredIcons holds all the icons as .PNGs.
 	ColoredIcons [4][]byte
 )
 
diff --git a/cmds/notifier/http_api.go b/cmds/notifier/http_api.go
index bb0eebf3..356b81cd 100644
--- a/cmds/notifier/http_api.go
+++ b/cmds/notifier/http_api.go
@@ -2,7 +2,7 @@ package main
 
 import (
 	"fmt"
-	"io/ioutil"
+	"io"
 	"net/http"
 	"net/http/cookiejar"
 	"strings"
@@ -16,9 +16,7 @@ const (
 	apiShutdownEndpoint = "core/shutdown"
 )
 
-var (
-	httpApiClient *http.Client
-)
+var httpAPIClient *http.Client
 
 func init() {
 	// Make cookie jar.
@@ -29,22 +27,22 @@ func init() {
 	}
 
 	// Create client.
-	httpApiClient = &http.Client{
+	httpAPIClient = &http.Client{
 		Jar:     jar,
 		Timeout: 3 * time.Second,
 	}
 }
 
-func httpApiAction(endpoint string) (response string, err error) {
+func httpAPIAction(endpoint string) (response string, err error) {
 	// Make action request.
-	resp, err := httpApiClient.Post(apiBaseURL+endpoint, "", nil)
+	resp, err := httpAPIClient.Post(apiBaseURL+endpoint, "", nil)
 	if err != nil {
 		return "", fmt.Errorf("request failed: %w", err)
 	}
 
 	// Read the response body.
-	defer resp.Body.Close()
-	respData, err := ioutil.ReadAll(resp.Body)
+	defer func() { _ = resp.Body.Close() }()
+	respData, err := io.ReadAll(resp.Body)
 	if err != nil {
 		return "", fmt.Errorf("failed to read data: %w", err)
 	}
@@ -60,6 +58,6 @@ func httpApiAction(endpoint string) (response string, err error) {
 
 // TriggerShutdown triggers a shutdown via the APi.
 func TriggerShutdown() error {
-	_, err := httpApiAction(apiShutdownEndpoint)
+	_, err := httpAPIAction(apiShutdownEndpoint)
 	return err
 }
diff --git a/cmds/notifier/icons.go b/cmds/notifier/icons.go
index 93b3db74..b3690a3f 100644
--- a/cmds/notifier/icons.go
+++ b/cmds/notifier/icons.go
@@ -18,7 +18,7 @@ func ensureAppIcon() (location string, err error) {
 		if appIconPath == "" {
 			appIconPath = filepath.Join(dataDir, "exec", "portmaster.png")
 		}
-		err = os.WriteFile(appIconPath, icons.PNG, 0o0644)
+		err = os.WriteFile(appIconPath, icons.PNG, 0o0644) // nolint:gosec
 	})
 
 	return appIconPath, err
diff --git a/cmds/notifier/main.go b/cmds/notifier/main.go
index 8bd95b3b..4cc9f84c 100644
--- a/cmds/notifier/main.go
+++ b/cmds/notifier/main.go
@@ -52,6 +52,8 @@ var (
 	}
 )
 
+const query = "query "
+
 func init() {
 	flag.StringVar(&dataDir, "data", "", "set data directory")
 	flag.BoolVar(&printStackOnExit, "print-stack-on-exit", false, "prints the stack before of shutting down")
diff --git a/cmds/notifier/notification.go b/cmds/notifier/notification.go
index fc37690b..075dba83 100644
--- a/cmds/notifier/notification.go
+++ b/cmds/notifier/notification.go
@@ -14,7 +14,7 @@ type Notification struct {
 	systemID NotificationID
 }
 
-// IsSupported returns whether the action is supported on this system.
+// IsSupportedAction returns whether the action is supported on this system.
 func IsSupportedAction(a pbnotify.Action) bool {
 	switch a.Type {
 	case pbnotify.ActionTypeNone:
@@ -26,11 +26,10 @@ func IsSupportedAction(a pbnotify.Action) bool {
 
 // SelectAction sends an action back to the portmaster.
 func (n *Notification) SelectAction(action string) {
-	new := &pbnotify.Notification{
+	upd := &pbnotify.Notification{
 		EventID:          n.EventID,
 		SelectedActionID: action,
 	}
 
-	// FIXME: check response
-	apiClient.Update(fmt.Sprintf("%s%s", dbNotifBasePath, new.EventID), new, nil)
+	_ = apiClient.Update(fmt.Sprintf("%s%s", dbNotifBasePath, upd.EventID), upd, nil)
 }
diff --git a/cmds/notifier/notify.go b/cmds/notifier/notify.go
index 1b271b67..2286dff6 100644
--- a/cmds/notifier/notify.go
+++ b/cmds/notifier/notify.go
@@ -9,7 +9,6 @@ import (
 	"github.com/safing/portbase/api/client"
 	"github.com/safing/portbase/formats/dsd"
 	"github.com/safing/portbase/log"
-
 	pbnotify "github.com/safing/portbase/notifications"
 )
 
diff --git a/cmds/notifier/notify_linux.go b/cmds/notifier/notify_linux.go
index bcf650cf..ba3f638e 100644
--- a/cmds/notifier/notify_linux.go
+++ b/cmds/notifier/notify_linux.go
@@ -2,9 +2,11 @@ package main
 
 import (
 	"context"
+	"errors"
 	"sync"
 
 	notify "github.com/dhaavi/go-notify"
+
 	"github.com/safing/portbase/log"
 )
 
@@ -45,7 +47,12 @@ listenForNotifications:
 				continue listenForNotifications
 			}
 
-			notification := n.(*Notification)
+			notification, ok := n.(*Notification)
+			if !ok {
+				log.Errorf("received invalid notification type %T", n)
+
+				continue listenForNotifications
+			}
 
 			log.Tracef("notify: received signal: %+v", sig)
 			if sig.ActionKey != "" {
@@ -62,7 +69,6 @@ listenForNotifications:
 			}
 		}
 	}
-
 }
 
 func actionListener() {
@@ -71,7 +77,7 @@ func actionListener() {
 	go handleActions(mainCtx, actions)
 
 	err := notify.SignalNotify(mainCtx, actions)
-	if err != nil && err != context.Canceled {
+	if err != nil && errors.Is(err, context.Canceled) {
 		log.Errorf("notify: signal listener failed: %s", err)
 	}
 }
diff --git a/cmds/notifier/spn.go b/cmds/notifier/spn.go
index 1da5639d..d313716b 100644
--- a/cmds/notifier/spn.go
+++ b/cmds/notifier/spn.go
@@ -4,10 +4,11 @@ import (
 	"sync"
 	"time"
 
+	"github.com/tevino/abool"
+
 	"github.com/safing/portbase/api/client"
 	"github.com/safing/portbase/formats/dsd"
 	"github.com/safing/portbase/log"
-	"github.com/tevino/abool"
 )
 
 const (
@@ -48,10 +49,10 @@ func updateSPNStatus(s *SPNStatus) {
 }
 
 func spnStatusClient() {
-	moduleQueryOp := apiClient.Qsub("query "+spnModuleKey, handleSPNModuleUpdate)
+	moduleQueryOp := apiClient.Qsub(query+spnModuleKey, handleSPNModuleUpdate)
 	moduleQueryOp.EnableResuscitation()
 
-	statusQueryOp := apiClient.Qsub("query "+spnStatusKey, handleSPNStatusUpdate)
+	statusQueryOp := apiClient.Qsub(query+spnStatusKey, handleSPNStatusUpdate)
 	statusQueryOp.EnableResuscitation()
 }
 
diff --git a/cmds/notifier/subsystems.go b/cmds/notifier/subsystems.go
index f810538c..8444bf13 100644
--- a/cmds/notifier/subsystems.go
+++ b/cmds/notifier/subsystems.go
@@ -1,7 +1,6 @@
 package main
 
 import (
-	"fmt"
 	"sync"
 
 	"github.com/safing/portbase/api/client"
@@ -14,7 +13,7 @@ const (
 
 	// Module Failure Status Values
 	// FailureNone    = 0 // unused
-	// FailureHint    = 1 // unused
+	// FailureHint    = 1 // unused.
 	FailureWarning = 2
 	FailureError   = 3
 )
@@ -92,7 +91,7 @@ func clearSubsystems() {
 }
 
 func subsystemsClient() {
-	subsystemsOp := apiClient.Qsub(fmt.Sprintf("query %s", subsystemsKeySpace), handleSubsystem)
+	subsystemsOp := apiClient.Qsub("query "+subsystemsKeySpace, handleSubsystem)
 	subsystemsOp.EnableResuscitation()
 }
 
diff --git a/cmds/notifier/tray.go b/cmds/notifier/tray.go
index 5766611f..4044d4f7 100644
--- a/cmds/notifier/tray.go
+++ b/cmds/notifier/tray.go
@@ -102,7 +102,6 @@ func onReady() {
 }
 
 func onExit() {
-
 }
 
 func triggerTrayUpdate() {
@@ -172,7 +171,7 @@ func updateTray() {
 	// Set SPN status if changed.
 	if spnStatus != nil && activeSPNStatus != spnStatus.Status {
 		activeSPNStatus = spnStatus.Status
-		menuItemSPNStatus.SetTitle("SPN: " + strings.Title(activeSPNStatus))
+		menuItemSPNStatus.SetTitle("SPN: " + strings.Title(activeSPNStatus)) // nolint:staticcheck
 	}
 
 	// Set SPN switch if changed.
diff --git a/cmds/portmaster-start/lock.go b/cmds/portmaster-start/lock.go
index 0db86606..0526084c 100644
--- a/cmds/portmaster-start/lock.go
+++ b/cmds/portmaster-start/lock.go
@@ -79,7 +79,7 @@ func createInstanceLock(lockFilePath string) error {
 
 	// create lock file
 	// TODO: Investigate required permissions.
-	err = os.WriteFile(lockFilePath, []byte(fmt.Sprintf("%d", os.Getpid())), 0o0666) //nolint:gosec
+	err = os.WriteFile(lockFilePath, []byte(strconv.Itoa(os.Getpid())), 0o0666) //nolint:gosec
 	if err != nil {
 		return err
 	}
diff --git a/service/core/api.go b/service/core/api.go
index 8e7d24bc..abc43dad 100644
--- a/service/core/api.go
+++ b/service/core/api.go
@@ -3,6 +3,7 @@ package core
 import (
 	"context"
 	"encoding/hex"
+	"errors"
 	"fmt"
 	"net/http"
 	"net/url"
@@ -23,6 +24,8 @@ import (
 	"github.com/safing/portmaster/spn/captain"
 )
 
+var errInvalidReadPermission = errors.New("invalid read permission")
+
 func registerAPIEndpoints() error {
 	if err := api.RegisterEndpoint(api.Endpoint{
 		Path:  "core/shutdown",
@@ -207,10 +210,10 @@ func authorizeApp(ar *api.Request) (interface{}, error) {
 	// convert the requested read and write permissions to their api.Permission
 	// value. This ensures only "user" or "admin" permissions can be requested.
 	if getSavePermission(readPermStr) <= api.NotSupported {
-		return nil, fmt.Errorf("invalid read permission")
+		return nil, errInvalidReadPermission
 	}
 	if getSavePermission(writePermStr) <= api.NotSupported {
-		return nil, fmt.Errorf("invalid read permission")
+		return nil, errInvalidReadPermission
 	}
 
 	proc, err := process.GetProcessByRequestOrigin(ar)
@@ -281,7 +284,7 @@ func authorizeApp(ar *api.Request) (interface{}, error) {
 	select {
 	case key := <-ch:
 		if len(key) == 0 {
-			return nil, fmt.Errorf("access denied")
+			return nil, errors.New("access denied")
 		}
 
 		return map[string]interface{}{
@@ -289,6 +292,6 @@ func authorizeApp(ar *api.Request) (interface{}, error) {
 			"validUntil": validUntil,
 		}, nil
 	case <-ar.Context().Done():
-		return nil, fmt.Errorf("timeout")
+		return nil, errors.New("timeout")
 	}
 }
diff --git a/service/firewall/interception/nfq/conntrack.go b/service/firewall/interception/nfq/conntrack.go
index 6959d328..ea7761e4 100644
--- a/service/firewall/interception/nfq/conntrack.go
+++ b/service/firewall/interception/nfq/conntrack.go
@@ -4,6 +4,7 @@ package nfq
 
 import (
 	"encoding/binary"
+	"errors"
 	"fmt"
 
 	ct "github.com/florianl/go-conntrack"
@@ -35,7 +36,7 @@ func TeardownNFCT() {
 // DeleteAllMarkedConnection deletes all marked entries from the conntrack table.
 func DeleteAllMarkedConnection() error {
 	if nfct == nil {
-		return fmt.Errorf("nfq: nfct not initialized")
+		return errors.New("nfq: nfct not initialized")
 	}
 
 	// Delete all ipv4 marked connections
@@ -87,7 +88,7 @@ func deleteMarkedConnections(nfct *ct.Nfct, f ct.Family) (deleted int) {
 // DeleteMarkedConnection removes a specific connection from the conntrack table.
 func DeleteMarkedConnection(conn *network.Connection) error {
 	if nfct == nil {
-		return fmt.Errorf("nfq: nfct not initialized")
+		return errors.New("nfq: nfct not initialized")
 	}
 
 	con := ct.Con{
diff --git a/service/firewall/packet_handler.go b/service/firewall/packet_handler.go
index 22d9ce37..d4b3bbe2 100644
--- a/service/firewall/packet_handler.go
+++ b/service/firewall/packet_handler.go
@@ -612,18 +612,6 @@ func issueVerdict(conn *network.Connection, pkt packet.Packet, verdict network.V
 	}
 }
 
-// verdictRating rates the privacy and security aspect of verdicts from worst to best.
-var verdictRating = []network.Verdict{
-	network.VerdictAccept,              // Connection allowed in the open.
-	network.VerdictRerouteToTunnel,     // Connection allowed, but protected.
-	network.VerdictRerouteToNameserver, // Connection allowed, but resolved via Portmaster.
-	network.VerdictBlock,               // Connection blocked, with feedback.
-	network.VerdictDrop,                // Connection blocked, without feedback.
-	network.VerdictFailed,
-	network.VerdictUndeterminable,
-	network.VerdictUndecided,
-}
-
 // func tunnelHandler(pkt packet.Packet) {
 // 	tunnelInfo := GetTunnelInfo(pkt.Info().Dst)
 // 	if tunnelInfo == nil {
diff --git a/service/intel/entity.go b/service/intel/entity.go
index 5311881a..df67edfc 100644
--- a/service/intel/entity.go
+++ b/service/intel/entity.go
@@ -2,9 +2,9 @@ package intel
 
 import (
 	"context"
-	"fmt"
 	"net"
 	"sort"
+	"strconv"
 	"strings"
 	"sync"
 
@@ -433,7 +433,7 @@ func (e *Entity) getASNLists(ctx context.Context) {
 	}
 
 	e.loadAsnListOnce.Do(func() {
-		asnStr := fmt.Sprintf("%d", asn)
+		asnStr := strconv.FormatUint(uint64(asn), 10)
 		list, err := filterlists.LookupASNString(asnStr)
 		if err != nil {
 			log.Tracer(ctx).Errorf("intel: failed to get ASN blocklist for %d: %s", asn, err)
diff --git a/service/intel/filterlists/decoder.go b/service/intel/filterlists/decoder.go
index b8837aca..e66d8d84 100644
--- a/service/intel/filterlists/decoder.go
+++ b/service/intel/filterlists/decoder.go
@@ -103,18 +103,19 @@ func parseHeader(r io.Reader) (compressed bool, format byte, err error) {
 	if _, err = r.Read(listHeader[:]); err != nil {
 		// if we have an error here we can safely abort because
 		// the file must be broken
-		return
+		return compressed, format, err
 	}
 
 	if listHeader[0] != dsd.LIST {
 		err = fmt.Errorf("unexpected file type: %d (%c), expected dsd list", listHeader[0], listHeader[0])
-		return
+
+		return compressed, format, err
 	}
 
 	var compression [1]byte
 	if _, err = r.Read(compression[:]); err != nil {
 		// same here, a DSDL file must have at least 2 bytes header
-		return
+		return compressed, format, err
 	}
 
 	if compression[0] == dsd.GZIP {
@@ -122,15 +123,16 @@ func parseHeader(r io.Reader) (compressed bool, format byte, err error) {
 
 		var formatSlice [1]byte
 		if _, err = r.Read(formatSlice[:]); err != nil {
-			return
+			return compressed, format, err
 		}
 
 		format = formatSlice[0]
-		return
+		return compressed, format, err
 	}
 
 	format = compression[0]
-	return // nolint:nakedret
+
+	return compressed, format, err
 }
 
 // byteReader extends an io.Reader to implement the ByteReader interface.
diff --git a/service/intel/geoip/lookup.go b/service/intel/geoip/lookup.go
index da69fa26..0aeef434 100644
--- a/service/intel/geoip/lookup.go
+++ b/service/intel/geoip/lookup.go
@@ -1,7 +1,7 @@
 package geoip
 
 import (
-	"fmt"
+	"errors"
 	"net"
 
 	"github.com/oschwald/maxminddb-golang"
@@ -16,7 +16,7 @@ func getReader(ip net.IP) *maxminddb.Reader {
 func GetLocation(ip net.IP) (*Location, error) {
 	db := getReader(ip)
 	if db == nil {
-		return nil, fmt.Errorf("geoip database not available")
+		return nil, errors.New("geoip database not available")
 	}
 	record := &Location{}
 	if err := db.Lookup(ip, record); err != nil {
diff --git a/service/nameserver/module.go b/service/nameserver/module.go
index 287ba48e..8380583b 100644
--- a/service/nameserver/module.go
+++ b/service/nameserver/module.go
@@ -191,10 +191,8 @@ func handleListenError(err error, ip net.IP, port uint16, primaryListener bool)
 			EventID: eventIDConflictingService + secondaryEventIDSuffix,
 			Type:    notifications.Error,
 			Title:   "Conflicting DNS Software",
-			Message: fmt.Sprintf(
-				"Restart Portmaster after you have deactivated or properly configured the conflicting software: %s",
+			Message: "Restart Portmaster after you have deactivated or properly configured the conflicting software: " +
 				cfDescription,
-			),
 			ShowOnSystem: true,
 			AvailableActions: []*notifications.Action{
 				{
diff --git a/service/nameserver/nameserver.go b/service/nameserver/nameserver.go
index 55195756..66bccd8e 100644
--- a/service/nameserver/nameserver.go
+++ b/service/nameserver/nameserver.go
@@ -21,6 +21,8 @@ import (
 
 var hostname string
 
+const internalError = "internal error: "
+
 func handleRequestAsWorker(w dns.ResponseWriter, query *dns.Msg) {
 	err := module.RunWorker("handle dns request", func(ctx context.Context) error {
 		return handleRequest(ctx, w, query)
@@ -130,7 +132,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
 			tracer.Tracef("nameserver: delaying failing lookup until end of fail duration for %s", remainingFailingDuration.Round(time.Millisecond))
 			time.Sleep(remainingFailingDuration)
 			return reply(nsutil.ServerFailure(
-				"internal error: "+failingErr.Error(),
+				internalError+failingErr.Error(),
 				"delayed failing query to mitigate request flooding",
 			))
 		}
@@ -138,7 +140,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
 		tracer.Tracef("nameserver: delaying failing lookup for %s", failingDelay.Round(time.Millisecond))
 		time.Sleep(failingDelay)
 		return reply(nsutil.ServerFailure(
-			"internal error: "+failingErr.Error(),
+			internalError+failingErr.Error(),
 			"delayed failing query to mitigate request flooding",
 			fmt.Sprintf("error is cached for another %s", remainingFailingDuration.Round(time.Millisecond)),
 		))
@@ -148,7 +150,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
 	local, err := netenv.IsMyIP(remoteAddr.IP)
 	if err != nil {
 		tracer.Warningf("nameserver: failed to check if request for %s is local: %s", q.ID(), err)
-		return reply(nsutil.ServerFailure("internal error: failed to check if request is local"))
+		return reply(nsutil.ServerFailure(internalError + " failed to check if request is local"))
 	}
 
 	// Create connection ID for dns request.
@@ -170,7 +172,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
 		conn, err = network.NewConnectionFromExternalDNSRequest(ctx, q.FQDN, nil, connID, remoteAddr.IP)
 		if err != nil {
 			tracer.Warningf("nameserver: failed to get host/profile for request for %s%s: %s", q.FQDN, q.QType, err)
-			return reply(nsutil.ServerFailure("internal error: failed to get profile"))
+			return reply(nsutil.ServerFailure(internalError + "failed to get profile"))
 		}
 
 	default:
@@ -210,7 +212,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
 		case network.VerdictUndecided, network.VerdictAccept:
 			// Check if we have a response.
 			if rrCache == nil {
-				conn.Failed("internal error: no reply", "")
+				conn.Failed(internalError+"no reply", "")
 				return
 			}
 
@@ -293,7 +295,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
 			tracer.Warningf("nameserver: failed to resolve %s: %s", q.ID(), err)
 			conn.Failed(fmt.Sprintf("query failed: %s", err), "")
 			addFailingQuery(q, err)
-			return reply(nsutil.ServerFailure("internal error: " + err.Error()))
+			return reply(nsutil.ServerFailure(internalError + err.Error()))
 		}
 	}
 	// Handle special cases.
@@ -301,7 +303,7 @@ func handleRequest(ctx context.Context, w dns.ResponseWriter, request *dns.Msg)
 	case rrCache == nil:
 		tracer.Warning("nameserver: received successful, but empty reply from resolver")
 		addFailingQuery(q, errors.New("emptry reply from resolver"))
-		return reply(nsutil.ServerFailure("internal error: empty reply"))
+		return reply(nsutil.ServerFailure(internalError + "empty reply"))
 	case rrCache.RCode == dns.RcodeNameError:
 		// Try alternatives domain names for unofficial domain spaces.
 		altRRCache := checkAlternativeCaches(ctx, q)
diff --git a/service/netquery/active_chart_handler.go b/service/netquery/active_chart_handler.go
index 2d2fb682..264c903e 100644
--- a/service/netquery/active_chart_handler.go
+++ b/service/netquery/active_chart_handler.go
@@ -42,7 +42,7 @@ func (ch *ActiveChartHandler) ServeHTTP(resp http.ResponseWriter, req *http.Requ
 		orm.WithResult(&result),
 		orm.WithSchema(*ch.Database.Schema),
 	); err != nil {
-		http.Error(resp, "Failed to execute query: "+err.Error(), http.StatusInternalServerError)
+		http.Error(resp, failedQuery+err.Error(), http.StatusInternalServerError)
 
 		return
 	}
@@ -77,7 +77,7 @@ func (ch *ActiveChartHandler) parseRequest(req *http.Request) (*QueryActiveConne
 	var requestPayload QueryActiveConnectionChartPayload
 	blob, err := io.ReadAll(body)
 	if err != nil {
-		return nil, fmt.Errorf("failed to read body" + err.Error())
+		return nil, fmt.Errorf("failed to read body: %w", err)
 	}
 
 	body = bytes.NewReader(blob)
diff --git a/service/netquery/bandwidth_chart_handler.go b/service/netquery/bandwidth_chart_handler.go
index 615682e6..8e5647c4 100644
--- a/service/netquery/bandwidth_chart_handler.go
+++ b/service/netquery/bandwidth_chart_handler.go
@@ -49,7 +49,7 @@ func (ch *BandwidthChartHandler) ServeHTTP(resp http.ResponseWriter, req *http.R
 		orm.WithResult(&result),
 		orm.WithSchema(*ch.Database.Schema),
 	); err != nil {
-		http.Error(resp, "Failed to execute query: "+err.Error(), http.StatusInternalServerError)
+		http.Error(resp, failedQuery+err.Error(), http.StatusInternalServerError)
 
 		return
 	}
@@ -84,7 +84,7 @@ func (ch *BandwidthChartHandler) parseRequest(req *http.Request) (*BandwidthChar
 	var requestPayload BandwidthChartRequest
 	blob, err := io.ReadAll(body)
 	if err != nil {
-		return nil, fmt.Errorf("failed to read body" + err.Error())
+		return nil, fmt.Errorf("failed to read body: %w", err)
 	}
 
 	body = bytes.NewReader(blob)
diff --git a/service/netquery/manager.go b/service/netquery/manager.go
index 76403e03..d1809116 100644
--- a/service/netquery/manager.go
+++ b/service/netquery/manager.go
@@ -23,18 +23,18 @@ type (
 		// insert or an update.
 		// The ID of Conn is unique and can be trusted to never collide with other
 		// connections of the save device.
-		Save(context.Context, Conn, bool) error
+		Save(ctx context.Context, conn Conn, history bool) error
 
 		// MarkAllHistoryConnectionsEnded marks all active connections in the history
 		// database as ended NOW.
-		MarkAllHistoryConnectionsEnded(context.Context) error
+		MarkAllHistoryConnectionsEnded(ctx context.Context) error
 
 		// RemoveAllHistoryData removes all connections from the history database.
-		RemoveAllHistoryData(context.Context) error
+		RemoveAllHistoryData(ctx context.Context) error
 
 		// RemoveHistoryForProfile removes all connections from the history database.
 		// for a given profile ID (source/id)
-		RemoveHistoryForProfile(context.Context, string) error
+		RemoveHistoryForProfile(ctx context.Context, profile string) error
 
 		// UpdateBandwidth updates bandwidth data for the connection and optionally also writes
 		// the bandwidth data to the history database.
diff --git a/service/netquery/orm/decoder.go b/service/netquery/orm/decoder.go
index 21ce6146..169c5e7e 100644
--- a/service/netquery/orm/decoder.go
+++ b/service/netquery/orm/decoder.go
@@ -41,13 +41,13 @@ type (
 	// by *sqlite.Stmt.
 	Stmt interface {
 		ColumnCount() int
-		ColumnName(int) string
-		ColumnType(int) sqlite.ColumnType
-		ColumnText(int) string
-		ColumnBool(int) bool
-		ColumnFloat(int) float64
-		ColumnInt(int) int
-		ColumnReader(int) *bytes.Reader
+		ColumnName(col int) string
+		ColumnType(col int) sqlite.ColumnType
+		ColumnText(col int) string
+		ColumnBool(col int) bool
+		ColumnFloat(col int) float64
+		ColumnInt(col int) int
+		ColumnReader(col int) *bytes.Reader
 	}
 
 	// DecodeFunc is called for each non-basic type during decoding.
@@ -230,7 +230,7 @@ func DatetimeDecoder(loc *time.Location) DecodeFunc {
 
 		case sqlite.TypeFloat:
 			// stored as Julian day numbers
-			return nil, false, fmt.Errorf("REAL storage type not support for time.Time")
+			return nil, false, errors.New("REAL storage type not support for time.Time")
 
 		case sqlite.TypeNull:
 			return nil, true, nil
@@ -359,7 +359,7 @@ func decodeBasic() DecodeFunc {
 
 		case reflect.Slice:
 			if outval.Type().Elem().Kind() != reflect.Uint8 {
-				return nil, false, fmt.Errorf("slices other than []byte for BLOB are not supported")
+				return nil, false, errors.New("slices other than []byte for BLOB are not supported")
 			}
 
 			if colType != sqlite.TypeBlob {
diff --git a/service/netquery/orm/encoder.go b/service/netquery/orm/encoder.go
index 6dcd0e68..8aa53387 100644
--- a/service/netquery/orm/encoder.go
+++ b/service/netquery/orm/encoder.go
@@ -2,6 +2,7 @@ package orm
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"reflect"
 	"time"
@@ -171,7 +172,7 @@ func DatetimeEncoder(loc *time.Location) EncodeFunc {
 			valInterface := val.Interface()
 			t, ok = valInterface.(time.Time)
 			if !ok {
-				return nil, false, fmt.Errorf("cannot convert reflect value to time.Time")
+				return nil, false, errors.New("cannot convert reflect value to time.Time")
 			}
 
 		case valType.Kind() == reflect.String && colDef.IsTime:
diff --git a/service/netquery/orm/encoder_test.go b/service/netquery/orm/encoder_test.go
index d0d3c039..3a1dbb5b 100644
--- a/service/netquery/orm/encoder_test.go
+++ b/service/netquery/orm/encoder_test.go
@@ -6,6 +6,7 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 	"zombiezen.com/go/sqlite"
 )
 
@@ -120,7 +121,7 @@ func TestEncodeAsMap(t *testing.T) { //nolint:tparallel
 		c := cases[idx]
 		t.Run(c.Desc, func(t *testing.T) {
 			res, err := ToParamMap(ctx, c.Input, "", DefaultEncodeConfig, nil)
-			assert.NoError(t, err)
+			require.NoError(t, err)
 			assert.Equal(t, c.Expected, res)
 		})
 	}
@@ -253,7 +254,7 @@ func TestEncodeValue(t *testing.T) { //nolint:tparallel
 		c := cases[idx]
 		t.Run(c.Desc, func(t *testing.T) {
 			res, err := EncodeValue(ctx, &c.Column, c.Input, DefaultEncodeConfig)
-			assert.NoError(t, err)
+			require.NoError(t, err)
 			assert.Equal(t, c.Output, res)
 		})
 	}
diff --git a/service/netquery/orm/schema_builder.go b/service/netquery/orm/schema_builder.go
index 018a55e1..893dab2e 100644
--- a/service/netquery/orm/schema_builder.go
+++ b/service/netquery/orm/schema_builder.go
@@ -274,7 +274,7 @@ func applyStructFieldTag(fieldType reflect.StructField, def *ColumnDef) error {
 					case sqlite.TypeText:
 						def.Default = defaultValue
 					case sqlite.TypeBlob:
-						return fmt.Errorf("default values for TypeBlob not yet supported")
+						return errors.New("default values for TypeBlob not yet supported")
 					default:
 						return fmt.Errorf("failed to apply default value for unknown sqlite column type %s", def.Type)
 					}
diff --git a/service/netquery/orm/schema_builder_test.go b/service/netquery/orm/schema_builder_test.go
index fdd43ec7..b39fac72 100644
--- a/service/netquery/orm/schema_builder_test.go
+++ b/service/netquery/orm/schema_builder_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestSchemaBuilder(t *testing.T) {
@@ -37,7 +38,7 @@ func TestSchemaBuilder(t *testing.T) {
 		c := cases[idx]
 
 		res, err := GenerateTableSchema(c.Name, c.Model)
-		assert.NoError(t, err)
+		require.NoError(t, err)
 		assert.Equal(t, c.ExpectedSQL, res.CreateStatement("main", false))
 	}
 }
diff --git a/service/netquery/query_handler.go b/service/netquery/query_handler.go
index 68b1feb2..e996c183 100644
--- a/service/netquery/query_handler.go
+++ b/service/netquery/query_handler.go
@@ -19,6 +19,8 @@ import (
 
 var charOnlyRegexp = regexp.MustCompile("[a-zA-Z]+")
 
+const failedQuery = "Failed to execute query: "
+
 type (
 
 	// QueryHandler implements http.Handler and allows to perform SQL
@@ -78,7 +80,7 @@ func (qh *QueryHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
 		orm.WithResult(&result),
 		orm.WithSchema(*qh.Database.Schema),
 	); err != nil {
-		http.Error(resp, "Failed to execute query: "+err.Error(), http.StatusInternalServerError)
+		http.Error(resp, failedQuery+err.Error(), http.StatusInternalServerError)
 
 		return
 	}
@@ -230,7 +232,7 @@ func parseQueryRequestPayload[T any](req *http.Request) (*T, error) { //nolint:d
 
 	blob, err := io.ReadAll(body)
 	if err != nil {
-		return nil, fmt.Errorf("failed to read body" + err.Error())
+		return nil, fmt.Errorf("failed to read body: %w", err)
 	}
 
 	body = bytes.NewReader(blob)
diff --git a/service/netquery/query_test.go b/service/netquery/query_test.go
index bc9fde27..0582aacf 100644
--- a/service/netquery/query_test.go
+++ b/service/netquery/query_test.go
@@ -102,7 +102,7 @@ func TestUnmarshalQuery(t *testing.T) { //nolint:tparallel
 					assert.Equal(t, c.Error.Error(), err.Error())
 				}
 			} else {
-				assert.NoError(t, err)
+				require.NoError(t, err)
 				assert.Equal(t, c.Expected, q)
 			}
 		})
@@ -241,7 +241,7 @@ func TestQueryBuilder(t *testing.T) { //nolint:tparallel
 					assert.Equal(t, c.E.Error(), err.Error(), "test case %d", cID)
 				}
 			} else {
-				assert.NoError(t, err, "test case %d", cID)
+				require.NoError(t, err, "test case %d", cID)
 				assert.Equal(t, c.P, params, "test case %d", cID)
 				assert.Equal(t, c.R, str, "test case %d", cID)
 			}
diff --git a/service/network/api.go b/service/network/api.go
index afb2d610..878db313 100644
--- a/service/network/api.go
+++ b/service/network/api.go
@@ -136,11 +136,11 @@ func AddNetworkDebugData(di *debug.Info, profile, where string) {
 
 	// Collect matching connections.
 	var ( //nolint:prealloc // We don't know the size.
-		debugConns    []*Connection
-		accepted      int
-		total         int
+		debugConns []*Connection
+		accepted   int
+		total      int
 	)
-	
+
 	for maybeConn := range it.Next {
 		// Switch to correct type.
 		conn, ok := maybeConn.(*Connection)
diff --git a/service/network/connection.go b/service/network/connection.go
index 32ba8ee9..2459ea14 100644
--- a/service/network/connection.go
+++ b/service/network/connection.go
@@ -751,12 +751,14 @@ func (conn *Connection) SaveWhenFinished() {
 func (conn *Connection) Save() {
 	conn.UpdateMeta()
 
+	// nolint:exhaustive
 	switch conn.Verdict {
 	case VerdictAccept, VerdictRerouteToNameserver:
 		conn.ConnectionEstablished = true
 	case VerdictRerouteToTunnel:
 		// this is already handled when the connection tunnel has been
 		// established.
+	default:
 	}
 
 	// Do not save/update until data is complete.
diff --git a/service/network/packet/packet.go b/service/network/packet/packet.go
index 1ac3047f..18aa7eb2 100644
--- a/service/network/packet/packet.go
+++ b/service/network/packet/packet.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"fmt"
 	"net"
+	"strconv"
 
 	"github.com/google/gopacket"
 )
@@ -207,9 +208,9 @@ func (pkt *Base) FmtRemoteIP() string {
 func (pkt *Base) FmtRemotePort() string {
 	if pkt.info.SrcPort != 0 {
 		if pkt.info.Inbound {
-			return fmt.Sprintf("%d", pkt.info.SrcPort)
+			return strconv.FormatUint(uint64(pkt.info.SrcPort), 10)
 		}
-		return fmt.Sprintf("%d", pkt.info.DstPort)
+		return strconv.FormatUint(uint64(pkt.info.DstPort), 10)
 	}
 	return "-"
 }
@@ -235,10 +236,10 @@ type Packet interface {
 	ExpectInfo() bool
 
 	// Info.
-	SetCtx(context.Context)
+	SetCtx(ctx context.Context)
 	Ctx() context.Context
 	Info() *Info
-	SetPacketInfo(Info)
+	SetPacketInfo(info Info)
 	IsInbound() bool
 	IsOutbound() bool
 	SetInbound()
@@ -253,8 +254,8 @@ type Packet interface {
 	Payload() []byte
 
 	// Matching.
-	MatchesAddress(bool, IPProtocol, *net.IPNet, uint16) bool
-	MatchesIP(bool, *net.IPNet) bool
+	MatchesAddress(remote bool, protocol IPProtocol, network *net.IPNet, port uint16) bool
+	MatchesIP(endpoint bool, network *net.IPNet) bool
 
 	// Formatting.
 	String() string
diff --git a/service/network/socket/socket.go b/service/network/socket/socket.go
index 29393de8..0c294d66 100644
--- a/service/network/socket/socket.go
+++ b/service/network/socket/socket.go
@@ -44,7 +44,7 @@ type Address struct {
 // Info is a generic interface to both ConnectionInfo and BindInfo.
 type Info interface {
 	GetPID() int
-	SetPID(int)
+	SetPID(pid int)
 	GetUID() int
 	GetUIDandInode() (int, int)
 }
diff --git a/service/process/api.go b/service/process/api.go
index b687ae83..a2aca7f6 100644
--- a/service/process/api.go
+++ b/service/process/api.go
@@ -2,7 +2,6 @@ package process
 
 import (
 	"errors"
-	"fmt"
 	"net/http"
 	"strconv"
 
@@ -70,7 +69,7 @@ func handleGetProcessesByProfile(ar *api.Request) (any, error) {
 	source := ar.URLVars["source"]
 	id := ar.URLVars["id"]
 	if id == "" || source == "" {
-		return nil, api.ErrorWithStatus(fmt.Errorf("missing profile source/id"), http.StatusBadRequest)
+		return nil, api.ErrorWithStatus(errors.New("missing profile source/id"), http.StatusBadRequest)
 	}
 
 	result := GetProcessesWithProfile(ar.Context(), profile.ProfileSource(source), id, true)
diff --git a/service/process/database.go b/service/process/database.go
index 82a6dcb8..091d1470 100644
--- a/service/process/database.go
+++ b/service/process/database.go
@@ -72,7 +72,8 @@ func GetProcessesWithProfile(ctx context.Context, profileSource profile.ProfileS
 	slices.SortFunc[[]*Process, *Process](procs, func(a, b *Process) int {
 		return strings.Compare(a.processKey, b.processKey)
 	})
-	slices.CompactFunc[[]*Process, *Process](procs, func(a, b *Process) bool {
+
+	procs = slices.CompactFunc[[]*Process, *Process](procs, func(a, b *Process) bool {
 		return a.processKey == b.processKey
 	})
 
diff --git a/service/status/module.go b/service/status/module.go
index 2465d09b..d10d51dc 100644
--- a/service/status/module.go
+++ b/service/status/module.go
@@ -40,6 +40,6 @@ func AddToDebugInfo(di *debug.Info) {
 		fmt.Sprintf("Status: %s", netenv.GetOnlineStatus()),
 		debug.UseCodeSection|debug.AddContentLineBreaks,
 		fmt.Sprintf("OnlineStatus:          %s", netenv.GetOnlineStatus()),
-		fmt.Sprintf("CaptivePortal:         %s", netenv.GetCaptivePortal().URL),
+		"CaptivePortal:         "+netenv.GetCaptivePortal().URL,
 	)
 }
diff --git a/service/updates/helper/indexes.go b/service/updates/helper/indexes.go
index 7af8a610..8a272ea5 100644
--- a/service/updates/helper/indexes.go
+++ b/service/updates/helper/indexes.go
@@ -25,6 +25,8 @@ const (
 	ReleaseChannelSupport = "support"
 )
 
+const jsonSuffix = ".json"
+
 // SetIndexes sets the update registry indexes and also configures the registry
 // to use pre-releases based on the channel.
 func SetIndexes(
@@ -51,12 +53,12 @@ func SetIndexes(
 
 	// Always add the stable index as a base.
 	registry.AddIndex(updater.Index{
-		Path:         ReleaseChannelStable + ".json",
+		Path:         ReleaseChannelStable + jsonSuffix,
 		AutoDownload: autoDownload,
 	})
 
 	// Add beta index if in beta or staging channel.
-	indexPath := ReleaseChannelBeta + ".json"
+	indexPath := ReleaseChannelBeta + jsonSuffix
 	if releaseChannel == ReleaseChannelBeta ||
 		releaseChannel == ReleaseChannelStaging ||
 		(releaseChannel == "" && indexExists(registry, indexPath)) {
@@ -74,7 +76,7 @@ func SetIndexes(
 	}
 
 	// Add staging index if in staging channel.
-	indexPath = ReleaseChannelStaging + ".json"
+	indexPath = ReleaseChannelStaging + jsonSuffix
 	if releaseChannel == ReleaseChannelStaging ||
 		(releaseChannel == "" && indexExists(registry, indexPath)) {
 		registry.AddIndex(updater.Index{
@@ -91,7 +93,7 @@ func SetIndexes(
 	}
 
 	// Add support index if in support channel.
-	indexPath = ReleaseChannelSupport + ".json"
+	indexPath = ReleaseChannelSupport + jsonSuffix
 	if releaseChannel == ReleaseChannelSupport ||
 		(releaseChannel == "" && indexExists(registry, indexPath)) {
 		registry.AddIndex(updater.Index{
diff --git a/service/updates/main.go b/service/updates/main.go
index 95c20f04..218675b8 100644
--- a/service/updates/main.go
+++ b/service/updates/main.go
@@ -226,7 +226,7 @@ func TriggerUpdate(forceIndexCheck, downloadAll bool) error {
 		updateASAP = true
 
 	case !forceIndexCheck && !enableSoftwareUpdates() && !enableIntelUpdates():
-		return fmt.Errorf("automatic updating is disabled")
+		return errors.New("automatic updating is disabled")
 
 	default:
 		if forceIndexCheck {
@@ -254,7 +254,7 @@ func TriggerUpdate(forceIndexCheck, downloadAll bool) error {
 func DisableUpdateSchedule() error {
 	switch module.Status() {
 	case modules.StatusStarting, modules.StatusOnline, modules.StatusStopping:
-		return fmt.Errorf("module already online")
+		return errors.New("module already online")
 	}
 
 	disableTaskSchedule = true
diff --git a/spn/access/api.go b/spn/access/api.go
index e38a8c9f..c97370bc 100644
--- a/spn/access/api.go
+++ b/spn/access/api.go
@@ -1,6 +1,7 @@
 package access
 
 import (
+	"errors"
 	"fmt"
 	"net/http"
 
@@ -86,7 +87,7 @@ func registerAPIEndpoints() error {
 		DataFunc: func(ar *api.Request) (data []byte, err error) {
 			featureID, ok := ar.URLVars["id"]
 			if !ok {
-				return nil, fmt.Errorf("invalid feature id")
+				return nil, errors.New("invalid feature id")
 			}
 
 			for _, feature := range features {
@@ -95,7 +96,7 @@ func registerAPIEndpoints() error {
 				}
 			}
 
-			return nil, fmt.Errorf("feature id not found")
+			return nil, errors.New("feature id not found")
 		},
 	}); err != nil {
 		return err
diff --git a/spn/captain/navigation.go b/spn/captain/navigation.go
index e60267fa..f080e0bc 100644
--- a/spn/captain/navigation.go
+++ b/spn/captain/navigation.go
@@ -128,7 +128,7 @@ findCandidates:
 	if err != nil {
 		return fmt.Errorf("failed to connect to a new home hub - tried %d hubs: %w", tries+1, err)
 	}
-	return fmt.Errorf("no home hub candidates available")
+	return errors.New("no home hub candidates available")
 }
 
 func connectToHomeHub(ctx context.Context, dst *hub.Hub) error {
@@ -200,7 +200,7 @@ func connectToHomeHub(ctx context.Context, dst *hub.Hub) error {
 	// Set new home on map.
 	ok := navigator.Main.SetHome(dst.ID, homeTerminal)
 	if !ok {
-		return fmt.Errorf("failed to set home hub on map")
+		return errors.New("failed to set home hub on map")
 	}
 
 	// Assign crane to home hub in order to query it later.
diff --git a/spn/crew/connect.go b/spn/crew/connect.go
index 96239931..4f376e44 100644
--- a/spn/crew/connect.go
+++ b/spn/crew/connect.go
@@ -82,7 +82,7 @@ func (t *Tunnel) connectWorker(ctx context.Context) (err error) {
 		// TODO: Clean this up.
 		t.connInfo.Lock()
 		defer t.connInfo.Unlock()
-		t.connInfo.Failed(fmt.Sprintf("SPN failed to establish route: %s", err), "")
+		t.connInfo.Failed("SPN failed to establish route: "+err.Error(), "")
 		t.connInfo.Save()
 
 		tracer.Warningf("spn/crew: failed to establish route for %s: %s", t.connInfo, err)
@@ -97,7 +97,7 @@ func (t *Tunnel) connectWorker(ctx context.Context) (err error) {
 
 		t.connInfo.Lock()
 		defer t.connInfo.Unlock()
-		t.connInfo.Failed(fmt.Sprintf("SPN failed to initialize data tunnel (connect op): %s", tErr.Error()), "")
+		t.connInfo.Failed("SPN failed to initialize data tunnel (connect op): "+tErr.Error(), "")
 		t.connInfo.Save()
 
 		// TODO: try with another route?
diff --git a/spn/hub/format_test.go b/spn/hub/format_test.go
index 62b79635..1e6bf7e2 100644
--- a/spn/hub/format_test.go
+++ b/spn/hub/format_test.go
@@ -5,7 +5,7 @@ import (
 	"net"
 	"testing"
 
-	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestCheckStringFormat(t *testing.T) {
@@ -48,9 +48,9 @@ func TestCheckStringFormat(t *testing.T) {
 
 	for testCharacter, isPermitted := range testSet {
 		if isPermitted {
-			assert.NoError(t, checkStringFormat(fmt.Sprintf("test character %q", testCharacter), testCharacter, 3))
+			require.NoError(t, checkStringFormat(fmt.Sprintf("test character %q", testCharacter), testCharacter, 3))
 		} else {
-			assert.Error(t, checkStringFormat(fmt.Sprintf("test character %q", testCharacter), testCharacter, 3))
+			require.Error(t, checkStringFormat(fmt.Sprintf("test character %q", testCharacter), testCharacter, 3))
 		}
 	}
 }
@@ -59,22 +59,22 @@ func TestCheckIPFormat(t *testing.T) {
 	t.Parallel()
 
 	// IPv4
-	assert.NoError(t, checkIPFormat("test IP 1.1.1.1", net.IPv4(1, 1, 1, 1)))
-	assert.NoError(t, checkIPFormat("test IP 192.168.1.1", net.IPv4(192, 168, 1, 1)))
-	assert.Error(t, checkIPFormat("test IP 255.0.0.1", net.IPv4(255, 0, 0, 1)))
+	require.NoError(t, checkIPFormat("test IP 1.1.1.1", net.IPv4(1, 1, 1, 1)))
+	require.NoError(t, checkIPFormat("test IP 192.168.1.1", net.IPv4(192, 168, 1, 1)))
+	require.Error(t, checkIPFormat("test IP 255.0.0.1", net.IPv4(255, 0, 0, 1)))
 
 	// IPv6
-	assert.NoError(t, checkIPFormat("test IP ::1", net.ParseIP("::1")))
-	assert.NoError(t, checkIPFormat("test IP 2606:4700:4700::1111", net.ParseIP("2606:4700:4700::1111")))
+	require.NoError(t, checkIPFormat("test IP ::1", net.ParseIP("::1")))
+	require.NoError(t, checkIPFormat("test IP 2606:4700:4700::1111", net.ParseIP("2606:4700:4700::1111")))
 
 	// Invalid
-	assert.Error(t, checkIPFormat("test IP with length 3", net.IP([]byte{0, 0, 0})))
-	assert.Error(t, checkIPFormat("test IP with length 5", net.IP([]byte{0, 0, 0, 0, 0})))
-	assert.Error(t, checkIPFormat(
+	require.Error(t, checkIPFormat("test IP with length 3", net.IP([]byte{0, 0, 0})))
+	require.Error(t, checkIPFormat("test IP with length 5", net.IP([]byte{0, 0, 0, 0, 0})))
+	require.Error(t, checkIPFormat(
 		"test IP with length 15",
 		net.IP([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}),
 	))
-	assert.Error(t, checkIPFormat(
+	require.Error(t, checkIPFormat(
 		"test IP with length 17",
 		net.IP([]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}),
 	))
diff --git a/spn/hub/transport_test.go b/spn/hub/transport_test.go
index c885fcfa..9ed31b6f 100644
--- a/spn/hub/transport_test.go
+++ b/spn/hub/transport_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func parseT(t *testing.T, definition string) *Transport {
@@ -140,8 +141,8 @@ func TestTransportParsing(t *testing.T) {
 
 	// test invalid
 
-	assert.NotEqual(t, parseTError("spn"), nil, "should fail")
-	assert.NotEqual(t, parseTError("spn:"), nil, "should fail")
-	assert.NotEqual(t, parseTError("spn:0"), nil, "should fail")
-	assert.NotEqual(t, parseTError("spn:65536"), nil, "should fail")
+	require.Error(t, parseTError("spn"), "should fail")
+	require.Error(t, parseTError("spn:"), "should fail")
+	require.Error(t, parseTError("spn:0"), "should fail")
+	require.Error(t, parseTError("spn:65536"), "should fail")
 }
diff --git a/spn/navigator/optimize_region.go b/spn/navigator/optimize_region.go
index 14814813..5f362e18 100644
--- a/spn/navigator/optimize_region.go
+++ b/spn/navigator/optimize_region.go
@@ -210,9 +210,9 @@ func (m *Map) optimizeForSatelliteConnectivity(result *OptimizationResult) {
 
 		// Add to suggested pins.
 		if len(region.regardedPins) <= region.satelliteMinLanes {
-			result.addSuggested(fmt.Sprintf("best to region %s", region.ID), region.regardedPins...)
+			result.addSuggested("best to region "+region.ID, region.regardedPins...)
 		} else {
-			result.addSuggested(fmt.Sprintf("best to region %s", region.ID), region.regardedPins[:region.satelliteMinLanes]...)
+			result.addSuggested("best to region "+region.ID, region.regardedPins[:region.satelliteMinLanes]...)
 		}
 	}
 }
diff --git a/spn/navigator/update.go b/spn/navigator/update.go
index 73f52811..3fe17074 100644
--- a/spn/navigator/update.go
+++ b/spn/navigator/update.go
@@ -622,7 +622,7 @@ func (m *Map) updateQuickSettingExcludeCountryList(ctx context.Context, configKe
 	for _, country := range countryList {
 		quickSettings = append(quickSettings, config.QuickSetting{
 			Name:   fmt.Sprintf("Exclude %s (%s)", country.Name, country.Code),
-			Value:  []string{fmt.Sprintf("- %s", country.Code)},
+			Value:  []string{"- " + country.Code},
 			Action: config.QuickMergeTop,
 		})
 	}
@@ -700,7 +700,7 @@ func (m *Map) updateSelectRuleCountryList(ctx context.Context, configKey string,
 		selections = append(selections, selectCountry{
 			QuickSetting: config.QuickSetting{
 				Name:   fmt.Sprintf("%s (%s)", country.Name, country.Code),
-				Value:  []string{fmt.Sprintf("+ %s", country.Code), "- *"},
+				Value:  []string{"+ " + country.Code, "- *"},
 				Action: config.QuickReplace,
 			},
 			FlagID: country.Code,
@@ -712,7 +712,7 @@ func (m *Map) updateSelectRuleCountryList(ctx context.Context, configKey string,
 		selections = append(selections, selectCountry{
 			QuickSetting: config.QuickSetting{
 				Name:   fmt.Sprintf("%s (C:%s)", continent.Name, continent.Code),
-				Value:  []string{fmt.Sprintf("+ C:%s", continent.Code), "- *"},
+				Value:  []string{"+ C:" + continent.Code, "- *"},
 				Action: config.QuickReplace,
 			},
 		})
diff --git a/spn/ships/http_shared_test.go b/spn/ships/http_shared_test.go
index e16ff53d..d48417e4 100644
--- a/spn/ships/http_shared_test.go
+++ b/spn/ships/http_shared_test.go
@@ -4,6 +4,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
 )
 
 func TestSharedHTTP(t *testing.T) { //nolint:paralleltest // Test checks global state.
@@ -11,23 +12,23 @@ func TestSharedHTTP(t *testing.T) { //nolint:paralleltest // Test checks global
 
 	// Register multiple handlers.
 	err := addHTTPHandler(testPort, "", ServeInfoPage)
-	assert.NoError(t, err, "should be able to share http listener")
+	require.NoError(t, err, "should be able to share http listener")
 	err = addHTTPHandler(testPort, "/test", ServeInfoPage)
-	assert.NoError(t, err, "should be able to share http listener")
+	require.NoError(t, err, "should be able to share http listener")
 	err = addHTTPHandler(testPort, "/test2", ServeInfoPage)
-	assert.NoError(t, err, "should be able to share http listener")
+	require.NoError(t, err, "should be able to share http listener")
 	err = addHTTPHandler(testPort, "/", ServeInfoPage)
-	assert.Error(t, err, "should fail to register path twice")
+	require.Error(t, err, "should fail to register path twice")
 
 	// Unregister
-	assert.NoError(t, removeHTTPHandler(testPort, ""))
-	assert.NoError(t, removeHTTPHandler(testPort, "/test"))
-	assert.NoError(t, removeHTTPHandler(testPort, "/not-registered")) // removing unregistered handler does not error
-	assert.NoError(t, removeHTTPHandler(testPort, "/test2"))
-	assert.NoError(t, removeHTTPHandler(testPort, "/not-registered")) // removing unregistered handler does not error
+	require.NoError(t, removeHTTPHandler(testPort, ""))
+	require.NoError(t, removeHTTPHandler(testPort, "/test"))
+	require.NoError(t, removeHTTPHandler(testPort, "/not-registered")) // removing unregistered handler does not error
+	require.NoError(t, removeHTTPHandler(testPort, "/test2"))
+	require.NoError(t, removeHTTPHandler(testPort, "/not-registered")) // removing unregistered handler does not error
 
 	// Check if all handlers are gone again.
 	sharedHTTPServersLock.Lock()
 	defer sharedHTTPServersLock.Unlock()
-	assert.Equal(t, 0, len(sharedHTTPServers), "shared http handlers should be back to zero")
+	assert.Empty(t, sharedHTTPServers, "shared http handlers should be back to zero")
 }
diff --git a/spn/sluice/sluice.go b/spn/sluice/sluice.go
index 32a33151..bc136b10 100644
--- a/spn/sluice/sluice.go
+++ b/spn/sluice/sluice.go
@@ -47,7 +47,7 @@ func StartSluice(network, address string) {
 
 	// Start service worker.
 	module.StartServiceWorker(
-		fmt.Sprintf("%s sluice listener", s.network),
+		s.network+" sluice listener",
 		10*time.Second,
 		s.listenHandler,
 	)