From 3ad9d396e3e57477b4da4b20665ca33edd5d7f67 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 7 Sep 2001 22:39:01 +0000 Subject: [PATCH] Robert de Bath's asynchronous-connect patch. Helps a lot in port forwarding; improves Event Log; and causes the PuTTY window to appear earlier in the setup process. git-svn-id: svn://svn.tartarus.org/sgt/putty@1239 cda61777-01e9-0310-a592-d414129be87e --- network.h | 1 + plink.c | 5 ++++- raw.c | 19 ++++++++++++++++++- rlogin.c | 19 ++++++++++++++++++- ssh.c | 11 +++++++++++ telnet.c | 19 ++++++++++++++++++- window.c | 6 +++++- winnet.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++----------- 8 files changed, 121 insertions(+), 16 deletions(-) diff --git a/network.h b/network.h index 4b7808a3..4300fb2e 100644 --- a/network.h +++ b/network.h @@ -64,6 +64,7 @@ struct plug_function_table { void sk_init(void); /* called once at program startup */ SockAddr sk_namelookup(char *host, char **canonicalname); +void sk_getaddr(SockAddr addr, char *buf, int buflen); void sk_addr_free(SockAddr addr); Socket sk_new(SockAddr addr, int port, int privport, int oobinline, diff --git a/plink.c b/plink.c index 461035a2..77724a5b 100644 --- a/plink.c +++ b/plink.c @@ -352,7 +352,8 @@ char *do_select(SOCKET skt, int startup) { int events; if (startup) { - events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE | FD_ACCEPT; + events = (FD_CONNECT | FD_READ | FD_WRITE | + FD_OOB | FD_CLOSE | FD_ACCEPT); } else { events = 0; } @@ -767,6 +768,8 @@ int main(int argc, char **argv) if (!WSAEnumNetworkEvents(socket, NULL, &things)) { noise_ultralight(socket); noise_ultralight(things.lNetworkEvents); + if (things.lNetworkEvents & FD_CONNECT) + connopen &= select_result(wp, (LPARAM) FD_CONNECT); if (things.lNetworkEvents & FD_READ) connopen &= select_result(wp, (LPARAM) FD_READ); if (things.lNetworkEvents & FD_CLOSE) diff --git a/raw.c b/raw.c index 4bed83cd..4b170511 100644 --- a/raw.c +++ b/raw.c @@ -44,6 +44,11 @@ static int raw_receive(Plug plug, int urgent, char *data, int len) return 1; } +static void raw_sent(Plug plug, int bufsize) +{ + raw_bufsize = bufsize; +} + /* * Called to set up the raw connection. * @@ -56,7 +61,8 @@ static char *raw_init(char *host, int port, char **realhost) { static struct plug_function_table fn_table = { raw_closing, - raw_receive + raw_receive, + raw_sent }, *fn_table_ptr = &fn_table; SockAddr addr; @@ -65,6 +71,11 @@ static char *raw_init(char *host, int port, char **realhost) /* * Try to find host. */ + { + char buf[200]; + sprintf(buf, "Looking up host \"%.170s\"", host); + logevent(buf); + } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) return err; @@ -75,6 +86,12 @@ static char *raw_init(char *host, int port, char **realhost) /* * Open socket. */ + { + char buf[200], addrbuf[100]; + sk_getaddr(addr, addrbuf, 100); + sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); + logevent(buf); + } s = sk_new(addr, port, 0, 1, &fn_table_ptr); if ((err = sk_socket_error(s))) return err; diff --git a/rlogin.c b/rlogin.c index a2199cf5..525d48d0 100644 --- a/rlogin.c +++ b/rlogin.c @@ -73,6 +73,11 @@ static int rlogin_receive(Plug plug, int urgent, char *data, int len) return 1; } +static void rlogin_sent(Plug plug, int bufsize) +{ + rlogin_bufsize = bufsize; +} + /* * Called to set up the rlogin connection. * @@ -85,7 +90,8 @@ static char *rlogin_init(char *host, int port, char **realhost) { static struct plug_function_table fn_table = { rlogin_closing, - rlogin_receive + rlogin_receive, + rlogin_sent }, *fn_table_ptr = &fn_table; SockAddr addr; @@ -94,6 +100,11 @@ static char *rlogin_init(char *host, int port, char **realhost) /* * Try to find host. */ + { + char buf[200]; + sprintf(buf, "Looking up host \"%.170s\"", host); + logevent(buf); + } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) return err; @@ -104,6 +115,12 @@ static char *rlogin_init(char *host, int port, char **realhost) /* * Open socket. */ + { + char buf[200], addrbuf[100]; + sk_getaddr(addr, addrbuf, 100); + sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); + logevent(buf); + } s = sk_new(addr, port, 1, 0, &fn_table_ptr); if ((err = sk_socket_error(s))) return err; diff --git a/ssh.c b/ssh.c index 845b01cc..c03cd6db 100644 --- a/ssh.c +++ b/ssh.c @@ -1686,6 +1686,11 @@ static char *connect_to_host(char *host, int port, char **realhost) /* * Try to find host. */ + { + char buf[200]; + sprintf(buf, "Looking up host \"%.170s\"", host); + logevent(buf); + } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) return err; @@ -1697,6 +1702,12 @@ static char *connect_to_host(char *host, int port, char **realhost) /* * Open socket. */ + { + char buf[200], addrbuf[100]; + sk_getaddr(addr, addrbuf, 100); + sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); + logevent(buf); + } s = sk_new(addr, port, 0, 1, &fn_table_ptr); if ((err = sk_socket_error(s))) return err; diff --git a/telnet.c b/telnet.c index 40d032cc..f4e04d37 100644 --- a/telnet.c +++ b/telnet.c @@ -588,6 +588,11 @@ static int telnet_receive(Plug plug, int urgent, char *data, int len) return 1; } +static void telnet_sent(Plug plug, int bufsize) +{ + telnet_bufsize = bufsize; +} + /* * Called to set up the Telnet connection. * @@ -600,7 +605,8 @@ static char *telnet_init(char *host, int port, char **realhost) { static struct plug_function_table fn_table = { telnet_closing, - telnet_receive + telnet_receive, + telnet_sent }, *fn_table_ptr = &fn_table; SockAddr addr; @@ -609,6 +615,11 @@ static char *telnet_init(char *host, int port, char **realhost) /* * Try to find host. */ + { + char buf[200]; + sprintf(buf, "Looking up host \"%.170s\"", host); + logevent(buf); + } addr = sk_namelookup(host, realhost); if ((err = sk_addr_error(addr))) return err; @@ -619,6 +630,12 @@ static char *telnet_init(char *host, int port, char **realhost) /* * Open socket. */ + { + char buf[200], addrbuf[100]; + sk_getaddr(addr, addrbuf, 100); + sprintf(buf, "Connecting to %.100s port %d", addrbuf, port); + logevent(buf); + } s = sk_new(addr, port, 0, 1, &fn_table_ptr); if ((err = sk_socket_error(s))) return err; diff --git a/window.c b/window.c index f3db0cd3..378634f9 100644 --- a/window.c +++ b/window.c @@ -706,7 +706,8 @@ char *do_select(SOCKET skt, int startup) int msg, events; if (startup) { msg = WM_NETEVENT; - events = FD_READ | FD_WRITE | FD_OOB | FD_CLOSE | FD_ACCEPT; + events = (FD_CONNECT | FD_READ | FD_WRITE | + FD_OOB | FD_CLOSE | FD_ACCEPT); } else { msg = events = 0; } @@ -1666,6 +1667,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message, pending_netevent = TRUE; pend_netevent_wParam = wParam; pend_netevent_lParam = lParam; + if (WSAGETSELECTEVENT(lParam) != FD_READ) + enact_pending_netevent(); + time(&last_movement); return 0; case WM_SETFOCUS: diff --git a/winnet.c b/winnet.c index 1a80a80c..c5e9eb7a 100644 --- a/winnet.c +++ b/winnet.c @@ -63,6 +63,7 @@ struct Socket_tag { Plug plug; void *private_ptr; bufchain output_data; + int connected; int writable; int frozen; /* this causes readability notifications to be ignored */ int frozen_readable; /* this means we missed at least one readability @@ -338,6 +339,21 @@ SockAddr sk_namelookup(char *host, char **canonicalname) return ret; } +void sk_getaddr(SockAddr addr, char *buf, int buflen) +{ +#ifdef IPV6 + if (addr->family == AF_INET) { +#endif + struct in_addr a; + a.s_addr = htonl(addr->address); + strncpy(buf, inet_ntoa(a), buflen); +#ifdef IPV6 + } else { + FIXME; /* I don't know how to get a text form of an IPv6 address. */ + } +#endif +} + void sk_addr_free(SockAddr addr) { sfree(addr); @@ -448,7 +464,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, ret->error = NULL; ret->plug = plug; bufchain_init(&ret->output_data); - ret->writable = 1; /* to start with */ + ret->connected = 0; /* to start with */ + ret->writable = 0; /* to start with */ ret->sending_oob = 0; ret->frozen = 0; ret->frozen_readable = 0; @@ -543,6 +560,15 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, a.sin_addr.s_addr = htonl(addr->address); a.sin_port = htons((short) port); } + + /* Set up a select mechanism. This could be an AsyncSelect on a + * window, or an EventSelect on an event object. */ + errstr = do_select(s, 1); + if (errstr) { + ret->error = errstr; + return (Socket) ret; + } + if (( #ifdef IPV6 connect(s, ((addr->family == AF_INET6) ? @@ -553,16 +579,22 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline, #endif ) == SOCKET_ERROR) { err = WSAGetLastError(); - ret->error = winsock_error_string(err); - return (Socket) ret; - } - - /* Set up a select mechanism. This could be an AsyncSelect on a - * window, or an EventSelect on an event object. */ - errstr = do_select(s, 1); - if (errstr) { - ret->error = errstr; - return (Socket) ret; + /* + * We expect a potential EWOULDBLOCK here, because the + * chances are the front end has done a select for + * FD_CONNECT, so that connect() will complete + * asynchronously. + */ + if ( err != WSAEWOULDBLOCK ) { + ret->error = winsock_error_string(err); + return (Socket) ret; + } + } else { + /* + * If we _don't_ get EWOULDBLOCK, the connect has completed + * and we should set the socket as writable. + */ + ret->writable = 1; } add234(sktree, ret); @@ -825,6 +857,9 @@ int select_result(WPARAM wParam, LPARAM lParam) noise_ultralight(lParam); switch (WSAGETSELECTEVENT(lParam)) { + case FD_CONNECT: + s->connected = s->writable = 1; + break; case FD_READ: /* In the case the socket is still frozen, we don't even bother */ if (s->frozen) { -- 2.11.0