fix(cloud): stop Xvnc black-listing viewers of additional displays

Merged
AU
10d ago
+508-368

Restored and newly opened Cloud displays (2 and up) sat on "Failed to connect to server" or "Cloud session unavailable", or loaded slowly. Each display's Xvnc was answering every viewer with Too many security failures.

Xvnc black-lists a peer after five unauthenticated connections, for a timeout that doubles on each repeat. Every viewer of an additional display reaches Xvnc through websockify on 127.0.0.1, so one lockout blocks the whole display. The guest helper's 30s health check read the RFB greeting and disconnected, which is an unauthenticated connection, so displays locked themselves out within minutes. Restore bursts and page reloads added more marks. Display 1 is started by the image and was not probed, which is why it kept working. Verified on a live VM: displays 2 and 4 returned the rejection while display 1 greeted normally, and the panes' own websockets opened then closed with 1000 Target closed.

  • Additional displays start Xvnc with -UseBlacklist=0. With SecurityTypes None behind the private network the black list protects nothing, and Xvnc refuses runtime changes (vncconfig -set fails), so this applies to new displays. Displays already locked recover on the first connection Xvnc lets through after the timeout.
  • The health check now completes the None handshake, which clears marks instead of adding them. A rejection still counts as a live server, so the session is never restarted for it.
  • Process recovery matched with pgrep patterns that its regex dialect rejected (pgrep: regex error in the service log), so nothing was ever adopted. It now matches exact argv from /proc.
  • Each helper request runs in a plain shell. The login shell cost about 0.7s per call; only the long-lived service is still started with the login environment, so new desktops keep agent routing, BROWSER and CA certificates (verified in the service's environ).

Verification: python3 -m unittest tests.test_cloud_display_catalog 21/21; the new tests fail against main's helper (1 failure, 3 errors). swift test --filter CloudGuestDisplayScriptTests passes. Live: a display created through the app's exact command runs with -UseBlacklist=0 and still greets after 10 aborted handshakes; a throwaway Xvnc with the flag behaved the same.

Not in this PR: concurrent websocket routes through the browser proxy are serialized (about 0.2 to 0.5s each), and browser-proxy processes outlive their parent app despite --exit-with-parent. Each create still pays one Cloud exec round trip (1.3 to 2.9s); moving creation onto the private-network carrier is the next latency step.

Changelog

Fixed: Cloud displays beyond the first no longer refuse connections after restore or repeated opens.

unregistered

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Fixes Cloud displays beyond the first (display 2 and up) rejecting viewers with "Too many security failures" after restore or repeated opens. Xvnc black-lists a peer after five unauthenticated connections, and the guest helper's 30s health check read the RFB greeting and disconnected, which counted as unauthenticated connections until the display locked itself out.

  • Additional displays start Xvnc with -UseBlacklist=0; Xvnc rejects runtime changes, so this applies only to newly created displays, while already locked ones recover when the timeout lapses.
  • The health check now completes the None authentication handshake, clearing black marks instead of adding them.
  • Process recovery now matches exact argv from /proc, replacing pgrep patterns its regex dialect rejected, so display processes are actually adopted after service restarts.
  • Helper requests now run in a plain shell, saving about 0.7s per call; only the long-lived service is started with the login environment.

Summary by CodeRabbit

  • Bug Fixes
    • Improved cloud display readiness checks across supported RFB server responses, reducing the chance that a live display is reported as unavailable.
    • Improved display recovery so it is less likely to adopt processes belonging to another display.
    • Updated service startup to use the login environment, improving compatibility with environment-dependent services.
    • Adjusted newly launched Xvnc instances to avoid blacklist-related startup issues.