diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 99a8de03..59c3e912 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -57,8 +57,8 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/checkout@v6 + - uses: actions/setup-go@v6 with: go-version: '^1.16.1' # The Go version to download (if necessary) and use. - name: install required packages @@ -70,7 +70,7 @@ jobs: - name: Configure AWS credentials if: ${{ github.event.inputs.Environment == 'prod' }} - uses: aws-actions/configure-aws-credentials@v1 + uses: aws-actions/configure-aws-credentials@v6 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} @@ -78,7 +78,7 @@ jobs: - name: Login to Amazon ECR if: ${{ github.event.inputs.Environment == 'prod'}} id: login-ecr - uses: aws-actions/amazon-ecr-login@v1 + uses: aws-actions/amazon-ecr-login@v2 with: mask-password: 'true' registry-type: public @@ -104,7 +104,7 @@ jobs: fi echo "Building and Pushing image to ECR with platform: $PLATFORM" docker buildx build --platform $PLATFORM -t $ECR_REGISTRY/$REGISTRY_ALIAS/mirror-api-logging:$IMAGE_TAG . --push - echo "::set-output name=image::$ECR_REGISTRY/$REGISTRY_ALIAS/mirror-api-logging:$IMAGE_TAG" + echo "image=$ECR_REGISTRY/$REGISTRY_ALIAS/mirror-api-logging:$IMAGE_TAG" >> $GITHUB_OUTPUT - name: Build, tag, and push the image to Amazon ECR -ebpf if: ${{ github.event.inputs.Environment == 'prod' && github.event.inputs.Module == 'ebpf'}} @@ -127,7 +127,7 @@ jobs: fi echo "Building and Pushing image to ECR with platform: $PLATFORM" docker buildx build --platform $PLATFORM -t $ECR_REGISTRY/$REGISTRY_ALIAS/mirror-api-logging:$IMAGE_TAG -f Dockerfile.eBPF . --push - echo "::set-output name=image::$ECR_REGISTRY/$REGISTRY_ALIAS/mirror-api-logging:$IMAGE_TAG" + echo "image=$ECR_REGISTRY/$REGISTRY_ALIAS/mirror-api-logging:$IMAGE_TAG" >> $GITHUB_OUTPUT build-docker: # The type of runner that the job will run on @@ -136,8 +136,8 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/checkout@v6 + - uses: actions/setup-go@v6 with: go-version: '^1.16.1' # The Go version to download (if necessary) and use. - name: install required packages @@ -174,8 +174,8 @@ jobs: fi echo "Building and Pushing image to DockerHub with platform: $PLATFORM" docker buildx build --platform $PLATFORM -t $ECR_REGISTRY/mirror-api-logging:$IMAGE_TAG . --push - echo "::set-output name=image::$ECR_REGISTRY/mirror-api-logging:$IMAGE_TAG" - + echo "image=$ECR_REGISTRY/mirror-api-logging:$IMAGE_TAG" >> $GITHUB_OUTPUT + - name: Build, tag, and push the image to DockerHub - ebpf if: ${{ github.event.inputs.Environment == 'prod' && github.event.inputs.Module == 'ebpf' }} id: build-image-dockerhub-ebpf @@ -195,4 +195,4 @@ jobs: fi echo "Building and Pushing image to DockerHub with platform: $PLATFORM" docker buildx build --platform $PLATFORM -t $ECR_REGISTRY/mirror-api-logging:$IMAGE_TAG -f Dockerfile.eBPF . --push - echo "::set-output name=image::$ECR_REGISTRY/mirror-api-logging:$IMAGE_TAG" + echo "image=$ECR_REGISTRY/mirror-api-logging:$IMAGE_TAG" >> $GITHUB_OUTPUT diff --git a/Dockerfile.eBPF b/Dockerfile.eBPF index f213d5b4..7872e3c8 100644 --- a/Dockerfile.eBPF +++ b/Dockerfile.eBPF @@ -17,7 +17,7 @@ RUN apk add --no-cache \ # Using --platform=$BUILDPLATFORM lets Docker run this stage natively # (no QEMU emulation). Go's built-in cross-compilation produces the binary # for the TARGET arch via GOARCH / GOOS env vars. -FROM --platform=$BUILDPLATFORM golang:1.24-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.25-alpine AS builder ARG TARGETARCH ARG TARGETOS=linux diff --git a/daemonset-ebpf.yml b/daemonset-ebpf.yml index 4642cb87..d86d8f86 100644 --- a/daemonset-ebpf.yml +++ b/daemonset-ebpf.yml @@ -1,8 +1,7 @@ apiVersion: apps/v1 kind: DaemonSet metadata: - name: akto-ebpf-connector - namespace: bookinfo + name: akto-k8s-ebpf labels: app: akto-collector spec: @@ -14,15 +13,11 @@ spec: labels: app: akto-collector spec: - # optional - nodeSelector: - mirror: "true" hostNetwork: true dnsPolicy: ClusterFirstWithHostNet - hostPID: true containers: - - name: akto-ebpf - image: coastaldemigod/ebpf:v84 + - name: mirror-api-logging + image: public.ecr.aws/aktosecurity/mirror-api-logging:k8s_ebpf_core imagePullPolicy: Always resources: limits: @@ -31,71 +26,50 @@ spec: requests: cpu: 50m memory: 50Mi - env: - # - name: AKTO_MODULE_DISCOVERY_CONFIG - # value: '[{"key":{"eq":"x-forwarded-client-cert","ifAbsent":"reject"},"value":{"regex":".*bookinfo.*"}}]' + env: - name: AKTO_TRAFFIC_BATCH_TIME_SECS value: "10" - name: AKTO_TRAFFIC_BATCH_SIZE value: "100" - name: AKTO_KAFKA_BROKER_MAL - value: "172.20.80.9:9092" - # - name: LOG_LEVEL - # value: "0" - - name: AKTO_MONGO_CONN - value: "mongodb://10.0.134.212:27017/admini" - - name: TRAFFIC_INACTIVITY_THRESHOLD - value: "30" - - name: INGEST_LOGS - value: "true" - # - name: TRAFFIC_COMPLETE_THRESHOLD - # value: "0" - # - name: TRAFFIC_MAX_ACTIVE_CONN - # value: "8192" - - name: PRINT_BPF_LOGS - value: "true" - # - name: TRAFFIC_MAX_BUFFER_PER_TRACKER - # value: "20" - # - name: KAFKA_POLL_INTERVAL - # value: "1" - - name: AKTO_MEM_THRESH_RESTART - value: "900" - # - name: TRAFFIC_SAMPLE_BUFFER_PER_MINUTE - # value: "100" - - name: DEBUG_MODE - value: "true" - # - name: AKTO_DISABLE_ON_DB - # value: "true" - # - name: SAMPLE_LIMIT_PER_MIN - # value: - - name: CAPTURE_SSL - value: "true" + value: "akto-mini-runtime-mini-runtime.default.svc.cluster.local:9092" + - name: AKTO_LOG_LEVEL + value: "DEBUG" + - name: UPROBE_POLL_INTERVAL + value: "5" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: HOST_PROC + value: "/host/proc" securityContext: + allowPrivilegeEscalation: false + privileged: false capabilities: + drop: + - ALL add: - - SYS_PTRACE - - SYS_ADMIN - privileged: true + - BPF + - PERFMON + - SYS_PTRACE volumeMounts: - # needed to load kernel headers - - name: lib-modules - mountPath: /lib/modules + - name: sys-kernel-btf + mountPath: /sys/kernel/btf readOnly: true - # needed to trace kernel events - - name: sys-kernel - mountPath: /sys/kernel - readOnly: true - - name: host - mountPath: /host + - name: host-proc + mountPath: /host/proc readOnly: true volumes: - - name: sys-kernel - hostPath: - path: /sys/kernel - - name: lib-modules + - name: sys-kernel-btf hostPath: - path: /lib/modules - - name: host + path: /sys/kernel/btf + type: Directory + - name: host-proc hostPath: - path : / - + path: /proc + type: Directory diff --git a/ebpf/bpfwrapper/deleteProbes.go b/ebpf/bpfwrapper/deleteProbes.go deleted file mode 100644 index a570c6e0..00000000 --- a/ebpf/bpfwrapper/deleteProbes.go +++ /dev/null @@ -1,48 +0,0 @@ -package bpfwrapper - -import ( - "log/slog" - "os/exec" - "strings" - - "github.com/akto-api-security/mirroring-api-logging/trafficUtil/utils" -) - -func DeleteExistingAktoKernelProbes() { - - listCmd := exec.Command("perf", "probe", "-l") - - listOutput, err := listCmd.Output() - if err != nil { - slog.Error("Error listing kprobes", "error", err) - return - } - - // Split the output into lines - kprobes := string(listOutput) - kprobeLines := strings.Split(kprobes, "\n") - - // Iterate over kprobe lines and delete each kprobe - for _, line := range kprobeLines { - fields := strings.Fields(line) - if len(fields) > 0 { - // Extract kprobe name - kprobeName := fields[0] - - // skip non-akto probes - if !strings.HasPrefix(kprobeName, "kprobes:akto") { - continue - } - - // Command to delete kprobe - deleteCmd := exec.Command("perf", "probe", "-d", kprobeName) - - // Run the command - if err := deleteCmd.Run(); err != nil { - slog.Error("Error deleting kprobe", "kprobe", kprobeName, "error", err) - } else { - utils.PrintLog("Deleted kprobe", "kprobe", kprobeName) - } - } - } -} diff --git a/ebpf/bpfwrapper/eventCallbacks.go b/ebpf/bpfwrapper/eventCallbacks.go index ca6e03b4..3e7b79c3 100644 --- a/ebpf/bpfwrapper/eventCallbacks.go +++ b/ebpf/bpfwrapper/eventCallbacks.go @@ -22,7 +22,7 @@ func SocketOpenEventCallback(inputChan chan []byte, connectionFactory *connectio } if !connectionFactory.CanBeFilled() { - metaUtils.LogIngest("Connections filled") + slog.Warn("Connections filled") continue } @@ -114,7 +114,7 @@ func SocketDataEventCallback(inputChan chan []byte, connectionFactory *connectio } if !(connectionFactory.CanBeFilled() && connections.BufferCheck()) { - metaUtils.LogIngest("Connections filled") + slog.Warn("Connections filled") continue } @@ -158,9 +158,6 @@ func SocketDataEventCallback(inputChan chan []byte, connectionFactory *connectio continue } - event.Attr.ReadEventsCount = event.Attr.ReadEventsCount - event.Attr.WriteEventsCount = event.Attr.WriteEventsCount - connectionFactory.CreateIfNotExists(connId) dataStr := string(event.Msg[:min(32, utils.Abs(bytesSent))]) diff --git a/ebpf/bpfwrapper/kprobes.go b/ebpf/bpfwrapper/kprobes.go index 247c2db3..dd93af2d 100644 --- a/ebpf/bpfwrapper/kprobes.go +++ b/ebpf/bpfwrapper/kprobes.go @@ -4,15 +4,10 @@ import ( "log/slog" "runtime" - "github.com/akto-api-security/mirroring-api-logging/trafficUtil/utils" "github.com/cilium/ebpf" "github.com/cilium/ebpf/link" ) -const ( - maxActiveConnections = 1024 -) - // ProbeType represents whether the probe is an entry or a return. type ProbeType int @@ -93,7 +88,7 @@ func AttachKprobes(coll *ebpf.Collection, kprobeList []Kprobe) ([]link.Link, err switch probe.Type { case EntryType: - utils.PrintLog("Attaching kprobe", "hook", probe.HookName, "function", functionToHook) + slog.Debug("Attaching kprobe", "hook", probe.HookName, "function", functionToHook) l, err := link.Kprobe(functionToHook, prog, nil) if err != nil { slog.Error("failed to attach kprobe", "hook", probe.HookName, "function", functionToHook, "error", err) @@ -102,7 +97,7 @@ func AttachKprobes(coll *ebpf.Collection, kprobeList []Kprobe) ([]link.Link, err links = append(links, l) case ReturnType: - utils.PrintLog("Attaching kretprobe", "hook", probe.HookName, "function", functionToHook) + slog.Debug("Attaching kretprobe", "hook", probe.HookName, "function", functionToHook) l, err := link.Kretprobe(functionToHook, prog, nil) if err != nil { slog.Error("failed to attach kretprobe", "hook", probe.HookName, "function", functionToHook, "error", err) diff --git a/ebpf/bpfwrapper/perfbufferreaders.go b/ebpf/bpfwrapper/perfbufferreaders.go index e9ac030b..9031e498 100644 --- a/ebpf/bpfwrapper/perfbufferreaders.go +++ b/ebpf/bpfwrapper/perfbufferreaders.go @@ -4,26 +4,25 @@ import ( "errors" "fmt" "log" - "os" "github.com/akto-api-security/mirroring-api-logging/ebpf/connections" "github.com/akto-api-security/mirroring-api-logging/trafficUtil/kafkaUtil" "github.com/cilium/ebpf" - "github.com/cilium/ebpf/perf" + "github.com/cilium/ebpf/ringbuf" ) -// ProbeEventLoop is the signature for callbacks that drain perf event channels. +// ProbeEventLoop is the signature for callbacks that drain ring buffer channels. type ProbeEventLoop func(inputChan chan []byte, connectionFactory *connections.Factory) -// ProbeChannel links a named BPF perf-event array to a Go channel and event loop. +// ProbeChannel links a named BPF ring buffer to a Go channel and event loop. type ProbeChannel struct { name string eventLoop ProbeEventLoop eventChannel chan []byte - reader *perf.Reader + reader *ringbuf.Reader } -// NewProbeChannel creates a new probe channel for the given BPF perf-event array name. +// NewProbeChannel creates a new probe channel for the given BPF ring buffer name. func NewProbeChannel(name string, handler ProbeEventLoop) *ProbeChannel { return &ProbeChannel{ name: name, @@ -31,7 +30,7 @@ func NewProbeChannel(name string, handler ProbeEventLoop) *ProbeChannel { } } -// Start opens the perf reader, launches the event loop goroutine and starts draining. +// Start opens the ring buffer reader, launches the event loop goroutine and starts draining. func (pc *ProbeChannel) Start(coll *ebpf.Collection, connectionFactory *connections.Factory) error { m, ok := coll.Maps[pc.name] if !ok { @@ -41,27 +40,23 @@ func (pc *ProbeChannel) Start(coll *ebpf.Collection, connectionFactory *connecti pc.eventChannel = make(chan []byte, kafkaUtil.EventChanBuffSize) var err error - pc.reader, err = perf.NewReader(m, os.Getpagesize()*8192) + pc.reader, err = ringbuf.NewReader(m) if err != nil { - return fmt.Errorf("failed to open perf reader for %q: %v", pc.name, err) + return fmt.Errorf("failed to open ring buffer reader for %q: %v", pc.name, err) } go pc.eventLoop(pc.eventChannel, connectionFactory) go func() { - log.Printf("perf reader started for channel %s", pc.name) + log.Printf("ring buffer reader started for channel %s", pc.name) for { record, err := pc.reader.Read() if err != nil { - if errors.Is(err, perf.ErrClosed) { + if errors.Is(err, ringbuf.ErrClosed) { close(pc.eventChannel) return } - log.Printf("error reading perf event on %s: %v", pc.name, err) - continue - } - if record.LostSamples > 0 { - log.Printf("⚠️ Lost %d events on channel %s", record.LostSamples, pc.name) + log.Printf("error reading ring buffer event on %s: %v", pc.name, err) continue } pc.eventChannel <- record.RawSample @@ -71,7 +66,7 @@ func (pc *ProbeChannel) Start(coll *ebpf.Collection, connectionFactory *connecti return nil } -// Stop closes the underlying perf reader, which will unblock the drain goroutine. +// Stop closes the underlying ring buffer reader, which will unblock the drain goroutine. func (pc *ProbeChannel) Stop() { if pc.reader != nil { pc.reader.Close() diff --git a/ebpf/bpfwrapper/uprobes.go b/ebpf/bpfwrapper/uprobes.go index f0fe5c82..de56134f 100644 --- a/ebpf/bpfwrapper/uprobes.go +++ b/ebpf/bpfwrapper/uprobes.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/cilium/ebpf" + "github.com/cilium/ebpf/features" "github.com/cilium/ebpf/link" ) @@ -24,16 +25,174 @@ type Uprobe struct { Addresses []uint64 } -var uprobeRegexp = regexp.MustCompile("[^a-zA-Z0-9_]") +// SetUprobeMultiAttachType upgrades all SEC("uprobe") programs in the spec to +// use BPF_TRACE_UPROBE_MULTI as their expected_attach_type, so they can be +// loaded and later attached via bpf(BPF_LINK_CREATE) instead of perf_event_open. +// This is a no-op if the kernel does not support uprobe_multi. +func SetUprobeMultiAttachType(spec *ebpf.CollectionSpec) { + if features.HaveBPFLinkUprobeMulti() != nil { + slog.Debug("kernel does not support uprobe_multi; using legacy perf-based uprobes") + return + } + slog.Info("uprobe_multi supported; upgrading uprobe programs to BPF_TRACE_UPROBE_MULTI") + for name, prog := range spec.Programs { + if prog.Type == ebpf.Kprobe && prog.AttachType == 0 && prog.SectionName != "" && + (strings.HasPrefix(prog.SectionName, "uprobe") || strings.HasPrefix(prog.SectionName, "uretprobe")) { + prog.AttachType = ebpf.AttachTraceUprobeMulti + slog.Debug("upgraded program attach type", "name", name, "section", prog.SectionName) + } + } +} // AttachUprobes attaches the given uprobe list using cilium/ebpf's link package. -// Returns the created links so the caller can close them when done. +// It prefers UprobeMulti (BPF_LINK_CREATE, no perf_event_open) when the kernel +// supports it, falling back to the legacy per-probe Uprobe path otherwise. func AttachUprobes(soPath string, pid int, coll *ebpf.Collection, uprobeList []Uprobe) ([]link.Link, error) { - // Convert BCC's "-1 = all PIDs" convention to cilium/ebpf's "0 = system-wide". if pid == -1 { pid = 0 } + useMulti := features.HaveBPFLinkUprobeMulti() == nil + + if useMulti { + return attachUprobesMulti(soPath, pid, coll, uprobeList) + } + return attachUprobesLegacy(soPath, pid, coll, uprobeList) +} + +// attachUprobesMulti uses UprobeMulti/UretprobeMulti which goes through +// bpf(BPF_LINK_CREATE) and does NOT call perf_event_open — so it is immune +// to perf_event_paranoid restrictions. +func attachUprobesMulti(soPath string, pid int, coll *ebpf.Collection, uprobeList []Uprobe) ([]link.Link, error) { + ex, err := link.OpenExecutable(soPath) + if err != nil { + return nil, fmt.Errorf("failed to open executable %q: %v", soPath, err) + } + + multiOpts := &link.UprobeMultiOptions{ + PID: uint32(pid), + } + + var links []link.Link + + for _, probe := range uprobeList { + prog, ok := coll.Programs[probe.HookName] + if !ok { + return links, fmt.Errorf("BPF program %q not found in collection", probe.HookName) + } + + isReturn := probe.Type == ReturnType || probe.Type == ReturnType_Matching_Pre + + switch probe.Type { + case EntryType, ReturnType: + syms := []string{probe.FunctionToHook} + slog.Debug("Attaching uprobe-multi", "hook", probe.HookName, "function", probe.FunctionToHook, "return", isReturn) + l, err := attachMultiLink(ex, syms, prog, multiOpts, isReturn) + if err != nil { + return links, fmt.Errorf("uprobe-multi %q to %q: %v", probe.HookName, probe.FunctionToHook, err) + } + links = append(links, l) + + case EntryType_Matching_Suf, EntryType_Matching_Pre: + var pattern string + if probe.Type == EntryType_Matching_Suf { + pattern = getSuffixRegex(probe.FunctionToHook) + } else { + pattern = getPrefixRegex(probe.FunctionToHook) + } + syms, err := findMatchingSymbols(soPath, pattern) + if err != nil { + return links, fmt.Errorf("failed to scan symbols in %q: %v", soPath, err) + } + if len(syms) == 0 { + continue + } + slog.Debug("Attaching uprobe-multi (pattern)", "hook", probe.HookName, "matches", len(syms)) + l, err := attachMultiLink(ex, syms, prog, multiOpts, false) + if err != nil { + slog.Error("uprobe-multi pattern attach failed", "hook", probe.HookName, "error", err) + continue + } + links = append(links, l) + + case ReturnType_Matching_Pre: + pattern := getPrefixRegex(probe.FunctionToHook) + syms, err := findMatchingSymbols(soPath, pattern) + if err != nil { + return links, fmt.Errorf("failed to scan symbols in %q: %v", soPath, err) + } + if len(syms) == 0 { + continue + } + slog.Debug("Attaching uretprobe-multi (pattern)", "hook", probe.HookName, "matches", len(syms)) + l, err := attachMultiLink(ex, syms, prog, multiOpts, true) + if err != nil { + slog.Error("uretprobe-multi pattern attach failed", "hook", probe.HookName, "error", err) + continue + } + links = append(links, l) + + case ReturnType_Matching_Suf_Addr: + // These are entry probes placed at specific RET instruction offsets + // (to capture return values), NOT uretprobes. + slog.Debug("Attaching uprobe-multi (addr offsets)", "hook", probe.HookName, "function", probe.FunctionToHook, "offsets", len(probe.Addresses)) + if len(probe.Addresses) == 0 { + continue + } + syms := make([]string, len(probe.Addresses)) + offsets := make([]uint64, len(probe.Addresses)) + for i, addr := range probe.Addresses { + syms[i] = probe.FunctionToHook + offsets[i] = addr + } + optsWithOffsets := &link.UprobeMultiOptions{ + PID: uint32(pid), + Offsets: offsets, + } + l, err := attachMultiLink(ex, syms, prog, optsWithOffsets, false) + if err != nil { + slog.Error("uprobe-multi addr attach failed", "hook", probe.HookName, "error", err) + continue + } + links = append(links, l) + + case EntryType_Abs_Offset: + if len(probe.Addresses) == 0 { + slog.Error("EntryType_Abs_Offset: no address provided", "hook", probe.HookName) + continue + } + slog.Debug("Attaching uprobe-multi (abs offset)", "hook", probe.HookName, "offset", probe.Addresses[0]) + optsAbs := &link.UprobeMultiOptions{ + PID: uint32(pid), + Addresses: probe.Addresses[:1], + } + l, err := attachMultiLink(ex, nil, prog, optsAbs, false) + if err != nil { + slog.Error("uprobe-multi abs-offset attach failed", "hook", probe.HookName, "error", err) + continue + } + links = append(links, l) + + default: + return links, fmt.Errorf("unknown uprobe type %d for %q", probe.Type, probe.HookName) + } + } + + return links, nil +} + +func attachMultiLink(ex *link.Executable, syms []string, prog *ebpf.Program, opts *link.UprobeMultiOptions, isReturn bool) (link.Link, error) { + if opts == nil { + opts = &link.UprobeMultiOptions{} + } + if isReturn { + return ex.UretprobeMulti(syms, prog, opts) + } + return ex.UprobeMulti(syms, prog, opts) +} + +// attachUprobesLegacy is the original per-probe attachment path using perf_event_open. +func attachUprobesLegacy(soPath string, pid int, coll *ebpf.Collection, uprobeList []Uprobe) ([]link.Link, error) { var links []link.Link for _, probe := range uprobeList { @@ -86,8 +245,6 @@ func AttachUprobes(soPath string, pid int, coll *ebpf.Collection, uprobeList []U } case ReturnType_Matching_Suf_Addr: - // Attach entry probes at specific offsets within a function (at each RET address). - // probe.Addresses contains the byte offsets of RET instructions from the function start. slog.Debug("Attaching suffix-match addr uprobes", "hook", probe.HookName, "function", probe.FunctionToHook) for _, add := range probe.Addresses { addrOpts := &link.UprobeOptions{Offset: add} @@ -103,8 +260,6 @@ func AttachUprobes(soPath string, pid int, coll *ebpf.Collection, uprobeList []U } case EntryType_Abs_Offset: - // Attach at an absolute ELF file offset (probe.Addresses[0]) with no - // symbol name — bypasses cilium/ebpf's symbol lookup entirely. if len(probe.Addresses) == 0 { slog.Error("EntryType_Abs_Offset: no address provided", "hook", probe.HookName) continue @@ -161,8 +316,6 @@ func AttachUprobes(soPath string, pid int, coll *ebpf.Collection, uprobeList []U return links, nil } -// findMatchingSymbols reads the ELF symbol table of path and returns all symbol -// names that match the given regex pattern. func findMatchingSymbols(path, pattern string) ([]string, error) { f, err := elf.Open(path) if err != nil { @@ -175,7 +328,6 @@ func findMatchingSymbols(path, pattern string) ([]string, error) { return nil, fmt.Errorf("compile regex %q: %v", pattern, err) } - // Gather both static and dynamic symbol tables. syms, _ := f.Symbols() dynSyms, _ := f.DynamicSymbols() syms = append(syms, dynSyms...) @@ -200,12 +352,8 @@ func getPrefixRegex(input string) string { } func escapeRegexChars(input string) string { - // List of regex special characters that need to be escaped, - // with the backslash itself included properly. specialChars := []string{`\`, `.`, `^`, `$`, `*`, `+`, `?`, `(`, `)`, `[`, `]`, `{`, `}`, `|`} - // Escape each special character found in the input. - // Start with the backslash to avoid double escaping issues. for _, char := range specialChars { if char == `\` { input = strings.ReplaceAll(input, char, `\\`) diff --git a/ebpf/connections/factory.go b/ebpf/connections/factory.go index e2f5d6cd..f467788d 100644 --- a/ebpf/connections/factory.go +++ b/ebpf/connections/factory.go @@ -34,7 +34,7 @@ func NewFactory() *Factory { } } -func convertToSingleByteArr(bufMap map[int][]byte) []byte { +func convertToSingleByteArr(connID structs.ConnID, bufMap map[int][]byte) []byte { if len(bufMap) == 0 { return make([]byte, 0) @@ -52,14 +52,19 @@ func convertToSingleByteArr(bufMap map[int][]byte) []byte { kPrev := -1 for _, k := range keys { if kPrev == -1 { - if k != 1 { - utils.LogProcessing("Bad start sequence", "key", k, "value", string(bufMap[k])) + // C sets read, write event count=0 only on new connection open + // For requests arriving after a time gap on the same underlying connection the + // read,write count will not be 1, they will simply continue from the last request + // This can only be replicated when there is a time gap/inactivityThreshold between requests + // on the same underlying connection + if !sequenceCheckSkip && k != 1 { + utils.LogProcessing("Bad start sequence", append(structs.ConnIDLogArgs(connID), "key", k, "value", string(bufMap[k]))...) break } kPrev = k } else { if kPrev+1 != k { - utils.LogProcessing("Missing sequence", "prev", kPrev, "current", k, "value", string(bufMap[k]), "prevValue", string(bufMap[kPrev])) + utils.LogProcessing("Missing sequence", append(structs.ConnIDLogArgs(connID), "prev", kPrev, "current", k, "value", string(bufMap[k]), "prevValue", string(bufMap[kPrev]))...) break } kPrev = k @@ -72,7 +77,7 @@ func convertToSingleByteArr(bufMap map[int][]byte) []byte { var ( disableEgress = false - maxActiveConnections = 4096 + maxActiveConnections = 8192 inactivityThreshold = 7 * time.Second // Value in MB bufferMemThreshold = 400 @@ -82,6 +87,8 @@ var ( trackerDataProcessInterval = 100 socketDataEventBytesThreshold = 10 * 1024 * 1024 + sequenceCheckSkip = false + workerChanBuffSize = 256 ) func init() { @@ -92,6 +99,8 @@ func init() { utils.InitVar("AKTO_MEM_SOFT_LIMIT", &bufferMemThreshold) utils.InitVar("TRACKER_DATA_PROCESS_INTERVAL", &trackerDataProcessInterval) utils.InitVar("SOCKET_DATA_EVENT_BYTES_THRESHOLD", &socketDataEventBytesThreshold) + utils.InitVar("AKTO_SKIP_SEQUENCE_CHECK", &sequenceCheckSkip) + utils.InitVar("WORKER_CHAN_BUFF_SIZE", &workerChanBuffSize) } func ProcessTrackerData(connID structs.ConnID, tracker *Tracker, isComplete bool) { @@ -101,8 +110,8 @@ func ProcessTrackerData(connID structs.ConnID, tracker *Tracker, isComplete bool if len(tracker.sentBuf) == 0 || len(tracker.recvBuf) == 0 { return } - receiveBuffer := convertToSingleByteArr(tracker.recvBuf) - sentBuffer := convertToSingleByteArr(tracker.sentBuf) + receiveBuffer := convertToSingleByteArr(connID, tracker.recvBuf) + sentBuffer := convertToSingleByteArr(connID, tracker.sentBuf) originalInt := uint32(connID.Ip) // Convert integer to little-endian byte slice @@ -124,12 +133,12 @@ func ProcessTrackerData(connID structs.ConnID, tracker *Tracker, isComplete bool } if len(sentBuffer) >= len(httpBytes) && (bytes.Equal(sentBuffer[:len(httpBytes)], httpBytes)) { - tryReadFromBD(destIpStr, srcIpStr, receiveBuffer, sentBuffer, isComplete, 1, connID.Id, connID.Fd, uniqueDaemonsetId, hostName) + tryReadFromBD(destIpStr, srcIpStr, receiveBuffer, sentBuffer, isComplete, 1, connID.Id, connID.Fd, uniqueDaemonsetId, hostName, connID) } if !disableEgress { // attempt to parse the egress as well by switching the recv and sent buffers. if len(receiveBuffer) >= len(httpBytes) && (bytes.Equal(receiveBuffer[:len(httpBytes)], httpBytes)) { - tryReadFromBD(srcIpStr, destIpStr, sentBuffer, receiveBuffer, isComplete, 2, connID.Id, connID.Fd, uniqueDaemonsetId, hostName) + tryReadFromBD(srcIpStr, destIpStr, sentBuffer, receiveBuffer, isComplete, 2, connID.Id, connID.Fd, uniqueDaemonsetId, hostName, connID) } } } @@ -167,7 +176,7 @@ func BufferCheck() bool { lastReset = uint64(time.Now().UnixMilli()) currentTotalBuffer = int64(0) lastPrint = int64(0) - utils.LogIngest("Buffer reset", "currentTotalBuffer", currentTotalBuffer, "lastPrint", lastPrint) + slog.Debug("Buffer reset", "currentTotalBuffer", currentTotalBuffer, "lastPrint", lastPrint) } bufferSampleCheck := (sampleBufferPerMin == -1) || currentTotalBuffer < int64(sampleBufferPerMin*1024*1024) @@ -193,12 +202,12 @@ func (factory *Factory) CreateIfNotExists(connectionID structs.ConnID) { _, exists := factory.connections[connectionID] if !exists { - utils.LogProcessing("Creating tracker", "fd", connectionID.Fd, "id", connectionID.Id, "timestamp", connectionID.Conn_start_ns, "ip", connectionID.Ip, "port", connectionID.Port) + utils.LogProcessing("Creating tracker", structs.ConnIDLogArgs(connectionID)...) tracker := NewTracker(connectionID) now := uint64(time.Now().UnixNano()) tracker.openTimestamp = now factory.connections[connectionID] = tracker - ch := make(chan interface{}, 10) + ch := make(chan interface{}, workerChanBuffSize) factory.processor[connectionID] = ch factory.StartWorker(connectionID, tracker, ch) } @@ -227,7 +236,7 @@ func resetTimer(t *time.Timer, d time.Duration) { func (factory *Factory) StartWorker(connectionID structs.ConnID, tracker *Tracker, ch chan interface{}) { go func(connID structs.ConnID, tracker *Tracker, ch chan interface{}) { - utils.LogProcessing("Starting go routine", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Starting go routine", structs.ConnIDLogArgs(connID)...) inactivityTimer := time.NewTimer(inactivityThreshold) delayedDeleteChan := make(chan struct{}, 1) @@ -237,21 +246,21 @@ func (factory *Factory) StartWorker(connectionID structs.ConnID, tracker *Tracke // Handle event based on its type switch e := event.(type) { case *structs.SocketDataEvent: - utils.LogProcessing("Received data event", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Received data event", structs.ConnIDLogArgs(connID)...) tracker.AddDataEvent(*e) if tracker.GetSentBytes()+tracker.GetRecvBytes() > uint64(socketDataEventBytesThreshold) { - utils.LogProcessing("Socket Data threshold data breached, processing current data", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Socket Data threshold data breached, processing current data", structs.ConnIDLogArgs(connID)...) factory.StopProcessing(connID) return } else { resetTimer(inactivityTimer, inactivityThreshold) } case *structs.SocketOpenEvent: - utils.LogProcessing("Received open event", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Received open event", structs.ConnIDLogArgs(connID)...) tracker.AddOpenEvent(*e) resetTimer(inactivityTimer, inactivityThreshold) case *structs.SocketCloseEvent: - utils.LogProcessing("Received close event", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Received close event", structs.ConnIDLogArgs(connID)...) tracker.AddCloseEvent(*e) time.AfterFunc(100*time.Millisecond, func() { @@ -260,15 +269,15 @@ func (factory *Factory) StartWorker(connectionID structs.ConnID, tracker *Tracke } case <-delayedDeleteChan: - utils.LogProcessing("Stopping go routine (delayed close)", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Stopping go routine (delayed close)", structs.ConnIDLogArgs(connID)...) factory.StopProcessing(connID) return case <-inactivityTimer.C: // Eat the go routine after inactive threshold, process the tracker and stop the worker - utils.LogProcessing("Inactivity threshold reached, marking connection as inactive and processing", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Inactivity threshold reached, marking connection as inactive and processing", structs.ConnIDLogArgs(connID)...) factory.StopProcessing(connID) - utils.LogProcessing("Stopping go routine", "fd", connID.Fd, "id", connID.Id, "timestamp", connID.Conn_start_ns, "ip", connID.Ip, "port", connID.Port) + utils.LogProcessing("Stopping go routine", structs.ConnIDLogArgs(connID)...) return } } @@ -295,20 +304,20 @@ func (factory *Factory) DeleteWorker(connectionID structs.ConnID) { if ch, exists := factory.processor[connectionID]; exists { close(ch) delete(factory.processor, connectionID) - utils.LogProcessing("Deleted event channel", "fd", connectionID.Fd, "id", connectionID.Id, "timestamp", connectionID.Conn_start_ns, "ip", connectionID.Ip, "port", connectionID.Port) + utils.LogProcessing("Deleted event channel", structs.ConnIDLogArgs(connectionID)...) } if _, exists := factory.connections[connectionID]; exists { delete(factory.connections, connectionID) - utils.LogProcessing("Deleted connection", "fd", connectionID.Fd, "id", connectionID.Id, "timestamp", connectionID.Conn_start_ns, "ip", connectionID.Ip, "port", connectionID.Port) + utils.LogProcessing("Deleted connection", structs.ConnIDLogArgs(connectionID)...) requestProcessCount++ } if (time.Now().UnixMilli())-lastMemCheck > int64(memCheckInterval) { lastMemCheck = time.Now().UnixMilli() mem := utils.LogMemoryStats() - utils.PrintLog("Requests processed", "count", requestProcessCount, "lastMemCheck", lastMemCheck) - utils.PrintLog("connection factory size", "connections", len(factory.connections), "processors", len(factory.processor), "lastMemCheck", lastMemCheck) + slog.Debug("Requests processed", "count", requestProcessCount, "lastMemCheck", lastMemCheck) + slog.Debug("connection factory size", "connections", len(factory.connections), "processors", len(factory.processor), "lastMemCheck", lastMemCheck) requestProcessCount = 0 if mem >= bufferMemThreshold { trackersToDelete := make(map[structs.ConnID]struct{}) @@ -346,20 +355,20 @@ func (factory *Factory) SendEvent(connectionID structs.ConnID, event interface{} ch, exists := factory.getChannel(connectionID) if exists { - utils.LogProcessing("Received event", "fd", connectionID.Fd, "id", connectionID.Id, "timestamp", connectionID.Conn_start_ns, "ip", connectionID.Ip, "port", connectionID.Port) + utils.LogProcessing("Received event", structs.ConnIDLogArgs(connectionID)...) defer func() { if r := recover(); r != nil { // Recover from a panic, caused by sending to a closed channel - utils.LogProcessing("Attempted to send on a closed channel for connectionId", "connectionId", connectionID) + utils.LogProcessing("Attempted to send on a closed channel for connectionId", structs.ConnIDLogArgs(connectionID)...) } }() select { case ch <- event: // Try sending the event to the worker's channel - utils.LogProcessing("Sent event", "fd", connectionID.Fd, "id", connectionID.Id, "timestamp", connectionID.Conn_start_ns, "ip", connectionID.Ip, "port", connectionID.Port) + utils.LogProcessing("Sent event", structs.ConnIDLogArgs(connectionID)...) default: // Avoid blocking if the channel is full - utils.LogProcessing("Dropping event Channel full", "connectionId", connectionID) + utils.LogProcessing("Dropping event Channel full", structs.ConnIDLogArgs(connectionID)...) } } else { - utils.LogProcessing("No worker found for", "connectionId", connectionID) + utils.LogProcessing("No worker found for", structs.ConnIDLogArgs(connectionID)...) } } diff --git a/ebpf/connections/parser.go b/ebpf/connections/parser.go index 65b4a69d..3331058d 100644 --- a/ebpf/connections/parser.go +++ b/ebpf/connections/parser.go @@ -1,10 +1,11 @@ package connections import ( + "github.com/akto-api-security/mirroring-api-logging/ebpf/structs" "github.com/akto-api-security/mirroring-api-logging/trafficUtil/kafkaUtil" ) -func tryReadFromBD(ip string, destIp string, receiveBuffer []byte, sentBuffer []byte, isComplete bool, direction int, id uint64, fd uint32, daemonsetIdentifier, hostName string) { +func tryReadFromBD(ip string, destIp string, receiveBuffer []byte, sentBuffer []byte, isComplete bool, direction int, id uint64, fd uint32, daemonsetIdentifier, hostName string, connID structs.ConnID) { ctx := kafkaUtil.TrafficContext{ SourceIP: ip, DestIP: destIp, @@ -17,6 +18,13 @@ func tryReadFromBD(ip string, destIp string, receiveBuffer []byte, sentBuffer [] SocketFD: fd, DaemonsetIdentifier: daemonsetIdentifier, HostName: hostName, + ConnID: &kafkaUtil.TrafficConnID{ + ID: connID.Id, + Fd: connID.Fd, + Timestamp: connID.Conn_start_ns, + Ip: connID.Ip, + Port: connID.Port, + }, } kafkaUtil.ParseAndProduce(receiveBuffer, sentBuffer, ctx) } diff --git a/ebpf/connections/tracker.go b/ebpf/connections/tracker.go index 3056d0be..61ba6c9f 100644 --- a/ebpf/connections/tracker.go +++ b/ebpf/connections/tracker.go @@ -49,7 +49,7 @@ func (conn *Tracker) IsComplete() bool { complete := conn.closeTimestamp != 0 && uint64(time.Now().UnixNano()) >= conn.closeTimestamp if complete { - metaUtils.LogProcessing("Connection closed", "fd", conn.connID.Fd, "id", conn.connID.Id, "closeTimestamp", conn.closeTimestamp, "currentTimestamp", uint64(time.Now().UnixNano())) + metaUtils.LogProcessing("Connection closed", append(structs.ConnIDLogArgs(conn.connID), "closeTimestamp", conn.closeTimestamp, "currentTimestamp", uint64(time.Now().UnixNano()))...) } return complete } @@ -115,4 +115,4 @@ func (conn *Tracker) GetSentBytes() uint64 { func (conn *Tracker) GetRecvBytes() uint64 { return conn.recvBytes -} \ No newline at end of file +} diff --git a/ebpf/go.mod b/ebpf/go.mod index 487f63a9..c43b13b1 100644 --- a/ebpf/go.mod +++ b/ebpf/go.mod @@ -1,8 +1,6 @@ module github.com/akto-api-security/mirroring-api-logging/ebpf -go 1.24.0 - -toolchain go1.24.3 +go 1.25.8 require ( github.com/akto-api-security/mirroring-api-logging/trafficUtil v0.0.0-00010101000000-000000000000 @@ -13,64 +11,73 @@ require ( require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/google/gnostic-models v0.6.9 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.1 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonreference v0.21.5 // indirect + github.com/go-openapi/swag v0.25.5 // indirect + github.com/go-openapi/swag/cmdutils v0.25.5 // indirect + github.com/go-openapi/swag/conv v0.25.5 // indirect + github.com/go-openapi/swag/fileutils v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.25.5 // indirect + github.com/go-openapi/swag/jsonutils v0.25.5 // indirect + github.com/go-openapi/swag/loading v0.25.5 // indirect + github.com/go-openapi/swag/mangling v0.25.5 // indirect + github.com/go-openapi/swag/netutils v0.25.5 // indirect + github.com/go-openapi/swag/stringutils v0.25.5 // indirect + github.com/go-openapi/swag/typeutils v0.25.5 // indirect + github.com/go-openapi/swag/yamlutils v0.25.5 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/pflag v1.0.7 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.46.0 // indirect - golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/term v0.36.0 // indirect - golang.org/x/time v0.9.0 // indirect - google.golang.org/protobuf v1.36.6 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/time v0.15.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.33.0 // indirect - k8s.io/apimachinery v0.33.0 // indirect - k8s.io/client-go v0.33.0 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + k8s.io/api v0.35.3 // indirect + k8s.io/apimachinery v0.35.3 // indirect + k8s.io/client-go v0.35.3 // indirect + k8s.io/klog/v2 v2.140.0 // indirect + k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 // indirect + k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) require ( github.com/go-ole/go-ole v1.2.6 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/klauspost/compress v1.18.0 // indirect - github.com/montanaflynn/stats v0.7.1 // indirect - github.com/pierrec/lz4/v4 v4.1.21 // indirect - github.com/segmentio/kafka-go v0.4.47 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/klauspost/compress v1.18.5 // indirect + github.com/montanaflynn/stats v0.9.0 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect + github.com/segmentio/kafka-go v0.4.50 // indirect github.com/tklauser/go-sysconf v0.3.13 // indirect github.com/tklauser/numcpus v0.7.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/scram v1.2.0 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect - go.mongodb.org/mongo-driver v1.14.0 // indirect + go.mongodb.org/mongo-driver v1.17.9 // indirect golang.org/x/arch v0.7.0 - golang.org/x/crypto v0.43.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/text v0.30.0 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/text v0.36.0 // indirect ) replace github.com/akto-api-security/mirroring-api-logging/trafficUtil => ../trafficUtil diff --git a/ebpf/go.sum b/ebpf/go.sum index 5093045d..fe3eb6a7 100644 --- a/ebpf/go.sum +++ b/ebpf/go.sum @@ -1,66 +1,74 @@ github.com/cilium/ebpf v0.21.0 h1:4dpx1J/B/1apeTmWBH5BkVLayHTkFrMovVPnHEk+l3k= github.com/cilium/ebpf v0.21.0/go.mod h1:1kHKv6Kvh5a6TePP5vvvoMa1bclRyzUXELSs272fmIQ= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= +github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= +github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= +github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= +github.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU= +github.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA= +github.com/go-openapi/swag/cmdutils v0.25.5 h1:yh5hHrpgsw4NwM9KAEtaDTXILYzdXh/I8Whhx9hKj7c= +github.com/go-openapi/swag/cmdutils v0.25.5/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= +github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= +github.com/go-openapi/swag/fileutils v0.25.5 h1:B6JTdOcs2c0dBIs9HnkyTW+5gC+8NIhVBUwERkFhMWk= +github.com/go-openapi/swag/fileutils v0.25.5/go.mod h1:V3cT9UdMQIaH4WiTrUc9EPtVA4txS0TOmRURmhGF4kc= +github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= +github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= +github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= +github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo= +github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= +github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= +github.com/go-openapi/swag/mangling v0.25.5 h1:hyrnvbQRS7vKePQPHHDso+k6CGn5ZBs5232UqWZmJZw= +github.com/go-openapi/swag/mangling v0.25.5/go.mod h1:6hadXM/o312N/h98RwByLg088U61TPGiltQn71Iw0NY= +github.com/go-openapi/swag/netutils v0.25.5 h1:LZq2Xc2QI8+7838elRAaPCeqJnHODfSyOa7ZGfxDKlU= +github.com/go-openapi/swag/netutils v0.25.5/go.mod h1:lHbtmj4m57APG/8H7ZcMMSWzNqIQcu0RFiXrPUara14= +github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= +github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= +github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= +github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= +github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= +github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0 h1:7SgOMTvJkM8yWrQlU8Jm18VeDPuAvB/xWrdxFJkoFag= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM= +github.com/go-openapi/testify/v2 v2.4.0 h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM= +github.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6 h1:teYtXy9B7y5lHTp8V9KPxpYRAVA7dozigQcMiBust1s= github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6/go.mod h1:p4lGIVX+8Wa6ZPNDvqcxq36XpUDLh42FLetFU7odllI= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA= github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w= github.com/jsimonetti/rtnetlink/v2 v2.0.1 h1:xda7qaHDSVOsADNouv7ukSuicKZO7GgVUCXxpaIEIlM= github.com/jsimonetti/rtnetlink/v2 v2.0.1/go.mod h1:7MoNYNbb3UaDHtF8udiJo/RH6VsTKP1pqKLUTVCvToE= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= -github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= +github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g= github.com/mdlayher/netlink v1.7.2/go.mod h1:xraEF7uJbxLhc5fpHL4cPe221LI2bdttWlU+ZGLfQSw= github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= @@ -68,43 +76,32 @@ github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTa github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= -github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.9.0 h1:tsBJ0RXwph9BmAuFoCmqGv6e8xa0MENQ8m0ptKq29mQ= +github.com/montanaflynn/stats v0.9.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= -github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/segmentio/kafka-go v0.4.47 h1:IqziR4pA3vrZq7YdRxaT3w1/5fvIH5qpCwstUanQQB0= -github.com/segmentio/kafka-go v0.4.47/go.mod h1:HjF6XbOKh0Pjlkr5GVZxt6CsjjwnmhVOfURM5KMd8qg= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/segmentio/kafka-go v0.4.50 h1:mcyC3tT5WeyWzrFbd6O374t+hmcu1NKt2Pu1L3QaXmc= +github.com/segmentio/kafka-go v0.4.50/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= -github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= @@ -113,128 +110,93 @@ github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/scram v1.2.0 h1:bYKF2AEwG5rqd1BumT4gAnvwU/M9nBp2pTSxeZw7Wvs= +github.com/xdg-go/scram v1.2.0/go.mod h1:3dlrS0iBaWKYVt2ZfA4cj48umJZ+cAEbR6/SjLA88I8= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= -github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= -go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= +go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU= +go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= -golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= -k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= -k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= -k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= -k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ= +k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4= +k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8= +k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg= +k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c= +k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= +k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= +k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 h1:V+sn9a/1fEYDGwnllCmqXBk8x7obZ+hl869Q3Abumkg= +k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= +k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM= +k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/ebpf/kernel/module.bpf.c b/ebpf/kernel/module.bpf.c index 22c80707..196078be 100644 --- a/ebpf/kernel/module.bpf.c +++ b/ebpf/kernel/module.bpf.c @@ -293,21 +293,18 @@ struct { } conn_counter SEC(".maps"); struct { - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); - __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(u32)); + __uint(type, BPF_MAP_TYPE_RINGBUF); + __uint(max_entries, 64 * 1024 * 1024); } socket_data_events SEC(".maps"); struct { - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); - __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(u32)); + __uint(type, BPF_MAP_TYPE_RINGBUF); + __uint(max_entries, 1024 * 1024); } socket_open_events SEC(".maps"); struct { - __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); - __uint(key_size, sizeof(u32)); - __uint(value_size, sizeof(u32)); + __uint(type, BPF_MAP_TYPE_RINGBUF); + __uint(max_entries, 1024 * 1024); } socket_close_events SEC(".maps"); struct { @@ -666,8 +663,8 @@ static __always_inline void process_syscall_accept(struct pt_regs* ctx, } socket_open_event.socket_open_ns = conn_info.conn_start_ns; - bpf_perf_event_output(ctx, &socket_open_events, BPF_F_CURRENT_CPU, - &socket_open_event, sizeof(struct socket_open_event_t)); + bpf_ringbuf_output(&socket_open_events, &socket_open_event, + sizeof(struct socket_open_event_t), 0); } static __always_inline void process_syscall_close(struct pt_regs* ctx, @@ -698,8 +695,8 @@ static __always_inline void process_syscall_close(struct pt_regs* ctx, socket_close_event.ip = conn_info->ip; socket_close_event.socket_close_ns = bpf_ktime_get_ns(); - bpf_perf_event_output(ctx, &socket_close_events, BPF_F_CURRENT_CPU, - &socket_close_event, sizeof(struct socket_close_event_t)); + bpf_ringbuf_output(&socket_close_events, &socket_close_event, + sizeof(struct socket_close_event_t), 0); bpf_map_delete_elem(&conn_info_map, &tgid_fd); } @@ -811,9 +808,8 @@ static __always_inline void process_syscall_data(struct pt_regs* ctx, socket_data_event->bytes_sent = is_send ? 1 : -1; socket_data_event->bytes_sent *= size_to_save; - bpf_perf_event_output(ctx, &socket_data_events, BPF_F_CURRENT_CPU, - socket_data_event, - sizeof(struct socket_data_event_t) - MAX_MSG_SIZE + size_to_save); + bpf_ringbuf_output(&socket_data_events, socket_data_event, + sizeof(struct socket_data_event_t) - MAX_MSG_SIZE + size_to_save, 0); bytes_sent += current_size; } @@ -1035,7 +1031,8 @@ int syscall__probe_ret_writev(struct pt_regs* ctx) { } struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - if (write_args != NULL) { + /* Match module.cc: only capture after security_socket_sendmsg marked this syscall. */ + if (write_args != NULL && write_args->sock_event) { if (print_bpf_logs) { bpf_printk("syscall__probe_ret_writev data process: pid: %d", id); } @@ -1128,7 +1125,8 @@ int syscall__probe_ret_readv(struct pt_regs* ctx) { } struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args != NULL) { + /* Match module.cc: only capture after security_socket_recvmsg marked this syscall. */ + if (read_args != NULL && read_args->sock_event) { process_syscall_data_vecs(ctx, read_args, id, false); } @@ -1307,7 +1305,8 @@ int syscall__probe_ret_read(struct pt_regs* ctx) { struct data_args_t* read_args = bpf_map_lookup_elem(&active_read_args_map, &id); - if (read_args != NULL) { + /* Match module.cc: only capture after security_socket_recvmsg marked this syscall. */ + if (read_args != NULL && read_args->sock_event) { process_syscall_data(ctx, read_args, id, false, false); } @@ -1440,7 +1439,8 @@ int syscall__probe_ret_write(struct pt_regs* ctx) { struct data_args_t* write_args = bpf_map_lookup_elem(&active_write_args_map, &id); - if (write_args != NULL) { + /* Match module.cc: only capture after security_socket_sendmsg marked this syscall. */ + if (write_args != NULL && write_args->sock_event) { if (print_bpf_logs) { bpf_printk("syscall__probe_ret_write data process: pid: %d", id); } diff --git a/ebpf/main.go b/ebpf/main.go index 53ab591f..cac2f67d 100644 --- a/ebpf/main.go +++ b/ebpf/main.go @@ -26,8 +26,6 @@ import ( trafficUtils "github.com/akto-api-security/mirroring-api-logging/trafficUtil/utils" ) -var source string = "" - func replaceBpfLogsMacros(spec *ebpf.CollectionSpec) { printBpfLogs := false if v := os.Getenv("PRINT_BPF_LOGS"); strings.EqualFold(v, "true") { @@ -59,8 +57,6 @@ func main() { } func run() { - bpfwrapper.DeleteExistingAktoKernelProbes() - // ----------------------------------------------------------------------- // Load the pre-compiled BPF object. // @@ -87,6 +83,12 @@ func run() { replaceBpfLogsMacros(spec) replaceMaxConnectionMapSize(spec) + // If the kernel supports uprobe_multi (6.6+), mark all SEC("uprobe") + // programs with the multi attach type so they can be attached via + // bpf(BPF_LINK_CREATE) instead of perf_event_open — bypassing + // perf_event_paranoid restrictions. + bpfwrapper.SetUprobeMultiAttachType(spec) + // Load all programs and maps into the kernel. coll, err := ebpf.NewCollection(spec) if err != nil { @@ -182,29 +184,33 @@ func run() { ssl.InitMaps(coll) + attachToProcesses := func() { + slog.Debug("Starting to attach to processes in ticker") + mu.Lock() + if isRunning { + mu.Unlock() + return + } + isRunning = true + mu.Unlock() + + slog.Info("Starting to attach to processes") + processFactory.AddNewProcessesToProbe(coll) + slog.Debug("Ended attaching to processes") + + mu.Lock() + isRunning = false + mu.Unlock() + slog.Debug("Ended attaching to processes in ticker") + } if captureSsl == "true" || captureAll == "true" { + attachToProcesses() go func() { slog.Debug("Starting uprobe process ticker") ticker := time.NewTicker(pollInterval) defer ticker.Stop() for range ticker.C { - slog.Debug("Starting to attach to processes in ticker") - mu.Lock() - if isRunning { - mu.Unlock() - return - } - isRunning = true - mu.Unlock() - - slog.Info("Starting to attach to processes") - processFactory.AddNewProcessesToProbe(coll) - slog.Debug("Ended attaching to processes") - - mu.Lock() - isRunning = false - mu.Unlock() - slog.Debug("Ended attaching to processes in ticker") + attachToProcesses() } slog.Debug("Ended attaching to processes in ticker end") }() diff --git a/ebpf/structs/structs.go b/ebpf/structs/structs.go index 3a88bd09..91823767 100644 --- a/ebpf/structs/structs.go +++ b/ebpf/structs/structs.go @@ -12,6 +12,10 @@ type ConnID struct { Ip uint32 } +func ConnIDLogArgs(id ConnID) []any { + return []any{"fd", id.Fd, "id", id.Id, "timestamp", id.Conn_start_ns, "ip", id.Ip, "port", id.Port} +} + type SocketDataEventAttr struct { ConnId ConnID Bytes_sent int32 diff --git a/ebpf/uprobeBuilder/process/process.go b/ebpf/uprobeBuilder/process/process.go index 464f2f03..c1e0611b 100644 --- a/ebpf/uprobeBuilder/process/process.go +++ b/ebpf/uprobeBuilder/process/process.go @@ -13,7 +13,6 @@ import ( ) var ( - kubepodsRegex = regexp.MustCompile(`cri-containerd-(?P\w+)\.scope`) mapFileContentRegex = regexp.MustCompile("(?P[a-f\\d]+)\\-(?P[a-f\\d]+)\\s(?P[^\\s]+)" + "\\s(?P[a-f\\d]+)\\s[a-f\\d]+\\:[a-f\\d]+\\s\\d+\\s+(?P[^\\n]+)") ) diff --git a/ebpf/uprobeBuilder/process/processFactory.go b/ebpf/uprobeBuilder/process/processFactory.go index 6985a38b..d0a429a3 100644 --- a/ebpf/uprobeBuilder/process/processFactory.go +++ b/ebpf/uprobeBuilder/process/processFactory.go @@ -81,13 +81,19 @@ func (processFactory *ProcessFactory) AddNewProcessesToProbe(coll *ebpf.Collecti } } slog.Debug("Attempt for processes", "count", len(pidSet)) + skippedPids := make(map[int32]bool) for pid := range pidSet { time.Sleep(200 * time.Millisecond) _, ok := processFactory.unattachedProcess[pid] if ok { - slog.Debug("Not attempting for process", "pid", pid) + skippedPids[pid] = true continue } + if len(skippedPids) > 0 { + slog.Debug("Skipped unattached processes", "count", len(skippedPids), "pids", skippedPids) + skippedPids = make(map[int32]bool) + } + _, ok = processFactory.processMap[pid] if !ok { @@ -165,6 +171,9 @@ func (processFactory *ProcessFactory) AddNewProcessesToProbe(coll *ebpf.Collecti processFactory.unattachedProcess[pid] = true } } + if len(skippedPids) > 0 { + slog.Debug("Skipped unattached processes", "count", len(skippedPids), "pids", skippedPids) + } } func checkSelf(pid int32) bool { diff --git a/trafficUtil/go.mod b/trafficUtil/go.mod index 7debcb5e..9d0b8688 100644 --- a/trafficUtil/go.mod +++ b/trafficUtil/go.mod @@ -1,63 +1,71 @@ module github.com/akto-api-security/mirroring-api-logging/trafficUtil -go 1.24.0 - -toolchain go1.24.3 +go 1.25.8 require ( - github.com/segmentio/kafka-go v0.4.25 - go.mongodb.org/mongo-driver v1.11.3 - google.golang.org/protobuf v1.36.6 - k8s.io/api v0.33.0 - k8s.io/apimachinery v0.33.0 - k8s.io/client-go v0.33.0 + github.com/google/uuid v1.6.0 + github.com/segmentio/kafka-go v0.4.50 + go.mongodb.org/mongo-driver v1.17.9 + google.golang.org/protobuf v1.36.11 + k8s.io/api v0.35.3 + k8s.io/apimachinery v0.35.3 + k8s.io/client-go v0.35.3 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/snappy v0.0.1 // indirect - github.com/google/gnostic-models v0.6.9 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.1 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonreference v0.21.5 // indirect + github.com/go-openapi/swag v0.25.5 // indirect + github.com/go-openapi/swag/cmdutils v0.25.5 // indirect + github.com/go-openapi/swag/conv v0.25.5 // indirect + github.com/go-openapi/swag/fileutils v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.25.5 // indirect + github.com/go-openapi/swag/jsonutils v0.25.5 // indirect + github.com/go-openapi/swag/loading v0.25.5 // indirect + github.com/go-openapi/swag/mangling v0.25.5 // indirect + github.com/go-openapi/swag/netutils v0.25.5 // indirect + github.com/go-openapi/swag/stringutils v0.25.5 // indirect + github.com/go-openapi/swag/typeutils v0.25.5 // indirect + github.com/go-openapi/swag/yamlutils v0.25.5 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.13.6 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/klauspost/compress v1.18.5 // indirect + github.com/kr/text v0.2.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/montanaflynn/stats v0.9.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/pierrec/lz4 v2.6.0+incompatible // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/pierrec/lz4/v4 v4.1.26 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/pflag v1.0.10 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.1 // indirect - github.com/xdg-go/stringprep v1.0.3 // indirect - github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.38.0 // indirect - golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sync v0.12.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/term v0.30.0 // indirect - golang.org/x/text v0.23.0 // indirect - golang.org/x/time v0.9.0 // indirect - gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + github.com/xdg-go/scram v1.2.0 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/oauth2 v0.36.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.43.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/text v0.36.0 // indirect + golang.org/x/time v0.15.0 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + k8s.io/klog/v2 v2.140.0 // indirect + k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 // indirect + k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/trafficUtil/go.sum b/trafficUtil/go.sum index 4489cb35..b8978fea 100644 --- a/trafficUtil/go.sum +++ b/trafficUtil/go.sum @@ -2,204 +2,175 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8/yCZMuEPMUDHG0CW/brkkEp8mzqk2+ODEitlw= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= +github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= +github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= +github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= +github.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU= +github.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA= +github.com/go-openapi/swag/cmdutils v0.25.5 h1:yh5hHrpgsw4NwM9KAEtaDTXILYzdXh/I8Whhx9hKj7c= +github.com/go-openapi/swag/cmdutils v0.25.5/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= +github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= +github.com/go-openapi/swag/fileutils v0.25.5 h1:B6JTdOcs2c0dBIs9HnkyTW+5gC+8NIhVBUwERkFhMWk= +github.com/go-openapi/swag/fileutils v0.25.5/go.mod h1:V3cT9UdMQIaH4WiTrUc9EPtVA4txS0TOmRURmhGF4kc= +github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= +github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= +github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= +github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo= +github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= +github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= +github.com/go-openapi/swag/mangling v0.25.5 h1:hyrnvbQRS7vKePQPHHDso+k6CGn5ZBs5232UqWZmJZw= +github.com/go-openapi/swag/mangling v0.25.5/go.mod h1:6hadXM/o312N/h98RwByLg088U61TPGiltQn71Iw0NY= +github.com/go-openapi/swag/netutils v0.25.5 h1:LZq2Xc2QI8+7838elRAaPCeqJnHODfSyOa7ZGfxDKlU= +github.com/go-openapi/swag/netutils v0.25.5/go.mod h1:lHbtmj4m57APG/8H7ZcMMSWzNqIQcu0RFiXrPUara14= +github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= +github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= +github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= +github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= +github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= +github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0 h1:7SgOMTvJkM8yWrQlU8Jm18VeDPuAvB/xWrdxFJkoFag= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM= +github.com/go-openapi/testify/v2 v2.4.0 h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM= +github.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE= +github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.9.0 h1:tsBJ0RXwph9BmAuFoCmqGv6e8xa0MENQ8m0ptKq29mQ= +github.com/montanaflynn/stats v0.9.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= -github.com/pierrec/lz4 v2.6.0+incompatible h1:Ix9yFKn1nSPBLFl/yZknTp8TU5G4Ps0JDmguYK6iH1A= -github.com/pierrec/lz4 v2.6.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY= +github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/segmentio/kafka-go v0.4.25 h1:QVx9yz12syKBFkxR+dVDDwTO0ItHgnjjhIdBfqizj+8= -github.com/segmentio/kafka-go v0.4.25/go.mod h1:XzMcoMjSzDGHcIwpWUI7GB43iKZ2fTVmryPSGLf/MPg= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/segmentio/kafka-go v0.4.50 h1:mcyC3tT5WeyWzrFbd6O374t+hmcu1NKt2Pu1L3QaXmc= +github.com/segmentio/kafka-go v0.4.50/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c h1:u40Z8hqBAAQyv+vATcGgV0YCnDjqSL7/q/JyPhhJSPk= -github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= -github.com/xdg/stringprep v1.0.0 h1:d9X0esnoa3dFsV0FG35rAT0RIhYFlPq7MiP+DW89La0= -github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= -go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= +github.com/xdg-go/scram v1.2.0 h1:bYKF2AEwG5rqd1BumT4gAnvwU/M9nBp2pTSxeZw7Wvs= +github.com/xdg-go/scram v1.2.0/go.mod h1:3dlrS0iBaWKYVt2ZfA4cj48umJZ+cAEbR6/SjLA88I8= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5tU= +go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= -golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= -golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= -golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= -golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= -gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= -k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= -k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= -k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= -k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= -k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= -k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ= +k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4= +k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8= +k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg= +k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c= +k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= +k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= +k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31 h1:V+sn9a/1fEYDGwnllCmqXBk8x7obZ+hl869Q3Abumkg= +k8s.io/kube-openapi v0.0.0-20260330154417-16be699c7b31/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= +k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM= +k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= -sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= -sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8= +sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/trafficUtil/kafkaUtil/kafka.go b/trafficUtil/kafkaUtil/kafka.go index 1df2b620..d2d79594 100644 --- a/trafficUtil/kafkaUtil/kafka.go +++ b/trafficUtil/kafkaUtil/kafka.go @@ -71,16 +71,16 @@ func InitKafka() { if len(kafka_url) == 0 { kafka_url = os.Getenv("AKTO_KAFKA_BROKER_URL") } - utils.PrintLog("kafka_url: " + kafka_url) + slog.Info("kafka_url: " + kafka_url) bytesInThresholdInput := os.Getenv("AKTO_BYTES_IN_THRESHOLD") if len(bytesInThresholdInput) > 0 { bytesInThreshold, err := strconv.Atoi(bytesInThresholdInput) if err != nil { - utils.PrintLog("AKTO_BYTES_IN_THRESHOLD should be valid integer. Found " + bytesInThresholdInput) + slog.Error("AKTO_BYTES_IN_THRESHOLD should be valid integer. Found " + bytesInThresholdInput) return } else { - utils.PrintLog("Setting bytes in threshold at " + strconv.Itoa(bytesInThreshold)) + slog.Info("Setting bytes in threshold at " + strconv.Itoa(bytesInThreshold)) } } @@ -123,7 +123,7 @@ func InitKafka() { } time.Sleep(time.Second * 2) } else { - utils.PrintLog("connection establishing with kafka successfully") + slog.Info("connection establishing with kafka successfully") kafkaWriterMutex.Lock() kafkaWriter.Completion = kafkaCompletion() kafkaWriterMutex.Unlock() diff --git a/trafficUtil/kafkaUtil/parser.go b/trafficUtil/kafkaUtil/parser.go index 1a643c12..ed2563e8 100644 --- a/trafficUtil/kafkaUtil/parser.go +++ b/trafficUtil/kafkaUtil/parser.go @@ -21,6 +21,23 @@ import ( "github.com/akto-api-security/mirroring-api-logging/trafficUtil/utils" ) +// TrafficConnID mirrors ebpf/structs.ConnID fields used for log correlation (eBPF mirroring path). +type TrafficConnID struct { + ID uint64 + Fd uint32 + Timestamp uint64 // connection start, nanoseconds (Conn_start_ns) + Ip uint32 + Port uint16 +} + +// TrafficConnIDLogArgs returns the same alternating key/value pairs as structs.ConnIDLogArgs for slog. +func TrafficConnIDLogArgs(c *TrafficConnID) []any { + if c == nil { + return nil + } + return []any{"fd", c.Fd, "id", c.ID, "timestamp", c.Timestamp, "ip", c.Ip, "port", c.Port} +} + // TrafficContext holds metadata about the captured traffic. // This consolidates the many parameters previously passed to ParseAndProduce. type TrafficContext struct { @@ -35,6 +52,8 @@ type TrafficContext struct { SocketFD uint32 DaemonsetIdentifier string HostName string + // ConnID is set on the eBPF mirroring path for structured logs (nil elsewhere). + ConnID *TrafficConnID } // ParsedTraffic holds the parsed HTTP requests and responses with their bodies. @@ -123,7 +142,7 @@ func buildJSONPayload(input PayloadInput) map[string]string { // resolvePodLabels resolves pod labels for inbound traffic and adds them to the value map. func resolvePodLabels(value map[string]string, ctx TrafficContext, url, host string) { - + if PodInformerInstance == nil { checkDebugUrlAndPrint(url, host, "Pod labels not resolved, PodInformerInstance is nil") return @@ -142,20 +161,20 @@ func resolvePodLabels(value map[string]string, ctx TrafficContext, url, host str if ctx.HostName == "" { checkDebugUrlAndPrint(url, host, "Failed to resolve pod name, hostName is empty for processId "+fmt.Sprint(ctx.ProcessID)) - slog.Debug("Failed to resolve pod name, hostName is empty for ", "processId", ctx.ProcessID, "hostName", ctx.HostName) + slog.Debug("Failed to resolve pod name, hostName is empty for ", append(TrafficConnIDLogArgs(ctx.ConnID), "processId", ctx.ProcessID, "hostName", ctx.HostName)...) return } podLabels, err := PodInformerInstance.ResolvePodLabels(ctx.HostName, url, host) if err != nil { - slog.Error("Failed to resolve pod labels", "hostName", ctx.HostName, "error", err) + slog.Error("Failed to resolve pod labels", append(TrafficConnIDLogArgs(ctx.ConnID), "hostName", ctx.HostName, "error", err)...) checkDebugUrlAndPrint(url, host, "Error resolving pod labels "+ctx.HostName) return } value["tag"] = podLabels checkDebugUrlAndPrint(url, host, "Pod labels found in ParseAndProduce, podLabels found "+fmt.Sprint(podLabels)+" for hostName "+ctx.HostName) - slog.Debug("Pod labels", "podName", ctx.HostName, "labels", podLabels) + slog.Debug("Pod labels", append(TrafficConnIDLogArgs(ctx.ConnID), "podName", ctx.HostName, "labels", podLabels)...) } // convertHeaders converts HTTP headers to both protobuf and string map formats in a single pass. @@ -218,7 +237,7 @@ func shouldProcessRequest(req *http.Request, reqHeaders map[string]string, ctx T } if utils.IgnoreEnvoyProxycalls && ctx.SourceIP == utils.EnvoyProxyIp && ctx.Direction == utils.DirectionOutbound { - slog.Debug("Ignoring outbound envoy proxy call", "sourceIp", ctx.SourceIP, "url", req.URL.String(), "host", req.Host) + slog.Debug("Ignoring outbound envoy proxy call", append(TrafficConnIDLogArgs(ctx.ConnID), "sourceIp", ctx.SourceIP, "url", req.URL.String(), "host", req.Host)...) return false } @@ -250,7 +269,7 @@ var ( "PATCH": true} DebugStrings = []string{} - EventChanBuffSize = 100000 + EventChanBuffSize = 20000 ) const ONE_MINUTE = 60 @@ -377,21 +396,95 @@ func IsValidMethod(method string) bool { return ok } +var httpRequestMethods = [][]byte{ + []byte("GET "), []byte("HEAD "), []byte("POST "), + []byte("PUT "), []byte("DELETE "), []byte("CONNECT "), + []byte("OPTIONS "), []byte("TRACE "), []byte("TRACK "), + []byte("PATCH "), +} + +var httpVersionTag = []byte(" HTTP/") +var httpStatusLinePrefix = []byte("HTTP/") + +// findHTTPRequestBoundaries returns byte offsets where HTTP request lines begin. +// Uses bytes.Index for efficient scanning instead of byte-by-byte iteration. +func findHTTPRequestBoundaries(buf []byte) []int { + var offsets []int + for i := 0; i < len(buf); { + idx := bytes.Index(buf[i:], httpVersionTag) + if idx < 0 { + break + } + pos := i + idx + + lineStart := pos + for lineStart > 0 && buf[lineStart-1] != '\n' { + lineStart-- + } + + for _, method := range httpRequestMethods { + if bytes.HasPrefix(buf[lineStart:], method) { + offsets = append(offsets, lineStart) + break + } + } + + i = pos + len(httpVersionTag) + } + return offsets +} + +// findHTTPResponseBoundaries returns byte offsets where HTTP status lines begin. +// Validates the version+status format to avoid matching "HTTP/" inside bodies. +func findHTTPResponseBoundaries(buf []byte) []int { + var offsets []int + for i := 0; i < len(buf); { + idx := bytes.Index(buf[i:], httpStatusLinePrefix) + if idx < 0 { + break + } + pos := i + idx + + if pos == 0 || buf[pos-1] == '\n' { + remaining := buf[pos:] + // "HTTP/1.0 NNN" or "HTTP/1.1 NNN" (need at least 13 bytes) + if len(remaining) >= 13 && + remaining[5] == '1' && remaining[6] == '.' && + (remaining[7] == '0' || remaining[7] == '1') && + remaining[8] == ' ' && + remaining[9] >= '1' && remaining[9] <= '5' { + offsets = append(offsets, pos) + } else if len(remaining) >= 8 && remaining[5] == '2' && remaining[6] == ' ' { + offsets = append(offsets, pos) + } + } + + i = pos + len(httpStatusLinePrefix) + } + return offsets +} + // parseHTTPTraffic parses HTTP requests and responses from raw byte buffers. -// Returns nil if parsing fails (errors are logged). -func parseHTTPTraffic(reqBuffer, respBuffer []byte, shouldPrint bool) *ParsedTraffic { - // Parse requests - reader := bufio.NewReader(bytes.NewReader(reqBuffer)) +// Splits at HTTP message boundaries so truncated bodies on keep-alive connections +// cannot bleed into adjacent messages. +func parseHTTPTraffic(reqBuffer, respBuffer []byte, shouldPrint bool, ctx TrafficContext) *ParsedTraffic { + reqBoundaries := findHTTPRequestBoundaries(reqBuffer) requests := []http.Request{} requestBodies := []string{} - for { + for i, start := range reqBoundaries { + end := len(reqBuffer) + if i+1 < len(reqBoundaries) { + end = reqBoundaries[i+1] + } + + reader := bufio.NewReader(bytes.NewReader(reqBuffer[start:end])) req, err := http.ReadRequest(reader) - if err == io.EOF || err == io.ErrUnexpectedEOF { - break - } else if err != nil { - utils.PrintLog(fmt.Sprintf("HTTP-request error: %s \n", err)) - return nil + if err != nil { + if err != io.EOF && err != io.ErrUnexpectedEOF { + utils.PrintLog(fmt.Sprintf("HTTP-request error: %s \n", err)) + } + continue } body, err := io.ReadAll(req.Body) req.Body.Close() @@ -405,28 +498,34 @@ func parseHTTPTraffic(reqBuffer, respBuffer []byte, shouldPrint bool) *ParsedTra } if shouldPrint { - slog.Debug("parseHTTPTraffic", "requestCount", len(requests)) + slog.Debug("parseHTTPTraffic", append(TrafficConnIDLogArgs(ctx.ConnID), "requestCount", len(requests))...) } if len(requests) == 0 { return nil } - // Parse responses - reader = bufio.NewReader(bytes.NewReader(respBuffer)) + respBoundaries := findHTTPResponseBoundaries(respBuffer) responses := []http.Response{} responseBodies := []string{} - for { + for i, start := range respBoundaries { + end := len(respBuffer) + if i+1 < len(respBoundaries) { + end = respBoundaries[i+1] + } + + reader := bufio.NewReader(bytes.NewReader(respBuffer[start:end])) resp, err := http.ReadResponse(reader, nil) - if err == io.EOF || err == io.ErrUnexpectedEOF { - break - } else if err != nil { - utils.PrintLog(fmt.Sprintf("HTTP-Response error: %s\n", err)) - return nil + if err != nil { + if err != io.EOF && err != io.ErrUnexpectedEOF { + utils.PrintLog(fmt.Sprintf("HTTP-Response error: %s\n", err)) + } + continue } body, err := io.ReadAll(resp.Body) + resp.Body.Close() if err != nil { utils.PrintLog(fmt.Sprintf("Got err reading resp body: %s\n", err)) body = []byte{} @@ -459,7 +558,7 @@ func parseHTTPTraffic(reqBuffer, respBuffer []byte, shouldPrint bool) *ParsedTra } if shouldPrint { - slog.Debug("parseHTTPTraffic", "responseCount", len(responses)) + slog.Debug("parseHTTPTraffic", append(TrafficConnIDLogArgs(ctx.ConnID), "responseCount", len(responses))...) } return &ParsedTraffic{ @@ -478,10 +577,10 @@ func ParseAndProduce(receiveBuffer []byte, sentBuffer []byte, ctx TrafficContext shouldPrint := debugMode && strings.Contains(string(receiveBuffer), "x-debug-token") if shouldPrint { - slog.Debug("ParseAndProduce", "receiveBuffer", string(receiveBuffer), "sentBuffer", string(sentBuffer)) + slog.Debug("ParseAndProduce", append(TrafficConnIDLogArgs(ctx.ConnID), "receiveBuffer", string(receiveBuffer), "sentBuffer", string(sentBuffer))...) } - parsed := parseHTTPTraffic(receiveBuffer, sentBuffer, shouldPrint) + parsed := parseHTTPTraffic(receiveBuffer, sentBuffer, shouldPrint, ctx) if parsed == nil { return } @@ -493,7 +592,9 @@ func ParseAndProduce(receiveBuffer []byte, sentBuffer []byte, ctx TrafficContext if len(requests) != len(responses) { if shouldPrint { - slog.Debug("Len req-res mismatch", "lenRequests", len(requests), "lenResponses", len(responses), "lenReceiveBuffer", len(receiveBuffer), "lenSentBuffer", len(sentBuffer), "isComplete", ctx.IsComplete) + slog.Debug("Len req-res mismatch", append(TrafficConnIDLogArgs(ctx.ConnID), + "lenRequests", len(requests), "lenResponses", len(responses), + "lenReceiveBuffer", len(receiveBuffer), "lenSentBuffer", len(sentBuffer), "isComplete", ctx.IsComplete)...) } if ctx.IsComplete { return @@ -514,10 +615,10 @@ func ParseAndProduce(receiveBuffer []byte, sentBuffer []byte, ctx TrafficContext for i := 0; i < len(requests); i++ { req := &requests[i] resp := &responses[i] - + url := req.URL.String() checkDebugUrlAndPrint(url, req.Host, "URL,host found in ParseAndProduce") - + // Convert headers in a single pass (both protobuf and string map formats) headers := convertHeaders(req, resp, shouldPrint) @@ -593,12 +694,12 @@ func sendMetrics(headers ConvertedHeaders, ctx TrafficContext, outgoingBytes int if strings.Contains(responsesContent[i], headers.DebugID) { goodRequests++ } else { - slog.Debug("req-resp.String()", "out", string(out)) + slog.Debug("req-resp.String()", append(TrafficConnIDLogArgs(ctx.ConnID), "out", string(out))...) badRequests++ } if goodRequests%100 == 0 || badRequests%100 == 0 { - slog.Debug("Good requests", "count", goodRequests, "badRequests", badRequests) + slog.Debug("Good requests", append(TrafficConnIDLogArgs(ctx.ConnID), "count", goodRequests, "badRequests", badRequests)...) } } } diff --git a/trafficUtil/kafkaUtil/parser_test.go b/trafficUtil/kafkaUtil/parser_test.go index b673916f..7bb9dc81 100644 --- a/trafficUtil/kafkaUtil/parser_test.go +++ b/trafficUtil/kafkaUtil/parser_test.go @@ -13,7 +13,7 @@ func TestParseHTTPTraffic_ValidRequest(t *testing.T) { respBody := `{"status":"success"}` resp := []byte("HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: 20\r\n\r\n" + respBody) - result := parseHTTPTraffic(req, resp, true) + result := parseHTTPTraffic(req, resp, true, TrafficContext{}) if result == nil { t.Fatal("expected non-nil result for valid request") @@ -39,7 +39,7 @@ func TestParseHTTPTraffic_BadGzip(t *testing.T) { // Response claims gzip but body is not gzip encoded resp := []byte("HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\nContent-Type: application/json\r\nContent-Length: 13\r\n\r\nnot-gzip-data") - result := parseHTTPTraffic(req, resp, true) + result := parseHTTPTraffic(req, resp, true, TrafficContext{}) if result == nil { t.Fatal("should not return nil on gzip failure") @@ -67,7 +67,7 @@ func TestParseHTTPTraffic_TruncatedGzip(t *testing.T) { resp := append([]byte("HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\n\r\n"), truncatedGzip...) - result := parseHTTPTraffic(req, resp, true) + result := parseHTTPTraffic(req, resp, true, TrafficContext{}) if result == nil { t.Fatal("should not return nil on truncated gzip") @@ -88,7 +88,7 @@ func TestParseHTTPTraffic_ValidGzip(t *testing.T) { resp := append([]byte("HTTP/1.1 200 OK\r\nContent-Encoding: gzip\r\nContent-Type: application/json\r\n\r\n"), buf.Bytes()...) - result := parseHTTPTraffic(req, resp, true) + result := parseHTTPTraffic(req, resp, true, TrafficContext{}) if result == nil { t.Fatal("expected non-nil result for valid gzip") @@ -102,7 +102,7 @@ func TestParseHTTPTraffic_EmptyRequestBody(t *testing.T) { req := []byte("GET /health HTTP/1.1\r\nHost: example.com\r\n\r\n") resp := []byte("HTTP/1.1 200 OK\r\n\r\nOK") - result := parseHTTPTraffic(req, resp, false) + result := parseHTTPTraffic(req, resp, false, TrafficContext{}) if result == nil { t.Fatal("expected non-nil result") @@ -119,7 +119,7 @@ func TestParseHTTPTraffic_MultipleRequests(t *testing.T) { req := []byte("GET /first HTTP/1.1\r\nHost: example.com\r\nContent-Length: 0\r\n\r\nGET /second HTTP/1.1\r\nHost: example.com\r\nContent-Length: 0\r\n\r\n") resp := []byte("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nfirstHTTP/1.1 200 OK\r\nContent-Length: 6\r\n\r\nsecond") - result := parseHTTPTraffic(req, resp, false) + result := parseHTTPTraffic(req, resp, false, TrafficContext{}) if result == nil { t.Fatal("expected non-nil result") @@ -136,7 +136,7 @@ func TestParseHTTPTraffic_InvalidRequest(t *testing.T) { req := []byte("not a valid http request") resp := []byte("HTTP/1.1 200 OK\r\n\r\nOK") - result := parseHTTPTraffic(req, resp, false) + result := parseHTTPTraffic(req, resp, false, TrafficContext{}) // Should return nil because request parsing fails completely if result != nil { @@ -148,7 +148,7 @@ func TestParseHTTPTraffic_NoRequests(t *testing.T) { req := []byte("") resp := []byte("HTTP/1.1 200 OK\r\n\r\nOK") - result := parseHTTPTraffic(req, resp, false) + result := parseHTTPTraffic(req, resp, false, TrafficContext{}) if result != nil { t.Error("expected nil result for empty request buffer") diff --git a/trafficUtil/utils/common.go b/trafficUtil/utils/common.go index e69197da..38a3d35e 100644 --- a/trafficUtil/utils/common.go +++ b/trafficUtil/utils/common.go @@ -9,17 +9,24 @@ import ( ) var printCounter = 1000 +var printCounterResetAt = time.Now() const ( DirectionInbound = 1 DirectionOutbound = 2 + printCounterMax = 1000 + printCounterReset = 60 // seconds ) /* -Initial 1000 logs, marking as warn. -Help in checking if the module started as expected. +Logs at WARN level with a budget that resets every minute. */ func PrintLog(val string, args ...any) { + now := time.Now() + if now.Sub(printCounterResetAt).Seconds() > printCounterReset { + printCounter = printCounterMax + printCounterResetAt = now + } if printCounter > 0 { slog.Warn(val, args...) printCounter--