mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-11-04 08:34:12 +00:00
Three TCP connections carry WebRTC signalling to hbbs in the clear: the controller's punch connection, which carries the offer up and the answer and both sides' ICE candidates through it, and on the controlled side the short-lived connection that returns the answer and the one that trickles its candidates. Candidates are every interface address of both machines, and the controller is the side most often on a network it does not trust. `secure_tcp` is fail-open by design: a server that answers the first message with anything but a key exchange, or with nothing, leaves the stream in the clear and the call returns Ok, which the paths from before such servers rely on. That is not a channel WebRTC signalling may go out on. So the four legs use `secure_tcp_required`: Ok only once the server's key exchange has encrypted the stream, an error otherwise. WebSocket is treated as `secure_tcp` treats it, as a transport encrypted already. On the controller an error drops the offer, closes its peer connection through the guard and reconnects, then punches without WebRTC on the fresh socket, with the legacy condition applied to it as before; the failed exchange may have consumed a message on the old one. On the controlled side an error abandons that WebRTC attempt: the answer is not sent, or the candidates are not, and the controller falls back to its other transports. A relay response carrying an answer, which the symmetric-NAT and forced-relay branches send on a connection of their own, keeps the relay and loses only the answer: the response goes without it, on a fresh socket. Degrade to no WebRTC, never to WebRTC signalling in the clear. `secure_tcp` itself is unchanged; the exchange moves into `key_exchange`, which reports whether it happened. A punch without an offer is unchanged: the legacy secure condition takes this socket straight to the punch as before, and every other punch waits for the UDP NAT test as before. The exchange does not replace that wait, it spends part of the same budget, which now runs from before it: what is left is waited out, and a probe that has already answered is taken at once. Tests run a loopback stand-in for hbbs: a server that answers with another message, or closes, is refused where `secure_tcp` would carry on in the clear; a completed exchange is accepted and the stub decodes the reply with its ephemeral key. Claude-Session: https://claude.ai/code/session_019aokqJuhjvB3kijXtAg5Ns Co-authored-by: Claude Opus 5 <noreply@anthropic.com>