Improve socket error handling so that a socket error isn't an
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 24 Jan 2001 10:11:18 +0000 (10:11 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Wed, 24 Jan 2001 10:11:18 +0000 (10:11 +0000)
automatic fatalbox(). Instead, the error is passed to the receiver
routine, which can decide just how fatal the problem really is.

git-svn-id: svn://svn.tartarus.org/sgt/putty@894 cda61777-01e9-0310-a592-d414129be87e

network.h
raw.c
rlogin.c
ssh.c
telnet.c
winnet.c
x11fwd.c

index 4608800..528e92a 100644 (file)
--- a/network.h
+++ b/network.h
@@ -8,10 +8,6 @@
  * send data without having to worry about blocking. The stuff
  * behind the abstraction takes care of selects and nonblocking
  * writes and all that sort of painful gubbins.
- * 
- * If urgent data comes in on a socket, the back end will read and
- * discard up to the urgent pointer, then read the urgent byte and
- * send _that_ to the receiver function with `urgent' set.
  */
 
 #ifndef PUTTY_NETWORK_H
 
 typedef struct Socket_tag *Socket;
 typedef struct SockAddr_tag *SockAddr;
+
+/*
+ * This is the function a client must register with each socket, to
+ * receive data coming in on that socket. The parameter `urgent'
+ * decides the meaning of `data' and `len':
+ * 
+ *  - urgent==0. `data' points to `len' bytes of perfectly ordinary
+ *    data.
+ * 
+ *  - urgent==1. `data' points to `len' bytes of data, which were
+ *    read from before an Urgent pointer.
+ * 
+ *  - urgent==2. `data' points to `len' bytes of data, the first of
+ *    which was the one at the Urgent mark.
+ * 
+ *  - urgent==3. An error has occurred on the socket. `data' points
+ *    to an error string, and `len' points to an error code.
+ */
 typedef int (*sk_receiver_t)(Socket s, int urgent, char *data, int len);
 
 void sk_init(void);                   /* called once at program startup */
diff --git a/raw.c b/raw.c
index 61a7d66..c354580 100644 (file)
--- a/raw.c
+++ b/raw.c
@@ -25,6 +25,11 @@ static void c_write (char *buf, int len) {
 }
 
 static int raw_receive (Socket s, int urgent, char *data, int len) {
+    if (urgent==3) {
+        /* A socket error has occurred. */
+        connection_fatal(data);
+        len = 0;
+    }
     if (!len) {
        /* Connection has closed. */
        sk_close(s);
index b3e9eac..c77f381 100644 (file)
--- a/rlogin.c
+++ b/rlogin.c
@@ -25,6 +25,11 @@ static void c_write (char *buf, int len) {
 }
 
 static int rlogin_receive (Socket s, int urgent, char *data, int len) {
+    if (urgent==3) {
+        /* A socket error has occurred. */
+        connection_fatal(data);
+        len = 0;
+    }
     if (!len) {
        /* Connection has closed. */
        sk_close(s);
diff --git a/ssh.c b/ssh.c
index ee320af..3845264 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -1148,6 +1148,11 @@ static void ssh_gotdata(unsigned char *data, int datalen)
 }
 
 static int ssh_receive(Socket skt, int urgent, char *data, int len) {
+    if (urgent==3) {
+        /* A socket error has occurred. */
+        connection_fatal(data);
+        len = 0;
+    }
     if (!len) {
        /* Connection has closed. */
        ssh_state = SSH_STATE_CLOSED;
index 6797912..f30902d 100644 (file)
--- a/telnet.c
+++ b/telnet.c
@@ -461,6 +461,11 @@ static void do_telnet_read (char *buf, int len) {
 }
 
 static int telnet_receive(Socket s, int urgent, char *data, int len) {
+    if (urgent==3) {
+        /* A socket error has occurred. */
+        connection_fatal(data);
+        len = 0;
+    }
     if (!len) {
        /* Connection has closed. */
        sk_close(s);
index 372845d..fb27616 100644 (file)
--- a/winnet.c
+++ b/winnet.c
@@ -569,7 +569,11 @@ int select_result(WPARAM wParam, LPARAM lParam) {
        return 1;                      /* boggle */
 
     if ((err = WSAGETSELECTERROR(lParam)) != 0) {
-       fatalbox(winsock_error_string(err));
+        /*
+         * An error has occurred on this socket. Pass it to the
+         * receiver function.
+         */
+        return s->receiver(s, 3, winsock_error_string(err), err);
     }
 
     noise_ultralight(lParam);
@@ -584,7 +588,7 @@ int select_result(WPARAM wParam, LPARAM lParam) {
            }
        }
        if (ret < 0) {
-           fatalbox(winsock_error_string(err));
+           return s->receiver(s, 3, winsock_error_string(err), err);
        } else {
             int type = s->in_oob ? 2 : 0;
             s->in_oob = FALSE;
index b4fecd9..7e99523 100644 (file)
--- a/x11fwd.c
+++ b/x11fwd.c
@@ -106,6 +106,14 @@ static int x11_verify(char *proto, unsigned char *data, int dlen) {
 static int x11_receive (Socket s, int urgent, char *data, int len) {
     struct X11Private *pr = (struct X11Private *)sk_get_private_ptr(s);
 
+    if (urgent==3) {
+        /*
+         * A socket error has occurred. We have no way to
+         * communicate this down the forwarded connection, so we'll
+         * just treat it like a proper close.
+         */
+        len = 0;
+    }
     if (!len) {
        /* Connection has closed. */
         sshfwd_close(pr->c);