xpra icon
Bug tracker and wiki

Opened 4 years ago

Closed 7 days ago

#1022 closed enhancement (fixed)

Xpra Client in Listen Mode

Reported by: adarrab Owned by: adarrab
Priority: minor Milestone: 3.0
Component: core Version: trunk
Keywords: Listen Mode Cc:

Description (last modified by Antoine Martin)

It would be nice to have those two additional options (--listen, --client) e.g.

Xpra_cmd.exe attach [ssh/tcp]: EMPTY --listen=[IP:PORT] (Waits for server ready msg, with optional timeout. IP is provided in case a machine has more than 1 active address, otherwise not needed)

xpra --start :XX --start-child=CMD  --client=IP:PORT


Once server is initiated successfully, it sends a triggering tcp msg to the client containing USER@SERVER :XX to be used by the client to initiate ssh/tcp connection.
One useful option with client listen mode is continues listing, so that it exec clients once server msg received and keeps listing for more servers as they become ready, instead of launching clients manually for each application

  • The main driver for this is to mimic the Xserver behavior where it listens and accepts connections from remote hosts
  • But another benefit of this listen option is that you can have servers that are NATed, unreachable from regular clients, since they will be the ones initiating the connection.

Thank you,

Attachments (2)

client-listen.patch (7.1 KB) - added by Antoine Martin 10 days ago.
add listen mode for client
client-listen-v2.patch (12.7 KB) - added by Antoine Martin 8 days ago.
working patch

Download all attachments as: .zip

Change History (17)

comment:1 Changed 4 years ago by Antoine Martin

Description: modified (diff)
Milestone: 0.160.17
Owner: changed from Antoine Martin to adarrab
Type: taskenhancement

As per this original mailing list thread: Xpra Client in Listen Mode Enquiry

I think it would be better, safer and more useful to simply reverse the connection so that the server connects to the client: no need for passing the user+host to connect to using a new magic message to trigger yet another connection. (with the inherent security risks every time - and new connections cannot traverse NAT back to the server).

The "listen" mode should probably be a new subcommand, rather than overloading "attach", ie:

xpra listen tcp:host:port

I really don't see much point at all in the listen via SSH option: if you can SSH to the client, you might as well start the client command via SSH, which is also much safer.

Pointers:

  • the Protocol is quite well abstracted and is used by both client and server, it does not care about which end initiates the connection
  • the client (and its subclasses / superclasses) will need a bit of work to be able to start:
    • without timing out
    • create a tray icon (or not?) and handle menus that are not meant to be used yet
    • create the socket in listen mode (same code as the server) - when the connection is received, it just goes through the normal startup sequence: send hello and everything else should fall into place
  • the Server Base Class (and sub/super classes) will just need a new bit of code to create a new TCP connection and add it to its "sources" list. This should be available via "xpra control" and the dbus server so we can initiate new ones after the server is started if necessary. Think about timeouts, and retries..
  • authentication / encryption: the client should authenticate the server if the password option is used - and maybe we should be doing this anyway in all cases? (which we sort of do when you have encryption)

@adarrab: if you can take a look at the comments above and maybe even play with the code a little bit, I should be able to take a look at this for the next release

comment:2 Changed 4 years ago by adarrab

Sorry for the confusion, client doesn't listen through SSH, the [SSH/TCP] in the command line is to instruct the client to use [SSH/TCP] connection to the server (like attach [ssh/tcp]:....), once the server is ready. Listening is going to be always over tcp, since clients mostly do not run ssh server.

comment:3 Changed 4 years ago by Antoine Martin

Milestone: 0.170.18

comment:4 Changed 3 years ago by Antoine Martin

May be related / useful for #983 since vsock connections go from guest to host only. (AFAICT)

Edit: that was incorrect.

Last edited 3 years ago by Antoine Martin (previous) (diff)

comment:5 Changed 3 years ago by Antoine Martin

Milestone: 0.181.0

Milestone renamed

comment:6 Changed 3 years ago by Antoine Martin

Milestone: 1.0future

I don't have time for this.

comment:7 Changed 22 months ago by Antoine Martin

Milestone: future2.3
Owner: changed from adarrab to Antoine Martin
Status: newassigned

Should be easy enough to implement.

There are security implications.. I don't think we want to resurrect #1660

Last edited 22 months ago by Antoine Martin (previous) (diff)

comment:8 Changed 21 months ago by Antoine Martin

Milestone: 2.3future

Actually not that easy to implement, and no real need for it.
Re-scheduling.

comment:9 Changed 8 months ago by Antoine Martin

See also #2125, #1590.

Last edited 7 months ago by Antoine Martin (previous) (diff)

Changed 10 days ago by Antoine Martin

Attachment: client-listen.patch added

add listen mode for client

comment:10 Changed 10 days ago by Antoine Martin

Helped by the refactoring from ticket:2125#comment:11, the patch above makes it possible for the client to wait for a connection on sockets specified using the usual --bind-tcp syntax.

comment:11 Changed 10 days ago by Antoine Martin

See #2406 for generic client bind options.

Changed 8 days ago by Antoine Martin

Attachment: client-listen-v2.patch added

working patch

comment:12 Changed 8 days ago by Antoine Martin

Milestone: future3.0

The patch above works as long as one uses "socat" to join the server and client socket together:

  • server:
    xpra start --start="xterm" --bind-tcp=0.0.0.0:10000
    
  • client:
    xpra listen --bind-tcp=0.0.0.0:10001
    
  • socat:
    socat TCP:localhost:10000 TCP:localhost:10001
    

I may still merge this just as a POC.

comment:13 Changed 8 days ago by Antoine Martin

Owner: changed from Antoine Martin to adarrab
Status: assignednew

Merged in r23767.
As of r23770, the client can also be told where to connect, instead of just expecting a server connection:

xpra listen --bind-tcp=0.0.0.0:10001
echo tcp://192.168.1.10:10000 | socat - TCP:localhost:10001

The client will print:

closing tcp socket 0.0.0.0:10001
connecting to tcp://192.168.1.10:10000

Then proceeds as if it had been started with attach tcp://192.168.1.10:10000.

Caveats:

  • only the first connection will be used, after that the sockets are closed.

(so if the connection fails at that point, the client will just exit)

  • the client doesn't do any socket wrapping, so tcp sockets can't be upgraded to ssl, ssh or ws(s).

Will follow up in #2412

@adarrab: does that work for you?

comment:14 in reply to:  13 Changed 8 days ago by adarrab

@adarrab: does that work for you?

First of all, many thanks for putting the time to implement this feature, really appreciated!

The very basic scenario does work, but you would need a port for each client, which makes it annoying in situations where firewall is restricted to limited number of opened ports (which is the case in many places). I was hoping to have the client in listening mode acts like a proxy server where it listens on a single port, and upon receiving a connection from xpra servers, it spawns clients and forward traffic to them.

At least this is what I ended up doing couple of years ago: a listener service on a specific port which spawns xpra clients (ssh connection & key authentication) to the ready server (once server is ready it sends a message similar to your approach). The only downfall to this is that the client takes up to 5 seconds to initialize and establish the ssh connection, despite disabling many of the features like speaker, microphone, tray ...etc. Your approach with tcp binding (when the client is ready in listening mode) it shows the received application almost instantaneous upon receiving the signal from the server.

Last edited 7 days ago by Antoine Martin (previous) (diff)

comment:15 Changed 7 days ago by Antoine Martin

Resolution: fixed
Status: newclosed

I was hoping to have the client in listening mode acts like a proxy server where it listens on a single port, and upon receiving a connection from xpra servers, it spawns clients and forward traffic to them.

You should be able to achieve this with minimal code by spawning enough clients in advance in listen mode on a unix domain socket, then have a very simple tcp listener that dispatches to them.
This could be helped by #2406: by creating your unix domain sockets in a pre-defined location, the dispatcher could just use xpra info on them to know which ones are still free. (and potentially pre-spawn more as needed)

Note: See TracTickets for help on using tickets.