fix mcp-path registration, relative remote teardown, reuse existing remote listener

This commit is contained in:
Luxferre
2026-09-15 10:30:28 +03:00
parent a8f3767b90
commit 936dad0ea7
3 changed files with 46 additions and 10 deletions
+35 -7
View File
@@ -91,6 +91,7 @@ GetOptions(
'test-port=i' => \$opt{test_port},
'workdir=s' => \$opt{workdir},
'gs-netcat=s' => \$opt{gs_netcat},
'mcp-path=s' => \$opt{mcp_path},
'insecure' => \$opt{insecure},
'verbose|v' => \$opt{verbose},
'no-mcp' => \$opt{no_mcp},
@@ -135,6 +136,7 @@ Options:
--test-host HOST Host probed through each SOCKS (default www.google.com)
--test-port PORT Port probed through each SOCKS (default 443)
--workdir DIR Remote workdir for the MCP call (default .)
--mcp-path PATH MCP path appended to base endpoint (default /gradio_api/mcp/)
--gs-netcat PATH gs-netcat binary (default: from PATH)
--target-sha256 HASH Verify remote gs-netcat SHA-256 before running (64 hex)
--log FILE Log file (default ./gsproxy.log)
@@ -410,13 +412,35 @@ sub target_cmd {
return $cmd;
}
# Remote /proc access is expressed relative to the remote workdir because the
# MCP sandbox rejects absolute paths. With the default workdir the remote shell
# runs with cwd '/', so 'proc/...' resolves to /proc/... without a leading '/'.
sub remote_scan_cmd {
my ($secret, $action) = @_;
my $pat = shq('GSOCKET_ARGS=-lSD -s ' . $secret);
return 'for p in proc/[0-9]*; do '
. 'grep -Fq -a -- ' . $pat . ' "$p/environ" 2>/dev/null && { '
. $action
. '; }; done; true';
}
sub teardown_cmd {
my ($secret) = @_;
my $pat = shq('GSOCKET_ARGS=-lSD -s ' . $secret);
return 'for p in /proc/[0-9]*; do '
. 'grep -Fq -a -- ' . $pat . ' $p/environ 2>/dev/null && '
. 'kill $(basename $p) 2>/dev/null; '
. 'done; true';
return remote_scan_cmd($secret, 'kill "${p##*/}" 2>/dev/null');
}
sub reuse_check_cmd {
my ($secret) = @_;
return remote_scan_cmd($secret, 'echo GS_REUSED');
}
# Returns true when the endpoint already runs a listener for this secret, so the
# caller can reuse it instead of spawning a duplicate remote gs-netcat.
sub remote_listener_alive {
my ($e) = @_;
my ($ok, $out) = mcp_call($e->{endpoint}, reuse_check_cmd($e->{secret}));
return 0 unless $ok;
return index($out, 'GS_REUSED') >= 0 ? 1 : 0;
}
sub read_proc_file {
@@ -527,8 +551,12 @@ sub bring_up {
my $port = $e->{port};
logmsg(qq{bring-up $label: secret } . mask($e->{secret}) . qq{ port $port});
if (!$opt{no_mcp}) {
my ($ok, $out) = mcp_call($e->{endpoint}, target_cmd($e->{secret}));
logmsg('MCP ' . $e->{endpoint} . ': ' . ($ok ? 'ok' : 'failed') . ' ' . one_line($out));
if (remote_listener_alive($e)) {
logmsg('MCP ' . $e->{endpoint} . ': reusing existing remote gs-netcat listener');
} else {
my ($ok, $out) = mcp_call($e->{endpoint}, target_cmd($e->{secret}));
logmsg('MCP ' . $e->{endpoint} . ': ' . ($ok ? 'ok' : 'failed') . ' ' . one_line($out));
}
}
if (!$opt{no_local}) {
my ($ok, $msg) = start_local($e);