Fixed few memory leaks. Implement testing of the functionality.
This commit is contained in:
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user