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.

[originally from svn r1239]
This commit is contained in:
Simon Tatham 2001-09-07 22:39:01 +00:00
Родитель 47e97ae032
Коммит f08de20a1e
8 изменённых файлов: 121 добавлений и 16 удалений

Просмотреть файл

@ -64,6 +64,7 @@ struct plug_function_table {
void sk_init(void); /* called once at program startup */ void sk_init(void); /* called once at program startup */
SockAddr sk_namelookup(char *host, char **canonicalname); SockAddr sk_namelookup(char *host, char **canonicalname);
void sk_getaddr(SockAddr addr, char *buf, int buflen);
void sk_addr_free(SockAddr addr); void sk_addr_free(SockAddr addr);
Socket sk_new(SockAddr addr, int port, int privport, int oobinline, Socket sk_new(SockAddr addr, int port, int privport, int oobinline,

Просмотреть файл

@ -352,7 +352,8 @@ char *do_select(SOCKET skt, int startup)
{ {
int events; int events;
if (startup) { 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 { } else {
events = 0; events = 0;
} }
@ -767,6 +768,8 @@ int main(int argc, char **argv)
if (!WSAEnumNetworkEvents(socket, NULL, &things)) { if (!WSAEnumNetworkEvents(socket, NULL, &things)) {
noise_ultralight(socket); noise_ultralight(socket);
noise_ultralight(things.lNetworkEvents); noise_ultralight(things.lNetworkEvents);
if (things.lNetworkEvents & FD_CONNECT)
connopen &= select_result(wp, (LPARAM) FD_CONNECT);
if (things.lNetworkEvents & FD_READ) if (things.lNetworkEvents & FD_READ)
connopen &= select_result(wp, (LPARAM) FD_READ); connopen &= select_result(wp, (LPARAM) FD_READ);
if (things.lNetworkEvents & FD_CLOSE) if (things.lNetworkEvents & FD_CLOSE)

19
raw.c
Просмотреть файл

@ -44,6 +44,11 @@ static int raw_receive(Plug plug, int urgent, char *data, int len)
return 1; return 1;
} }
static void raw_sent(Plug plug, int bufsize)
{
raw_bufsize = bufsize;
}
/* /*
* Called to set up the raw connection. * 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 = { static struct plug_function_table fn_table = {
raw_closing, raw_closing,
raw_receive raw_receive,
raw_sent
}, *fn_table_ptr = &fn_table; }, *fn_table_ptr = &fn_table;
SockAddr addr; SockAddr addr;
@ -65,6 +71,11 @@ static char *raw_init(char *host, int port, char **realhost)
/* /*
* Try to find host. * Try to find host.
*/ */
{
char buf[200];
sprintf(buf, "Looking up host \"%.170s\"", host);
logevent(buf);
}
addr = sk_namelookup(host, realhost); addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr))) if ((err = sk_addr_error(addr)))
return err; return err;
@ -75,6 +86,12 @@ static char *raw_init(char *host, int port, char **realhost)
/* /*
* Open socket. * 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); s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ((err = sk_socket_error(s))) if ((err = sk_socket_error(s)))
return err; return err;

Просмотреть файл

@ -73,6 +73,11 @@ static int rlogin_receive(Plug plug, int urgent, char *data, int len)
return 1; return 1;
} }
static void rlogin_sent(Plug plug, int bufsize)
{
rlogin_bufsize = bufsize;
}
/* /*
* Called to set up the rlogin connection. * 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 = { static struct plug_function_table fn_table = {
rlogin_closing, rlogin_closing,
rlogin_receive rlogin_receive,
rlogin_sent
}, *fn_table_ptr = &fn_table; }, *fn_table_ptr = &fn_table;
SockAddr addr; SockAddr addr;
@ -94,6 +100,11 @@ static char *rlogin_init(char *host, int port, char **realhost)
/* /*
* Try to find host. * Try to find host.
*/ */
{
char buf[200];
sprintf(buf, "Looking up host \"%.170s\"", host);
logevent(buf);
}
addr = sk_namelookup(host, realhost); addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr))) if ((err = sk_addr_error(addr)))
return err; return err;
@ -104,6 +115,12 @@ static char *rlogin_init(char *host, int port, char **realhost)
/* /*
* Open socket. * 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); s = sk_new(addr, port, 1, 0, &fn_table_ptr);
if ((err = sk_socket_error(s))) if ((err = sk_socket_error(s)))
return err; return err;

11
ssh.c
Просмотреть файл

@ -1686,6 +1686,11 @@ static char *connect_to_host(char *host, int port, char **realhost)
/* /*
* Try to find host. * Try to find host.
*/ */
{
char buf[200];
sprintf(buf, "Looking up host \"%.170s\"", host);
logevent(buf);
}
addr = sk_namelookup(host, realhost); addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr))) if ((err = sk_addr_error(addr)))
return err; return err;
@ -1697,6 +1702,12 @@ static char *connect_to_host(char *host, int port, char **realhost)
/* /*
* Open socket. * 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); s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ((err = sk_socket_error(s))) if ((err = sk_socket_error(s)))
return err; return err;

Просмотреть файл

@ -588,6 +588,11 @@ static int telnet_receive(Plug plug, int urgent, char *data, int len)
return 1; return 1;
} }
static void telnet_sent(Plug plug, int bufsize)
{
telnet_bufsize = bufsize;
}
/* /*
* Called to set up the Telnet connection. * 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 = { static struct plug_function_table fn_table = {
telnet_closing, telnet_closing,
telnet_receive telnet_receive,
telnet_sent
}, *fn_table_ptr = &fn_table; }, *fn_table_ptr = &fn_table;
SockAddr addr; SockAddr addr;
@ -609,6 +615,11 @@ static char *telnet_init(char *host, int port, char **realhost)
/* /*
* Try to find host. * Try to find host.
*/ */
{
char buf[200];
sprintf(buf, "Looking up host \"%.170s\"", host);
logevent(buf);
}
addr = sk_namelookup(host, realhost); addr = sk_namelookup(host, realhost);
if ((err = sk_addr_error(addr))) if ((err = sk_addr_error(addr)))
return err; return err;
@ -619,6 +630,12 @@ static char *telnet_init(char *host, int port, char **realhost)
/* /*
* Open socket. * 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); s = sk_new(addr, port, 0, 1, &fn_table_ptr);
if ((err = sk_socket_error(s))) if ((err = sk_socket_error(s)))
return err; return err;

Просмотреть файл

@ -706,7 +706,8 @@ char *do_select(SOCKET skt, int startup)
int msg, events; int msg, events;
if (startup) { if (startup) {
msg = WM_NETEVENT; 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 { } else {
msg = events = 0; msg = events = 0;
} }
@ -1666,6 +1667,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
pending_netevent = TRUE; pending_netevent = TRUE;
pend_netevent_wParam = wParam; pend_netevent_wParam = wParam;
pend_netevent_lParam = lParam; pend_netevent_lParam = lParam;
if (WSAGETSELECTEVENT(lParam) != FD_READ)
enact_pending_netevent();
time(&last_movement); time(&last_movement);
return 0; return 0;
case WM_SETFOCUS: case WM_SETFOCUS:

Просмотреть файл

@ -63,6 +63,7 @@ struct Socket_tag {
Plug plug; Plug plug;
void *private_ptr; void *private_ptr;
bufchain output_data; bufchain output_data;
int connected;
int writable; int writable;
int frozen; /* this causes readability notifications to be ignored */ int frozen; /* this causes readability notifications to be ignored */
int frozen_readable; /* this means we missed at least one readability int frozen_readable; /* this means we missed at least one readability
@ -338,6 +339,21 @@ SockAddr sk_namelookup(char *host, char **canonicalname)
return ret; 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) void sk_addr_free(SockAddr addr)
{ {
sfree(addr); sfree(addr);
@ -448,7 +464,8 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
ret->error = NULL; ret->error = NULL;
ret->plug = plug; ret->plug = plug;
bufchain_init(&ret->output_data); 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->sending_oob = 0;
ret->frozen = 0; ret->frozen = 0;
ret->frozen_readable = 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_addr.s_addr = htonl(addr->address);
a.sin_port = htons((short) port); 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 (( if ((
#ifdef IPV6 #ifdef IPV6
connect(s, ((addr->family == AF_INET6) ? connect(s, ((addr->family == AF_INET6) ?
@ -553,16 +579,22 @@ Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
#endif #endif
) == SOCKET_ERROR) { ) == SOCKET_ERROR) {
err = WSAGetLastError(); err = WSAGetLastError();
ret->error = winsock_error_string(err); /*
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
/* Set up a select mechanism. This could be an AsyncSelect on a * asynchronously.
* window, or an EventSelect on an event object. */ */
errstr = do_select(s, 1); if ( err != WSAEWOULDBLOCK ) {
if (errstr) { ret->error = winsock_error_string(err);
ret->error = errstr; return (Socket) ret;
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); add234(sktree, ret);
@ -825,6 +857,9 @@ int select_result(WPARAM wParam, LPARAM lParam)
noise_ultralight(lParam); noise_ultralight(lParam);
switch (WSAGETSELECTEVENT(lParam)) { switch (WSAGETSELECTEVENT(lParam)) {
case FD_CONNECT:
s->connected = s->writable = 1;
break;
case FD_READ: case FD_READ:
/* In the case the socket is still frozen, we don't even bother */ /* In the case the socket is still frozen, we don't even bother */
if (s->frozen) { if (s->frozen) {