Recon network batch 2: fleet relay scan and UDP hints.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

POST /api/v1/recon/relay-scan probes from the dashboard when reachable, otherwise dispatches recon_relay_scan to a same-/24 online agent. Agents reuse probePortsFn for TCP and optionally UDP 53/51820 with dns/wireguard Path Tracer tags.
This commit is contained in:
AetherForge
2026-06-07 11:58:09 -07:00
parent 53d43c7aea
commit 5dd5b1d894
12 changed files with 643 additions and 19 deletions

View File

@@ -827,7 +827,7 @@ func (c *AgentClient) handleCommand(action string, tailLines int, command, path,
if c.handleFileCommand(action, path, data) {
return
}
if c.handleReconCommand(action, command) {
if c.handleReconCommand(action, command, path) {
return
}
c.sendCommandResult(action, false, "unknown action")

View File

@@ -24,7 +24,22 @@ func (c *AgentClient) runExecCommand(command string) ([]byte, error) {
return exec.Command("/bin/sh", "-c", command).CombinedOutput()
}
func (c *AgentClient) handleReconCommand(action, command string) bool {
func (c *AgentClient) handleReconCommand(action, command, path string) bool {
if action == "recon_relay_scan" {
host := strings.TrimSpace(command)
if host == "" {
c.sendCommandResult(action, false, "host is required in command field")
return true
}
udpGuess := strings.EqualFold(strings.TrimSpace(path), "true")
out, err := deploy.RunRelayScanJSON(host, udpGuess)
if err != nil {
c.sendCommandResult(action, false, err.Error())
return true
}
c.sendCommandResult(action, true, out)
return true
}
if action == "connectivity_probe" {
probe := runConnectivityProbe(c.cfg.ServerURL, c.cfg.PoolHost, c.cfg.PoolPort)
b, _ := json.Marshal(probe)

View File

@@ -0,0 +1,57 @@
package client
import (
"encoding/json"
"testing"
"crypto-miner-agent/deploy"
)
func TestHandleReconRelayScanCommand(t *testing.T) {
deploy.SetProbePortsHook(func(host string, ports []int) []int {
if host == "10.1.2.3" {
return []int{22, 445}
}
return nil
})
t.Cleanup(func() { deploy.SetProbePortsHook(nil) })
deploy.SetRelayUDPGuessHook(func(host string, ports []int) []deploy.RelayUDPHint {
return []deploy.RelayUDPHint{{Port: 51820, Open: true, Service: "wireguard"}}
})
t.Cleanup(func() { deploy.SetRelayUDPGuessHook(nil) })
var gotAction string
var gotSuccess bool
var gotMsg string
c := &AgentClient{}
c.commandResultHook = func(action string, success bool, message string) {
gotAction, gotSuccess, gotMsg = action, success, message
}
if !c.handleReconCommand("recon_relay_scan", "10.1.2.3", "true") {
t.Fatal("expected handled")
}
if gotAction != "recon_relay_scan" || !gotSuccess {
t.Fatalf("action=%s success=%v", gotAction, gotSuccess)
}
var parsed map[string]interface{}
if err := json.Unmarshal([]byte(gotMsg), &parsed); err != nil {
t.Fatal(err)
}
ports, _ := parsed["open_ports"].([]interface{})
if len(ports) != 2 {
t.Fatalf("ports=%v", ports)
}
}
func TestHandleReconRelayScanMissingHost(t *testing.T) {
c := &AgentClient{}
c.commandResultHook = func(action string, success bool, _ string) {
if action != "recon_relay_scan" || success {
t.Fatalf("action=%s success=%v", action, success)
}
}
if !c.handleReconCommand("recon_relay_scan", "", "") {
t.Fatal("expected handled")
}
}