Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
fe18b5c
pkg/xtcp: capget injection + InitNetlinkers err branches + PollFlatRe…
randomizedcoder May 18, 2026
2fa61b9
pkg/xtcp: mountInfoDir var + checkMountInfo open-err + InitDeserializ…
randomizedcoder May 18, 2026
0b9fdc0
pkg/xtcp: cover isETimeError string fallback + iouringPrefillRecvs en…
randomizedcoder May 18, 2026
65b3e3d
pkg/xtcp: cover Close nil-conn + extractFD type-mismatch branches
randomizedcoder May 18, 2026
d9db9d7
tools/tcp_client: cover clientOnce write-timeout + dialWithRetry retr…
randomizedcoder May 18, 2026
a49180d
tools/tcp_server + udp_receiver_server: cover runMain happy + runServ…
randomizedcoder May 18, 2026
2b18c1f
pkg/xtcp: cover Set validate-err branch
randomizedcoder May 18, 2026
62f76c2
nix: expose xtcp2-cover flake attr for the microvm coverage harness
randomizedcoder May 18, 2026
021452b
nix/microvms: add coverage flavor + lifecycle scraper
randomizedcoder May 18, 2026
1b891fd
nix/microvms coverage flavor: -dest null + strip systemd prefix from …
randomizedcoder May 18, 2026
508bc40
nix: xtcp2-cover builds stdlib destinations only
randomizedcoder May 18, 2026
c7b7842
nix: add coverage-merge runnable for host + VM profile union
randomizedcoder May 18, 2026
c4f68fd
nix/microvms: add coverage-iouring flavor
randomizedcoder May 18, 2026
2011c33
nix/microvms: coverage flavors pre-create a test network namespace
randomizedcoder May 18, 2026
a3f2db1
gofmt: format 9 files touched by recent test additions
randomizedcoder May 18, 2026
4ebe677
lint(misspell): fix 35 occurrences of cancelled/signalled/behavior
randomizedcoder May 18, 2026
2e1c728
lint(errcheck): exclude fmt.Fprintf/Fprintln + 1 noctx nolint
randomizedcoder May 18, 2026
977d4f7
lint(govet): disable shadow check
randomizedcoder May 18, 2026
7bd313f
lint: cover remaining standard-tier findings (gosec G301, gocritic ex…
randomizedcoder May 18, 2026
2e518f9
pkg/xtcp: lift deserializer key strings to consts
randomizedcoder May 18, 2026
210baac
docs: refresh quality-report.md
randomizedcoder May 18, 2026
c04da35
lint: drive comprehensive-tier findings to zero
randomizedcoder May 18, 2026
eab70a1
lint: drive quick-tier + gosec/nixfmt findings to zero
randomizedcoder May 18, 2026
764ec52
fix(test): TestDialWithRetry_allTimeouts handles Nix sandbox EHOSTUNR…
randomizedcoder May 18, 2026
fee8be9
gosec: move #nosec annotations onto a preceding-line comment
randomizedcoder May 18, 2026
fcaf834
docs: refresh quality-report.md — total findings 250 → 5
randomizedcoder May 18, 2026
62beac8
pkg/xtcp: convert long-period ticker constants to vars + add ticker-a…
randomizedcoder May 18, 2026
1d2c7ad
pkg/xtcp: fix race in TestSignalNetlinkerDone_blockingPath
randomizedcoder May 18, 2026
be6463b
pkg/xtcp: fix latent type-assertion bug in flatRecordServiceSend pfr …
randomizedcoder May 18, 2026
5e6d68b
pkg/xtcp: fix thread-migration race in createNetworkNamespace + cover…
randomizedcoder May 18, 2026
070afaf
pkg/xtcp: fix slice-bounds panic in processInetDiagRecord on malforme…
randomizedcoder May 18, 2026
cb8913a
pkg/xtcp: fix slice-bounds panics in DeserializeAttributes (4 more sh…
randomizedcoder May 18, 2026
343b050
pkg/xtcp: add FuzzDeserialize against the netlink parser
randomizedcoder May 18, 2026
3f6ff41
pkg/xtcp/destinations_kafka: fix context.WithTimeout leak on successf…
randomizedcoder May 18, 2026
ce29138
pkg/xtcp: fix reconcileMaps deleting every nsMap entry every cycle (g…
randomizedcoder May 18, 2026
fcf036d
pkg/xtcp: fix openAndSetNSWithRetries returning fd=0 (stdin) and doub…
randomizedcoder May 18, 2026
5fb620f
pkg/xtcp/deserialize: return nlh + xtcpRecord to pools on Deserialize…
randomizedcoder May 18, 2026
81f3856
cmd/xtcp2: envUint64/envUint32 reject negative values instead of sile…
randomizedcoder May 18, 2026
edcfd7d
pkg/xtcpnl/Readfile: switch from single bufio.Read to io.ReadFull
randomizedcoder May 18, 2026
ddb0a7e
pkg/xtcp/destinations_kafka: pingKafkaWithRetries honors ctx cancella…
randomizedcoder May 18, 2026
801aa66
pkg/xtcp/netlinker: diagnostic capture-to-file failure must not log.F…
randomizedcoder May 18, 2026
59bf568
cmd/xtcp2client: fix inverted ResourceExhausted handling + ctx-aware …
randomizedcoder May 18, 2026
367b550
pkg/xtcp: netNamespaceInstance fd leak + log.Fatal on per-namespace B…
randomizedcoder May 18, 2026
9d41de2
pkg/xtcp/grpc_server: stop gRPC server when ctx fires
randomizedcoder May 19, 2026
643e509
pkg/xtcp: keep *os.File alive in io_uring destinations to prevent GC …
randomizedcoder May 19, 2026
1457911
pkg/xtcpnl: fix DeserializeBBRInfo (non-XTCP variant) slice-OOB on 16…
randomizedcoder May 19, 2026
1c852fb
pkg/xtcpnl: DeserializeInetDiagReqV2 reads SocketID from offset 8, not 4
randomizedcoder May 19, 2026
c2cec0b
pkg/xtcpnl: DeserializeInetDiagSockIDXTCP — SrcIP slice is 16 bytes, …
randomizedcoder May 19, 2026
f07b2a0
gofmt: reflow deserialize_corner_cases_test.go after fuzz-test additions
randomizedcoder Jun 14, 2026
1f8a982
Bug 73 (pulled forward): isETimeError walks unwrap chain + string fal…
randomizedcoder Jun 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions .golangci-comprehensive.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,23 @@ linters:
exclude-functions:
- (io.Closer).Close
- (*os.File).Close
# fmt.Fprintf/Fprintln to stdout/stderr writers can't fail in
# practice (writes to *os.File-backed tty fail only on EBADF or
# disk-full for regular files, neither of which we recover from).
# The runMain refactors made these explicit instead of fmt.Printf
# so checking the err here adds noise without protecting against
# a real failure mode.
- fmt.Fprintf
- fmt.Fprintln
- fmt.Fprint

govet:
enable-all: true
disable:
- fieldalignment
settings:
shadow:
strict: true
# err shadowing is idiomatic Go; disable the shadow check rather
# than rewriting many sites. See .golangci.yml for context.
- shadow

staticcheck:
checks:
Expand Down Expand Up @@ -138,23 +147,45 @@ linters:
- gocyclo
- errcheck
- unused
- goconst
- noctx
- path: "_test\\.go"
linters:
- gosec
text: "G404"
text: "G404|G301"
# Kernel-version-tagged names (TCPInfo6_10_3, TCPInfo5_4_281, …) mirror
# Linux kernel uapi `struct tcp_info` revisions; renaming would defeat
# the per-version mapping that is the point of pkg/xtcpnl.
- path: "pkg/xtcpnl/"
linters:
- staticcheck
text: "ST1003: should not use underscores in Go names; (struct field|const) TCPInfo[0-9_]+(_Size(Cst)?)?"
# Per-attribute parser files in pkg/xtcpnl deliberately mirror the
# 1:1 Linux kernel INET_DIAG_* → Go-struct mapping. Keeping them as
# separate files (tos vs tclass, the multiple tcpinfo size variants)
# is a maintenance feature, not duplication waiting to be deduped.
- path: "pkg/xtcpnl/"
linters:
- dupl
# The dest Send() methods share shape but each tracks its own
# prometheus metric prefix (destUDP vs destUnixGram) + xio.Op
# constant. Factoring out the common spine would force callers
# to thread the labels through and would couple the io_uring +
# syscall paths together — not worth the code-shape match.
- path: "pkg/xtcp/destinations_(udp|unixgram)\\.go"
linters:
- dupl
# tools/ analyzers are short utilities; complexity/duplication limits don't apply.
- path: "tools/"
linters:
- funlen
- gocyclo
- dupl
# tools/{metrics,quality-report,…} legitimately use linter and
# rule names ("govet", "errcheck", "G103") as bare literals
# since those ARE the canonical identifiers. Lifting to consts
# would obscure rather than clarify.
- goconst
- linters:
- staticcheck
text: "ST1003:"
Expand Down
12 changes: 12 additions & 0 deletions .golangci-quick.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,33 @@ linters:
errcheck:
# io.Closer / *os.File Close() are routinely unchecked; flagging them
# here is noise. Closer-failure on a read-only handle is not actionable.
# fmt.Fprintf/Fprintln are explicit-writer variants of fmt.Printf
# whose err returns can't fail in practice for tty/stdout/stderr.
exclude-functions:
- (io.Closer).Close
- (*os.File).Close
- fmt.Fprintf
- fmt.Fprintln
- fmt.Fprint

govet:
enable-all: true
disable:
# Struct alignment suggestions are noisy and not bugs.
- fieldalignment
# err shadowing is idiomatic Go; matches the other tier configs.
- shadow

staticcheck:
checks:
- "all"
# SA1019 = deprecated symbols. Allow during migration windows.
- "-SA1019"
# ST1003 (underscore / camelCase): protobuf-generated identifiers
# and kernel-uapi-mirroring constants legitimately use names that
# violate Go style. Disable globally; the comprehensive tier has a
# more granular pkg/xtcpnl override.
- "-ST1003"

exclusions:
warn-unused: true
Expand Down
27 changes: 21 additions & 6 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,21 @@ linters:
exclude-functions:
- (io.Closer).Close
- (*os.File).Close
# fmt.Fprintf/Fprintln to stdout/stderr writers can't fail in
# practice (writes to *os.File-backed tty fail only on EBADF or
# disk-full for regular files, neither of which we recover from).
- fmt.Fprintf
- fmt.Fprintln
- fmt.Fprint

govet:
enable-all: true
disable:
- fieldalignment
settings:
shadow:
strict: true
# err shadowing is idiomatic Go and the repo uses it throughout.
# Disable the shadow check rather than rewriting 26 sites just to
# satisfy the linter — the pattern doesn't produce real bugs here.
- shadow

staticcheck:
checks:
Expand Down Expand Up @@ -106,19 +113,27 @@ linters:
- "^dart/"
- "^python/"
rules:
# Test code: relax dup/funlen/gocyclo/errcheck/unused.
# Test code: relax dup/funlen/gocyclo/errcheck/unused/goconst/noctx.
# Repeated CLI-flag strings in -Args tests + net.Listen/DialTimeout
# without ctx are idiomatic for test setup; lifting them into
# constants or contextual variants adds noise without benefit.
- path: "_test\\.go"
linters:
- dupl
- funlen
- gocyclo
- errcheck
- unused
# G404 (math/rand): acceptable in tests for deterministic randomness.
- goconst
- noctx
# gosec G404 (math/rand): deterministic randomness is the right
# default in tests. G301 (0o755 dir perms): tempdirs created by
# t.TempDir() are already private to the test user; the perms on
# subdirs created inside don't materially affect anything.
- path: "_test\\.go"
linters:
- gosec
text: "G404"
text: "G404|G301"
# Kernel-version-tagged names (TCPInfo6_10_3, TCPInfo5_4_281, …) mirror
# Linux kernel uapi `struct tcp_info` revisions. Renaming breaks the
# explicit per-version mapping that is the point of pkg/xtcpnl.
Expand Down
2 changes: 1 addition & 1 deletion cmd/kafka_to_clickhouse/kafka_to_clickhouse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func TestGetLatestSchemaIDAt_ctxCancel(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel()
if _, err := getLatestSchemaIDAt(ctx, srv.Client(), srv.URL, "subj"); err == nil {
t.Error("cancelled ctx should produce error")
t.Error("canceled ctx should produce error")
}
}

Expand Down
4 changes: 2 additions & 2 deletions cmd/ns/ns.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func registerPprof(promListen string) {
// exercise the switch's branches without holding a deferred profiler.
func startProfile(mode string, d uint) func() {
switch mode {
case "cpu":
case "cpu": //nolint:goconst // pprof mode names are exact CLI inputs; consts add no value here
return profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop
case "mem":
return profile.Start(profile.MemProfile, profile.ProfilePath(".")).Stop
Expand Down Expand Up @@ -244,7 +244,7 @@ func awaitSignalAndShutdown(
}

if doExit {
os.Exit(0)
os.Exit(0) //nolint:gocritic // intentional process exit; deferred timer.Stop is moot once the process terminates
}
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/ns/ns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestAwaitSignalAndShutdown_completeBeforeTimeout(t *testing.T) {

func TestAwaitSignalAndShutdown_timeoutPath(t *testing.T) {
sigs := make(chan os.Signal, 1)
complete := make(chan struct{}) // never signalled
complete := make(chan struct{}) // never signaled
_, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
go func() {
Expand Down
14 changes: 7 additions & 7 deletions cmd/nsTest/nsTest.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func runMain(ctx context.Context, args []string, stderr io.Writer) int {
if ctx.Err() != nil {
return 0
}
createNamespace(namespaceName(i))
createNamespace(ctx, namespaceName(i))
}

// Churn loop: alternately create+remove one namespace per tick.
Expand All @@ -57,11 +57,11 @@ func churn(ctx context.Context, initial int, sleep time.Duration) int {
return 0
}
newNamespace := namespaceName(j + initial)
createNamespace(newNamespace)
createNamespace(ctx, newNamespace)
log.Printf("Added namespace: %s\n", newNamespace)

oldestNamespace := namespaceName(j)
removeNamespace(oldestNamespace)
removeNamespace(ctx, oldestNamespace)
log.Printf("Removed namespace: %s\n", oldestNamespace)

j++
Expand All @@ -77,19 +77,19 @@ func namespaceName(index int) string {
return fmt.Sprintf("%s%d", baseNamespaceName, index)
}

func createNamespace(name string) {
func createNamespace(ctx context.Context, name string) {

log.Printf("createNamespace: ip netns add %s", name)
cmd := exec.CommandContext(context.Background(), "ip", "netns", "add", name)
cmd := exec.CommandContext(ctx, "ip", "netns", "add", name)
if err := cmd.Run(); err != nil {
log.Printf("Failed to create namespace %s: %v", name, err)
}

}

func removeNamespace(name string) {
func removeNamespace(ctx context.Context, name string) {
log.Printf("removeNamespace: ip netns del %s", name)
cmd := exec.CommandContext(context.Background(), "ip", "netns", "del", name)
cmd := exec.CommandContext(ctx, "ip", "netns", "del", name)
if err := cmd.Run(); err != nil {
log.Printf("Failed to remove namespace %s: %v", name, err)
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/nsTest/nsTest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ func TestNamespaceName(t *testing.T) {
func TestCreateNamespace_logsError(t *testing.T) {
// Use a name with characters that ip netns rejects so the call
// fails fast without requiring privileges.
createNamespace("test/invalid/name/with/slashes")
createNamespace(t.Context(), "test/invalid/name/with/slashes")
// No panic = pass; we don't introspect log output.
}

func TestRemoveNamespace_logsError(t *testing.T) {
removeNamespace("test/invalid/name/with/slashes")
removeNamespace(t.Context(), "test/invalid/name/with/slashes")
}

func TestRunMain_invalidFlag(t *testing.T) {
Expand All @@ -47,7 +47,7 @@ func TestRunMain_invalidFlag(t *testing.T) {
}

func TestRunMain_cancelDuringInitial(t *testing.T) {
// Pre-cancelled ctx + initial=5: the initial-fill loop checks
// Pre-canceled ctx + initial=5: the initial-fill loop checks
// ctx.Err() at the top of each iter and exits without calling
// createNamespace 5 times — verifying the cancel hook fires.
ctx, cancel := context.WithCancel(t.Context())
Expand Down
14 changes: 9 additions & 5 deletions cmd/xtcp2/xtcp2.go
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ func awaitSignalAndShutdown(
}

if doExit {
os.Exit(0)
os.Exit(0) //nolint:gocritic // intentional process exit; deferred timer.Stop is moot once the process terminates
}
}

Expand Down Expand Up @@ -553,11 +553,13 @@ func envUint64(key string) (uint64, bool) {
if !ok {
return 0, false
}
i, err := strconv.ParseInt(v, base10, sixtyFour)
// ParseUint (not ParseInt) so a negative env value like "-1" is
// rejected. Previously: ParseInt + uint64(i) → -1 became MaxUint64.
u, err := strconv.ParseUint(v, base10, sixtyFour)
if err != nil {
return 0, false
}
return uint64(i), true
return u, true
}

// envUint32 parses an env var as decimal int and yields it as uint32.
Expand All @@ -566,11 +568,13 @@ func envUint32(key string) (uint32, bool) {
if !ok {
return 0, false
}
i, err := strconv.Atoi(v)
// Same fix as envUint64: ParseUint rejects negative values that
// previously wrapped to a huge unsigned via Atoi + uint32(i).
u, err := strconv.ParseUint(v, base10, 32)
if err != nil {
return 0, false
}
return uint32(i), true
return uint32(u), true
}

// envDuration parses an env var via time.ParseDuration.
Expand Down
11 changes: 10 additions & 1 deletion cmd/xtcp2/xtcp2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ func TestEnvUint64(t *testing.T) {
{name: "zero", key: "TEST_U64_ZERO", set: true, val: "0", wantVal: 0, wantOK: true},
{name: "unparseable", key: "TEST_U64_BAD", set: true, val: "abc", wantOK: false},
{name: "empty", key: "TEST_U64_EMPTY", set: true, val: "", wantOK: false},
// Negative values used to ParseInt-then-cast through uint64,
// silently producing MaxUint64. Now rejected via ParseUint.
{name: "negative", key: "TEST_U64_NEG", set: true, val: "-1", wantOK: false},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
Expand Down Expand Up @@ -86,6 +89,12 @@ func TestEnvUint32(t *testing.T) {
if _, ok := envUint32("TEST_U32_BAD"); ok {
t.Fatal("unparseable should return ok=false")
}
// Negative values previously wrapped to MaxUint32 via Atoi+cast.
// ParseUint rejects them.
t.Setenv("TEST_U32_NEG", "-1")
if _, ok := envUint32("TEST_U32_NEG"); ok {
t.Fatal("negative value should return ok=false (would silently wrap to MaxUint32 pre-fix)")
}
}

func TestEnvDuration(t *testing.T) {
Expand Down Expand Up @@ -422,7 +431,7 @@ func TestInitPromHandler_smoke(t *testing.T) {

func TestAwaitSignalAndShutdown_timeoutPath(t *testing.T) {
sigs := make(chan os.Signal, 1)
complete := make(chan struct{}) // never signalled
complete := make(chan struct{}) // never signaled
_, cancel := context.WithCancel(context.Background())
done := make(chan struct{})
go func() {
Expand Down
4 changes: 2 additions & 2 deletions cmd/xtcp2_kafka_client/xtcp2_kafka_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func runMain(ctx context.Context, args []string, stderr io.Writer) int {
}

// pollLoop is the Kafka consume body. Extracted so test code can call it
// against a fake client (with a pre-cancelled ctx for a quick exit).
// against a fake client (with a pre-canceled ctx for a quick exit).
func pollLoop(ctx context.Context, cl *kgo.Client) {
for i := 0; ; i++ {
select {
Expand All @@ -86,7 +86,7 @@ func pollLoop(ctx context.Context, cl *kgo.Client) {
continue
}
fetches.EachRecord(func(record *kgo.Record) {
_ = processRecord(record.Value, debugLevel)
_ = processRecord(record.Value, debugLevel) //nolint:errcheck // processRecord logs internally; nothing actionable here
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/xtcp2_kafka_client/xtcp2_kafka_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func TestRunMain_invalidFlag(t *testing.T) {
}

func TestRunMain_cancellable(t *testing.T) {
// Pre-cancelled ctx → pollLoop exits via ctx.Done() before fetching.
// Pre-canceled ctx → pollLoop exits via ctx.Done() before fetching.
ctx, cancel := context.WithCancel(t.Context())
cancel()
if rc := runMain(ctx, []string{"-d", "0"}, &bytes.Buffer{}); rc != 0 {
Expand Down
Loading