Fixed few memory leaks. Implement testing of the functionality.

This commit is contained in:
Kalzu Rekku
2026-01-08 18:55:32 +02:00
parent c663ec0431
commit 1130b7fb8c
10 changed files with 1334 additions and 13 deletions

View File

@@ -38,6 +38,7 @@ const (
type GeneratorState struct {
RemainingCIDRs []string `json:"remaining_cidrs"`
CurrentGen *HostGenState `json:"current_gen,omitempty"`
ActiveGens []HostGenState `json:"active_gens,omitempty"`
TotalCIDRs int `json:"total_cidrs"`
}
@@ -279,6 +280,19 @@ func (g *IPGenerator) buildState() GeneratorState {
Done: false,
}
}
// Save activeGens to preserve interleaving state
if len(g.activeGens) > 0 {
state.ActiveGens = make([]HostGenState, 0, len(g.activeGens))
for _, gen := range g.activeGens {
if gen != nil && !gen.done {
state.ActiveGens = append(state.ActiveGens, HostGenState{
CIDR: gen.prefix.String(),
Current: gen.current.String(),
Done: false,
})
}
}
}
return state
}
@@ -365,6 +379,25 @@ func (g *IPGenerator) loadState() error {
g.currentGen = gen
}
// Restore activeGens to preserve interleaving state
if len(state.ActiveGens) > 0 {
g.activeGens = make([]*hostGenerator, 0, len(state.ActiveGens))
for _, genState := range state.ActiveGens {
gen, err := newHostGenerator(genState.CIDR)
if err != nil {
log.Printf("⚠️ Failed to restore activeGen %s: %v", genState.CIDR, err)
continue
}
gen.current, err = netip.ParseAddr(genState.Current)
if err != nil {
log.Printf("⚠️ Failed to parse current IP for activeGen %s: %v", genState.CIDR, err)
continue
}
gen.done = genState.Done
g.activeGens = append(g.activeGens, gen)
}
}
return nil
}
@@ -373,7 +406,13 @@ type Server struct {
generators map[string]*IPGenerator
lastAccess map[string]time.Time
allCIDRs []string
globalSeen map[string]bool // Global deduplication across all sources
// MULTI-INSTANCE LIMITATION: globalSeen is instance-local, not shared across
// multiple input_service instances. In multi-instance deployments, either:
// 1. Use session affinity for ping workers (same worker always talks to same instance)
// 2. POST discovered hops to ALL input_service instances, or
// 3. Implement shared deduplication backend (Redis, database, etc.)
// Without this, different instances may serve duplicate hops.
globalSeen map[string]bool // Global deduplication across all sources (instance-local)
mu sync.RWMutex
stopSaver chan struct{}
stopCleanup chan struct{}
@@ -435,7 +474,15 @@ func (s *Server) loadAllCIDRs() error {
fields := strings.Fields(line)
for _, field := range fields {
if field != "" {
if strings.Contains(field, "/") || netip.MustParseAddr(field).IsValid() {
// Accept CIDRs (contains /) or valid IP addresses
isCIDR := strings.Contains(field, "/")
isValidIP := false
if !isCIDR {
if addr, err := netip.ParseAddr(field); err == nil && addr.IsValid() {
isValidIP = true
}
}
if isCIDR || isValidIP {
s.allCIDRs = append(s.allCIDRs, field)
}
}