fix(trayicon): bypass SOCKS proxy for X11 connections under --tor always#40
Merged
Conversation
When --tor always is set, src/util/SocksProxy.py:monkeyPatch replaces
socket.socket globally with socks.socksocket. pystray's _xorg backend
then connects to /tmp/.X11-unix/X* via AF_UNIX, which PySocks rejects
("PySocks doesn't support IPv6"). The TCP fallback also fails because
no destination is configured for the local X server.
Before #38 this killed the daemon. After #38 the broad except handler
catches DisplayConnectionError and continues without a tray icon —
but Tor users on a desktop still lose their tray icon for no good
reason (local X11 must never go over Tor anyway).
Fix:
- Temporarily restore socket.socket = socket.socket_noproxy while
pystray imports, so the import-time Xlib.display.Display() in
pystray/_xorg.py succeeds.
- Install a delegating socket-module shim into the loaded Xlib
modules (Xlib.support.unix_connect, Xlib.support.connect,
Xlib.protocol.display) whose .socket attribute is the un-proxied
class. This handles pystray._xorg's later Display() calls in
Icon.__init__ / Icon.run (running in the tray thread, long after
main() returns) which would otherwise re-hit the SOCKS-patched
global socket.
- Restore socket.socket in `finally` so all other EpixNet/Gevent
traffic continues to route through Tor.
No-op when --tor always is not in use, because socket.socket_noproxy
only exists after SocksProxy.monkeyPatch has run.
Credit: @parkour86 reported the bug and supplied a working patch in
the issue; this commit is a lightly cleaned-up version of their fix.
Fixes #30
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #30. With `--tor always` on a desktop Linux session with `$DISPLAY` set, EpixNet's tray icon previously crashed the daemon (pre-#38) or silently failed to appear (post-#38). The root cause is that local X11 traffic was being routed through Tor, which can't speak X11 to `/tmp/.X11-unix/X*`.
Credit to @parkour86 for the detailed report and a working patch in the issue body — this PR is a lightly cleaned-up version of their fix.
Root cause
`src/util/SocksProxy.py:monkeyPatch` replaces `socket.socket` with `socks.socksocket` globally so all outbound traffic routes through the Tor SOCKS proxy. When pystray's `_xorg` backend imports `Xlib`, Xlib.support.unix_connect does `socket.socket(socket.AF_UNIX, ...)` to talk to the local X server. PySocks rejects `AF_UNIX` (`PySocks doesn't support IPv6`), and the TCP fallback to `localhost:6001` also fails (`Invalid destination-connection (host, port) pair`).
Local X11 should never go over Tor anyway, so the right fix is to make Xlib use the un-proxied socket.
Fix
In `plugins/Trayicon/TrayiconPlugin.py`, inside `ActionsPlugin.main()`:
The fix is a no-op when `--tor always` is not in use, because `socket.socket_noproxy` only exists after `SocksProxy.monkeyPatch` has run (gated by `hasattr(socket, 'socket_noproxy')`).
Differences from @parkour86's suggested patch
Test plan
Notes
The Xlib module shim is not restored — it's a permanent side effect for the lifetime of the process. That's intentional: any future X11 connection should bypass SOCKS, not just the trayicon's. If at some point we add another X11-using component, it'll get the same correct behavior automatically.