mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-22 03:49:18 +02:00
[Debug] Virtual Printer proxy: diagnostic port probing for A1 (#757)
A1/A1 Mini printers fail to connect through VP proxy mode while
X1C/P2S/H2C work fine with identical transparent TCP proxy code.
Root cause unknown — the proxy is model-agnostic, so the failure
suggests BambuStudio uses a different connection flow for A1 models
that hits ports we don't proxy.
Add diagnostic probe listeners on ports 21, 80, and 443 on each
proxy VP's dedicated bind IP. If the slicer connects to any of
these un-proxied ports, a WARNING is logged so debug logs and
tcpdump can reveal what's missing.
This commit is contained in:
@@ -1463,6 +1463,7 @@ class SlicerProxyManager:
|
||||
self._rtsp_proxy: TCPProxy | None = None
|
||||
self._bind_proxies: list[TCPProxy] = []
|
||||
self._bind_server = None
|
||||
self._probe_servers: list[asyncio.Server] = []
|
||||
self._tasks: list[asyncio.Task] = []
|
||||
|
||||
# FTP passive data port range — Bambu printers typically use ports in
|
||||
@@ -1650,6 +1651,23 @@ class SlicerProxyManager:
|
||||
)
|
||||
)
|
||||
|
||||
# Diagnostic probe: listen on common un-proxied ports to detect
|
||||
# if the slicer tries to reach a service we don't handle.
|
||||
if self.bind_address and self.bind_address != "0.0.0.0":
|
||||
for probe_port in (21, 80, 443):
|
||||
try:
|
||||
srv = await asyncio.start_server(
|
||||
lambda r, w, p=probe_port: self._probe_handler(r, w, p),
|
||||
self.bind_address,
|
||||
probe_port,
|
||||
)
|
||||
self._probe_servers.append(srv)
|
||||
except OSError:
|
||||
pass # Port in use or no permission — skip
|
||||
if self._probe_servers:
|
||||
probed = [s.sockets[0].getsockname()[1] for s in self._probe_servers if s.sockets]
|
||||
logger.info("Proxy diagnostic: probing un-proxied ports %s on %s", probed, self.bind_address)
|
||||
|
||||
logger.info(
|
||||
"Slicer proxy started for %s (transparent TCP + MQTT TLS, %d FTP data ports)",
|
||||
self.target_host,
|
||||
@@ -1696,6 +1714,10 @@ class SlicerProxyManager:
|
||||
await dp.stop()
|
||||
self._ftp_data_proxies = []
|
||||
|
||||
for srv in self._probe_servers:
|
||||
srv.close()
|
||||
self._probe_servers = []
|
||||
|
||||
# Cancel tasks
|
||||
for task in self._tasks:
|
||||
task.cancel()
|
||||
@@ -1712,6 +1734,21 @@ class SlicerProxyManager:
|
||||
self._tasks = []
|
||||
logger.info("Slicer proxy stopped")
|
||||
|
||||
async def _probe_handler(self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, port: int) -> None:
|
||||
"""Log unexpected connections on un-proxied ports for diagnostics."""
|
||||
peername = writer.get_extra_info("peername")
|
||||
client = f"{peername[0]}:{peername[1]}" if peername else "unknown"
|
||||
logger.warning(
|
||||
"PROBE: slicer connected to un-proxied port %d from %s — this port may need proxying",
|
||||
port,
|
||||
client,
|
||||
)
|
||||
writer.close()
|
||||
try:
|
||||
await writer.wait_closed()
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def _log_activity(self, name: str, message: str) -> None:
|
||||
"""Log activity via callback if configured."""
|
||||
if self.on_activity:
|
||||
|
||||
Reference in New Issue
Block a user