Robert de Bath's asynchronous-connect patch. Helps a lot in port
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 7 Sep 2001 22:39:01 +0000 (22:39 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 7 Sep 2001 22:39:01 +0000 (22:39 +0000)
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
plink.c
raw.c
rlogin.c
ssh.c
telnet.c
window.c
winnet.c

index 4b7808a..4300fb2 100644 (file)
--- 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 461035a..77724a5 100644 (file)
--- 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 4bed83c..4b17051 100644 (file)
--- 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;
index a2199cf..525d48d 100644 (file)
--- 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 845b01c..c03cd6d 100644 (file)
--- 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;
index 40d032c..f4e04d3 100644 (file)
--- 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;
index f3db0cd..378634f 100644 (file)
--- 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:
index 1a80a80..c5e9eb7 100644 (file)
--- 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) {