X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=sshshare.c;h=82c4bd31ed8867755fcad1b467356450c3df5410;hb=510f49e405e71ba5c97875e7a019364e1ef5fac9;hp=dcf805d6bf7d31e61c3beee9b8ebeb9d4983c7a9;hpb=14892997d635aaf63d8a9c7630b9bf15389bef04;p=PuTTY.git diff --git a/sshshare.c b/sshshare.c index dcf805d6..82c4bd31 100644 --- a/sshshare.c +++ b/sshshare.c @@ -133,6 +133,7 @@ #include #include #include +#include #include "putty.h" #include "tree234.h" @@ -914,8 +915,25 @@ static int share_closing(Plug plug, const char *error_msg, int error_code, int calling_back) { struct ssh_sharing_connstate *cs = (struct ssh_sharing_connstate *)plug; - if (error_msg) - ssh_sharing_logf(cs->parent->ssh, cs->id, "%s", error_msg); + + if (error_msg) { +#ifdef BROKEN_PIPE_ERROR_CODE + /* + * Most of the time, we log what went wrong when a downstream + * disappears with a socket error. One exception, though, is + * receiving EPIPE when we haven't received a protocol version + * string from the downstream, because that can happen as a result + * of plink -shareexists (opening the connection and instantly + * closing it again without bothering to read our version string). + * So that one case is not treated as a log-worthy error. + */ + if (error_code == BROKEN_PIPE_ERROR_CODE && !cs->got_verstring) + /* do nothing */; + else +#endif + ssh_sharing_logf(cs->parent->ssh, cs->id, + "Socket error: %s", error_msg); + } share_begin_cleanup(cs); return 1; } @@ -2027,6 +2045,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