mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(tools): keep SSH ControlMaster socket path under macOS 104-byte limit
On macOS, Unix domain socket paths are capped at 104 bytes (sun_path). SSH appends a 16-byte random suffix to the ControlPath when operating in ControlMaster mode. With an IPv6 host embedded literally in the filename and a deeply-nested macOS $TMPDIR like /var/folders/XX/YYYYYYYYYYYY/T/, the full path reliably exceeds the limit — every terminal/file-op tool call then fails immediately with ``unix_listener: path "…" too long for Unix domain socket``. Swap the ``user@host:port.sock`` filename for a sha256-derived 16-char hex digest. The digest is deterministic for a given (user, host, port) triple, so ControlMaster reuse across reconnects is preserved, and the full path fits comfortably under the limit even after SSH's random suffix. Collision space is 2^64 — effectively unreachable for the handful of concurrent connections any single Hermes process holds. Regression tests cover: path length under realistic macOS $TMPDIR with the IPv6 host from the issue report, determinism for reconnects, and distinctness across different (user, host, port) triples. Closes #11840
This commit is contained in:
parent
649ef5c8f1
commit
64a1368210
2 changed files with 81 additions and 1 deletions
|
|
@ -1,5 +1,6 @@
|
|||
"""SSH remote execution environment with ControlMaster connection persistence."""
|
||||
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
import shlex
|
||||
|
|
@ -47,7 +48,18 @@ class SSHEnvironment(BaseEnvironment):
|
|||
|
||||
self.control_dir = Path(tempfile.gettempdir()) / "hermes-ssh"
|
||||
self.control_dir.mkdir(parents=True, exist_ok=True)
|
||||
self.control_socket = self.control_dir / f"{user}@{host}:{port}.sock"
|
||||
# Keep the socket filename short and deterministic so the full path
|
||||
# stays under the 104-byte sun_path limit that macOS enforces on
|
||||
# Unix domain sockets. A raw ``user@host:port`` — especially with an
|
||||
# IPv6 host — plus the 16-byte random suffix SSH appends in
|
||||
# ControlMaster mode easily exceeds the limit under macOS's
|
||||
# deeply-nested $TMPDIR (e.g. /var/folders/xx/yy/T/). Hashing the
|
||||
# triple keeps the path stable across reconnects so ControlMaster
|
||||
# reuse still works.
|
||||
_socket_id = hashlib.sha256(
|
||||
f"{user}@{host}:{port}".encode()
|
||||
).hexdigest()[:16]
|
||||
self.control_socket = self.control_dir / f"{_socket_id}.sock"
|
||||
_ensure_ssh_available()
|
||||
self._establish_connection()
|
||||
self._remote_home = self._detect_remote_home()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue