Yet another attempt at OOB handling in the network abstraction. This
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 1 Feb 2001 14:11:04 +0000 (14:11 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 1 Feb 2001 14:11:04 +0000 (14:11 +0000)
version allows you to specify, per socket, which sockets receive OOB
data in-line (so that you know what was before the mark and what was
after) and which receive it out of line (so it's really a one-byte
out-of-band facility rather than discard-to-mark). This reflects the
fact that rlogin appears to make more sense in the latter mode, and
telnet in the former. This patch makes rlogin work right for me.

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

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

index 528e92a..ba1e1df 100644 (file)
--- a/network.h
+++ b/network.h
@@ -40,7 +40,8 @@ void sk_init(void);                  /* called once at program startup */
 SockAddr sk_namelookup(char *host, char **canonicalname);
 void sk_addr_free(SockAddr addr);
 
-Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver);
+Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
+              sk_receiver_t receiver);
 void sk_close(Socket s);
 void sk_write(Socket s, char *buf, int len);
 void sk_write_oob(Socket s, char *buf, int len);
diff --git a/raw.c b/raw.c
index 9cbb606..e3d5c06 100644 (file)
--- a/raw.c
+++ b/raw.c
@@ -66,7 +66,7 @@ static char *raw_init (char *host, int port, char **realhost) {
     /*
      * Open socket.
      */
-    s = sk_new(addr, port, 0, raw_receive);
+    s = sk_new(addr, port, 0, 1, raw_receive);
     if ( (err = sk_socket_error(s)) )
        return err;
 
index e20b9e6..8a7b1fa 100644 (file)
--- a/rlogin.c
+++ b/rlogin.c
@@ -92,7 +92,7 @@ static char *rlogin_init (char *host, int port, char **realhost) {
     /*
      * Open socket.
      */
-    s = sk_new(addr, port, 1, rlogin_receive);
+    s = sk_new(addr, port, 1, 0, rlogin_receive);
     if ( (err = sk_socket_error(s)) )
        return err;
 
diff --git a/ssh.c b/ssh.c
index 5ad1ea4..5a7dcf2 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -1219,7 +1219,7 @@ static char *connect_to_host(char *host, int port, char **realhost)
     /*
      * Open socket.
      */
-    s = sk_new(addr, port, 0, ssh_receive);
+    s = sk_new(addr, port, 0, 1, ssh_receive);
     if ( (err = sk_socket_error(s)) )
        return err;
 
index e9db210..bf42ed2 100644 (file)
--- a/telnet.c
+++ b/telnet.c
@@ -507,7 +507,7 @@ static char *telnet_init (char *host, int port, char **realhost) {
     /*
      * Open socket.
      */
-    s = sk_new(addr, port, 0, telnet_receive);
+    s = sk_new(addr, port, 0, 1, telnet_receive);
     if ( (err = sk_socket_error(s)) )
        return err;
 
index cc0b080..f15b136 100644 (file)
--- a/winnet.c
+++ b/winnet.c
@@ -63,6 +63,7 @@ struct Socket_tag {
     struct buffer *head, *tail;
     int writable;
     int sending_oob;
+    int oobinline;
 };
 
 struct SockAddr_tag {
@@ -288,7 +289,8 @@ void sk_addr_free(SockAddr addr) {
     sfree(addr);
 }
 
-Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver) {
+Socket sk_new(SockAddr addr, int port, int privport, int oobinline,
+              sk_receiver_t receiver) {
     SOCKET s;
 #ifdef IPV6
     SOCKADDR_IN6 a6;
@@ -321,7 +323,9 @@ Socket sk_new(SockAddr addr, int port, int privport, sk_receiver_t receiver) {
         ret->error = winsock_error_string(err);
        return ret;
     }
-    {
+
+    ret->oobinline = oobinline;
+    if (oobinline) {
        BOOL b = TRUE;
        setsockopt (s, SOL_SOCKET, SO_OOBINLINE, (void *)&b, sizeof(b));
     }
@@ -583,13 +587,27 @@ int select_result(WPARAM wParam, LPARAM lParam) {
 
     switch (WSAGETSELECTEVENT(lParam)) {
       case FD_READ:
-        atmark = 1;
-        /* Some WinSock wrappers don't support this call, so we
-         * deliberately don't check the return value. If the call
-         * fails and does nothing, we will get back atmark==1,
-         * which is good enough to keep going at least. */
-        ioctlsocket(s->s, SIOCATMARK, &atmark);
+        /*
+         * We have received data on the socket. For an oobinline
+         * socket, this might be data _before_ an urgent pointer,
+         * in which case we send it to the back end with type==1
+         * (data prior to urgent).
+         */
+        if (s->oobinline) {
+            atmark = 1;
+            ioctlsocket(s->s, SIOCATMARK, &atmark);
+            /*
+             * Avoid checking the return value from ioctlsocket(),
+             * on the grounds that some WinSock wrappers don't
+             * support it. If it does nothing, we get atmark==1,
+             * which is equivalent to `no OOB pending', so the
+             * effect will be to non-OOB-ify any OOB data.
+             */
+        } else
+            atmark = 1;
+
        ret = recv(s->s, buf, sizeof(buf), 0);
+        noise_ultralight(ret);
        if (ret < 0) {
            err = WSAGetLastError();
            if (err == WSAEWOULDBLOCK) {
@@ -599,19 +617,16 @@ int select_result(WPARAM wParam, LPARAM lParam) {
        if (ret < 0) {
            return s->receiver(s, 3, winsock_error_string(err), err);
        } else {
-            int type = 0;
-           if (atmark==0) {
-               ioctlsocket(s->s, SIOCATMARK, &atmark);
-               if(atmark) type = 2; else type = 1;
-           }
-           return s->receiver(s, type, buf, ret);
+           return s->receiver(s, atmark ? 0 : 1, buf, ret);
        }
        break;
       case FD_OOB:
-       /*
-        * Read all data up to the OOB marker, and send it to the
-        * receiver with urgent==1 (OOB pending).
-        */
+        /*
+         * This will only happen on a non-oobinline socket. It
+         * indicates that we can immediately perform an OOB read
+         * and get back OOB data, which we will send to the back
+         * end with type==2 (urgent data).
+         */
         ret = recv(s->s, buf, sizeof(buf), MSG_OOB);
         noise_ultralight(ret);
         if (ret <= 0) {
index 7e99523..d0a1f99 100644 (file)
--- a/x11fwd.c
+++ b/x11fwd.c
@@ -163,7 +163,7 @@ char *x11_init (Socket *s, char *display, void *c) {
     /*
      * Open socket.
      */
-    *s = sk_new(addr, port, 0, x11_receive);
+    *s = sk_new(addr, port, 0, 1, x11_receive);
     if ( (err = sk_socket_error(*s)) )
        return err;