windows probe-only agent + agent version display unification + reality sni from sing-box fragment
Scope B (Windows agent): - probe.go split into shared core + probe_linux.go (verbatim Linux sampler, build-tagged) + probe_windows.go (Win32 sampler: GetSystemTimes CPU diff, GlobalMemoryStatusEx, fixed-drive df totals, GetIfTable2 counted set, MachineGuid boot identity, registry facts; load and TCP/UDP counts stay zero - x/sys v0.47.0 exports no wrapper) - update intents are acknowledged and skipped on Windows (the release assets are Linux binaries; Windows nodes update via install-agent.ps1) - cmd/xui-agent-windows: SCM service host (svc.Run + mgr install/ uninstall/start/stop) mirroring main.go's agent lifecycle wiring - install-agent.ps1: downloads the exe, writes probeOnly agent.json, registers and starts the service, rerun-safe Scope C (version display): - config.GetAgentDisplayVersion (and the master getter) compose from the bare number so a V-form injection no longer doubles the letter (AV2.1.0 -> A2.1.0) - node list view repairs stored AV-prefixed reports at assembly so deployed agents read uniformly without an update Scope D (production fix): - share-link reality sni: when the inbound has a sing-box fragment, sni is the fragment's tls.server_name - the only name the sing-box REALITY server serves. The previous rule picked a uniformly random serverNames entry per generation, which xray tolerated but sing-box refuses as an invalid connection. sid keeps its random pick: the converter carries the whole shortIds list into the fragment, so every listed sid is served.
This commit is contained in:
@@ -159,6 +159,39 @@ func TestAgentUpdateExecFailureRollsBack(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAgentUpdateSkippedOnUnsupportedOS(t *testing.T) {
|
||||
orig := selfUpdateSupported
|
||||
selfUpdateSupported = false
|
||||
t.Cleanup(func() { selfUpdateSupported = orig })
|
||||
|
||||
var hits atomic.Int32
|
||||
srv := fakeReleaseServer(t, []byte("new-binary"), true, &hits)
|
||||
defer srv.Close()
|
||||
a, exe := newUpdateTestAgent(t, srv.URL)
|
||||
|
||||
intent := &updateIntent{RequestedAt: 46, Target: "A2.0.1", Tag: "V2.0.1", BaseURL: srv.URL + "/"}
|
||||
a.maybeHandleUpdate(intent)
|
||||
// A repeated delivery of the same intent is also a no-op.
|
||||
a.maybeHandleUpdate(intent)
|
||||
|
||||
if hits.Load() != 0 {
|
||||
t.Fatalf("release server hit %d times on an unsupported OS, want 0", hits.Load())
|
||||
}
|
||||
got, _ := os.ReadFile(exe)
|
||||
if string(got) != "old-binary" {
|
||||
t.Fatalf("exe = %q, want untouched old-binary", got)
|
||||
}
|
||||
a.updateMu.Lock()
|
||||
handled, running := a.updateHandled, a.updateRunning
|
||||
a.updateMu.Unlock()
|
||||
if handled != 46 || running {
|
||||
t.Fatalf("handled=%d running=%v, want handled=46 running=false", handled, running)
|
||||
}
|
||||
if rep := a.currentUpdateReport(); rep != nil {
|
||||
t.Fatalf("report = %+v, want none for a skipped intent", rep)
|
||||
}
|
||||
}
|
||||
|
||||
var errExecBoom = &execBoomError{}
|
||||
|
||||
type execBoomError struct{}
|
||||
|
||||
Reference in New Issue
Block a user