mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-07-02 03:52:49 -05:00
New Plink operating mode: 'plink -shareexists'.
A Plink invocation of the form 'plink -shareexists <session>' tests for a currently live connection-sharing upstream for the session in question. <session> can be any syntax you'd use with Plink to make the actual connection (a host/port number, a bare saved session name, -load, whatever). I envisage this being useful for things like adaptive proxying - e.g. if you want to connect to host A which you can't route to directly, and you might already have a connection to either of hosts B or C which are viable proxies, then you could write a proxy shell script which checks whether you already have an upstream for B or C and goes via whichever one is currently active. Testing for the upstream's existence has to be done by actually connecting to its socket, because on Unix the mere existence of a Unix-domain socket file doesn't guarantee that there's a process listening to it. So we make a test connection, and then immediately disconnect; hence, that shows up in the upstream's event log.
This commit is contained in:
49
sshshare.c
49
sshshare.c
@ -2027,6 +2027,55 @@ char *ssh_share_sockname(const char *host, int port, Conf *conf)
|
||||
return sockname;
|
||||
}
|
||||
|
||||
static void nullplug_socket_log(Plug plug, int type, SockAddr addr, int port,
|
||||
const char *error_msg, int error_code) {}
|
||||
static int nullplug_closing(Plug plug, const char *error_msg, int error_code,
|
||||
int calling_back) { return 0; }
|
||||
static int nullplug_receive(Plug plug, int urgent, char *data,
|
||||
int len) { return 0; }
|
||||
static void nullplug_sent(Plug plug, int bufsize) {}
|
||||
|
||||
int ssh_share_test_for_upstream(const char *host, int port, Conf *conf)
|
||||
{
|
||||
static const struct plug_function_table fn_table = {
|
||||
nullplug_socket_log,
|
||||
nullplug_closing,
|
||||
nullplug_receive,
|
||||
nullplug_sent,
|
||||
NULL
|
||||
};
|
||||
struct nullplug {
|
||||
const struct plug_function_table *fn;
|
||||
} np;
|
||||
|
||||
char *sockname, *logtext, *ds_err, *us_err;
|
||||
int result;
|
||||
Socket sock;
|
||||
|
||||
np.fn = &fn_table;
|
||||
|
||||
sockname = ssh_share_sockname(host, port, conf);
|
||||
|
||||
sock = NULL;
|
||||
logtext = ds_err = us_err = NULL;
|
||||
result = platform_ssh_share(sockname, conf, (Plug)&np, (Plug)NULL, &sock,
|
||||
&logtext, &ds_err, &us_err, FALSE, TRUE);
|
||||
|
||||
sfree(logtext);
|
||||
sfree(ds_err);
|
||||
sfree(us_err);
|
||||
sfree(sockname);
|
||||
|
||||
if (result == SHARE_NONE) {
|
||||
assert(sock == NULL);
|
||||
return FALSE;
|
||||
} else {
|
||||
assert(result == SHARE_DOWNSTREAM);
|
||||
sk_close(sock);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Init function for connection sharing. We either open a listening
|
||||
* socket and become an upstream, or connect to an existing one and
|
||||
|
Reference in New Issue
Block a user