]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2001/02/28 08:54:55
authormouring <mouring>
Mon, 5 Mar 2001 06:16:11 +0000 (06:16 +0000)
committermouring <mouring>
Mon, 5 Mar 2001 06:16:11 +0000 (06:16 +0000)
     [channels.c nchan.c nchan.h]
     make sure remote stderr does not get truncated.
     remove closed fd's from the select mask.

ChangeLog
channels.c
nchan.c
nchan.h

index 5b4d02a0a2942eeeacba1103976253a7302f0260..ae363b9fc22b54b19c389aa92054f9aa40e12d53 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - markus@cvs.openbsd.org 2001/02/28 08:45:39
      [clientloop.c]
      fix byte counts for ssh protocol v1
+   - markus@cvs.openbsd.org 2001/02/28 08:54:55
+     [channels.c nchan.c nchan.h]
+     make sure remote stderr does not get truncated.
+     remove closed fd's from the select mask.
 
 20010304
  - (bal) Remove make-ssh-known-hosts.1 since it's no longer valid.
index 71a345109a7251ee752cf0f3de68bf9d74c81069..f10427c17827de3c86f2f151a75c7f337ce442c0 100644 (file)
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.92 2001/02/16 13:38:18 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.93 2001/02/28 08:54:55 markus Exp $");
 
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
@@ -824,7 +824,14 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
                            buffer_len(&c->extended));
                        debug2("channel %d: written %d to efd %d",
                            c->self, len, c->efd);
-                       if (len > 0) {
+                       if (len < 0 && (errno == EINTR || errno == EAGAIN))
+                               return 1;
+                       if (len <= 0) {
+                               debug2("channel %d: closing write-efd %d",
+                                   c->self, c->efd);
+                               close(c->efd);
+                               c->efd = -1;
+                       } else {
                                buffer_consume(&c->extended, len);
                                c->local_consumed += len;
                        }
@@ -833,19 +840,22 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
                        len = read(c->efd, buf, sizeof(buf));
                        debug2("channel %d: read %d from efd %d",
                             c->self, len, c->efd);
-                       if (len == 0) {
-                               debug("channel %d: closing efd %d",
+                       if (len < 0 && (errno == EINTR || errno == EAGAIN))
+                               return 1;
+                       if (len <= 0) {
+                               debug2("channel %d: closing read-efd %d",
                                    c->self, c->efd);
                                close(c->efd);
                                c->efd = -1;
-                       } else if (len > 0)
+                       } else {
                                buffer_append(&c->extended, buf, len);
+                       }
                }
        }
        return 1;
 }
 int
-channel_check_window(Channel *c, fd_set * readset, fd_set * writeset)
+channel_check_window(Channel *c)
 {
        if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
            c->local_window < c->local_window_max/2 &&
@@ -876,7 +886,8 @@ channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset)
        channel_handle_rfd(c, readset, writeset);
        channel_handle_wfd(c, readset, writeset);
        channel_handle_efd(c, readset, writeset);
-       channel_check_window(c, readset, writeset);
+
+       channel_check_window(c);
 }
 
 void
@@ -984,7 +995,24 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
                if (ftab[c->type] == NULL)
                        continue;
                (*ftab[c->type])(c, readset, writeset);
-               chan_delete_if_full_closed(c);
+               if (chan_is_dead(c)) {
+                       /*
+                        * we have to remove the fd's from the select mask
+                        * before the channels are free'd and the fd's are
+                        * closed
+                        */
+                       if (c->wfd != -1)
+                               FD_CLR(c->wfd, writeset);
+                       if (c->rfd != -1)
+                               FD_CLR(c->rfd, readset);
+                       if (c->efd != -1) {
+                               if (c->extended_usage == CHAN_EXTENDED_READ)
+                                       FD_CLR(c->efd, readset);
+                               if (c->extended_usage == CHAN_EXTENDED_WRITE)
+                                       FD_CLR(c->efd, writeset);
+                       }
+                       channel_free(c->self);
+               }
        }
 }
 
@@ -1037,19 +1065,18 @@ channel_output_poll()
                } else {
                        if (c->type != SSH_CHANNEL_OPEN)
                                continue;
-                       if (c->istate != CHAN_INPUT_OPEN &&
-                           c->istate != CHAN_INPUT_WAIT_DRAIN)
-                               continue;
                }
                if (compat20 &&
                    (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
+                       /* XXX is this true? */
                        debug("channel: %d: no data after CLOSE", c->self);
                        continue;
                }
 
                /* Get the amount of buffered data for this channel. */
-               len = buffer_len(&c->input);
-               if (len > 0) {
+               if ((c->istate == CHAN_INPUT_OPEN ||
+                   c->istate == CHAN_INPUT_WAIT_DRAIN) &&
+                   (len = buffer_len(&c->input)) > 0) {
                        /* Send some data for the other side over the secure connection. */
                        if (compat20) {
                                if (len > c->remote_window)
@@ -1089,6 +1116,9 @@ channel_output_poll()
                    c->remote_window > 0 &&
                    (len = buffer_len(&c->extended)) > 0 &&
                    c->extended_usage == CHAN_EXTENDED_READ) {
+                       debug2("channel %d: rwin %d elen %d euse %d",
+                           c->self, c->remote_window, buffer_len(&c->extended),
+                           c->extended_usage);
                        if (len > c->remote_window)
                                len = c->remote_window;
                        if (len > c->remote_maxpacket)
@@ -1100,6 +1130,7 @@ channel_output_poll()
                        packet_send();
                        buffer_consume(&c->extended, len);
                        c->remote_window -= len;
+                       debug2("channel %d: sent ext data %d", c->self, len);
                }
        }
 }
diff --git a/nchan.c b/nchan.c
index 6c347203d4c3757b775295c67900ccdda7c129d4..d91217e541cdf8899c31a39050878ffc781a27eb 100644 (file)
--- a/nchan.c
+++ b/nchan.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: nchan.c,v 1.22 2001/01/21 19:05:52 markus Exp $");
+RCSID("$OpenBSD: nchan.c,v 1.23 2001/02/28 08:54:55 markus Exp $");
 
 #include "ssh1.h"
 #include "ssh2.h"
@@ -54,9 +54,6 @@ static void   chan_send_oclose1(Channel *c);
 static void    chan_send_close2(Channel *c);
 static void    chan_send_eof2(Channel *c);
 
-/* channel cleanup */
-chan_event_fn *chan_delete_if_full_closed      = NULL;
-
 /* helper */
 static void    chan_shutdown_write(Channel *c);
 static void    chan_shutdown_read(Channel *c);
@@ -249,16 +246,6 @@ chan_send_oclose1(Channel *c)
                break;
        }
 }
-static void
-chan_delete_if_full_closed1(Channel *c)
-{
-       debug3("channel %d: chan_delete_if_full_closed1: istate %d ostate %d",
-           c->self, c->istate, c->ostate);
-       if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
-               debug("channel %d: full closed", c->self);
-               channel_free(c->self);
-       }
-}
 
 /*
  * the same for SSH2
@@ -401,24 +388,46 @@ chan_send_close2(Channel *c)
                c->flags |= CHAN_CLOSE_SENT;
        }
 }
-static void
-chan_delete_if_full_closed2(Channel *c)
+
+/* shared */
+
+int
+chan_is_dead(Channel *c)
 {
-       debug3("channel %d: chan_delete_if_full_closed2: istate %d ostate %d",
-           c->self, c->istate, c->ostate);
-       if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
+       if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
+               return 0;
+       if (!compat20) {
+               debug("channel %d: is dead", c->self);
+               return 1;
+       }
+       /*
+        * we have to delay the close message if the efd (for stderr) is
+        * still active
+        */
+       if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
+           buffer_len(&c->extended) > 0)
+#if 0
+           || ((c->extended_usage == CHAN_EXTENDED_READ) &&
+           c->efd != -1)
+#endif
+           ) {
+               debug2("channel %d: active efd: %d len %d type %s",
+                   c->self, c->efd, buffer_len(&c->extended),
+                   c->extended_usage==CHAN_EXTENDED_READ ?
+                      "read": "write");
+       } else {
                if (!(c->flags & CHAN_CLOSE_SENT)) {
                        chan_send_close2(c);
                }
                if ((c->flags & CHAN_CLOSE_SENT) &&
                    (c->flags & CHAN_CLOSE_RCVD)) {
-                       debug("channel %d: full closed2", c->self);
-                       channel_free(c->self);
+                       debug("channel %d: is dead", c->self);
+                       return 1;
                }
        }
+       return 0;
 }
 
-/* shared */
 void
 chan_init_iostates(Channel *c)
 {
@@ -439,8 +448,6 @@ chan_init(void)
                chan_rcvd_ieof                  = chan_rcvd_ieof2;
                chan_write_failed               = chan_write_failed2;
                chan_obuf_empty                 = chan_obuf_empty2;
-
-               chan_delete_if_full_closed      = chan_delete_if_full_closed2;
        } else {
                chan_rcvd_oclose                = chan_rcvd_oclose1;
                chan_read_failed                = chan_read_failed_12;
@@ -449,8 +456,6 @@ chan_init(void)
                chan_rcvd_ieof                  = chan_rcvd_ieof1;
                chan_write_failed               = chan_write_failed1;
                chan_obuf_empty                 = chan_obuf_empty1;
-
-               chan_delete_if_full_closed      = chan_delete_if_full_closed1;
        }
 }
 
diff --git a/nchan.h b/nchan.h
index 366b894ae98b874f35a465d8694103ceae6d20d0..623ecccc31cfbec1ab7990d0abba1dab93e75a4a 100644 (file)
--- a/nchan.h
+++ b/nchan.h
@@ -22,7 +22,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* RCSID("$OpenBSD: nchan.h,v 1.9 2000/09/07 20:27:52 deraadt Exp $"); */
+/* RCSID("$OpenBSD: nchan.h,v 1.10 2001/02/28 08:54:55 markus Exp $"); */
 
 #ifndef NCHAN_H
 #define NCHAN_H
@@ -84,7 +84,7 @@ extern chan_event_fn  *chan_rcvd_ieof;
 extern chan_event_fn   *chan_write_failed;
 extern chan_event_fn   *chan_obuf_empty;
 
-extern chan_event_fn   *chan_delete_if_full_closed;
+int chan_is_dead(Channel * c);
 
 void    chan_init_iostates(Channel * c);
 void   chan_init(void);
This page took 0.932787 seconds and 5 git commands to generate.