summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--channels.c57
-rw-r--r--nchan.c57
-rw-r--r--nchan.h4
4 files changed, 82 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index 36ab623ad..a30623c4a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -68,6 +68,10 @@
68 - markus@cvs.openbsd.org 2001/02/28 08:45:39 68 - markus@cvs.openbsd.org 2001/02/28 08:45:39
69 [clientloop.c] 69 [clientloop.c]
70 fix byte counts for ssh protocol v1 70 fix byte counts for ssh protocol v1
71 - markus@cvs.openbsd.org 2001/02/28 08:54:55
72 [channels.c nchan.c nchan.h]
73 make sure remote stderr does not get truncated.
74 remove closed fd's from the select mask.
71 75
7220010304 7620010304
73 - (bal) Remove make-ssh-known-hosts.1 since it's no longer valid. 77 - (bal) Remove make-ssh-known-hosts.1 since it's no longer valid.
@@ -4260,4 +4264,4 @@
4260 - Wrote replacements for strlcpy and mkdtemp 4264 - Wrote replacements for strlcpy and mkdtemp
4261 - Released 1.0pre1 4265 - Released 1.0pre1
4262 4266
4263$Id: ChangeLog,v 1.871 2001/03/05 06:14:02 mouring Exp $ 4267$Id: ChangeLog,v 1.872 2001/03/05 06:16:11 mouring Exp $
diff --git a/channels.c b/channels.c
index 71a345109..f10427c17 100644
--- a/channels.c
+++ b/channels.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42#include "includes.h" 42#include "includes.h"
43RCSID("$OpenBSD: channels.c,v 1.92 2001/02/16 13:38:18 markus Exp $"); 43RCSID("$OpenBSD: channels.c,v 1.93 2001/02/28 08:54:55 markus Exp $");
44 44
45#include <openssl/rsa.h> 45#include <openssl/rsa.h>
46#include <openssl/dsa.h> 46#include <openssl/dsa.h>
@@ -824,7 +824,14 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
824 buffer_len(&c->extended)); 824 buffer_len(&c->extended));
825 debug2("channel %d: written %d to efd %d", 825 debug2("channel %d: written %d to efd %d",
826 c->self, len, c->efd); 826 c->self, len, c->efd);
827 if (len > 0) { 827 if (len < 0 && (errno == EINTR || errno == EAGAIN))
828 return 1;
829 if (len <= 0) {
830 debug2("channel %d: closing write-efd %d",
831 c->self, c->efd);
832 close(c->efd);
833 c->efd = -1;
834 } else {
828 buffer_consume(&c->extended, len); 835 buffer_consume(&c->extended, len);
829 c->local_consumed += len; 836 c->local_consumed += len;
830 } 837 }
@@ -833,19 +840,22 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset)
833 len = read(c->efd, buf, sizeof(buf)); 840 len = read(c->efd, buf, sizeof(buf));
834 debug2("channel %d: read %d from efd %d", 841 debug2("channel %d: read %d from efd %d",
835 c->self, len, c->efd); 842 c->self, len, c->efd);
836 if (len == 0) { 843 if (len < 0 && (errno == EINTR || errno == EAGAIN))
837 debug("channel %d: closing efd %d", 844 return 1;
845 if (len <= 0) {
846 debug2("channel %d: closing read-efd %d",
838 c->self, c->efd); 847 c->self, c->efd);
839 close(c->efd); 848 close(c->efd);
840 c->efd = -1; 849 c->efd = -1;
841 } else if (len > 0) 850 } else {
842 buffer_append(&c->extended, buf, len); 851 buffer_append(&c->extended, buf, len);
852 }
843 } 853 }
844 } 854 }
845 return 1; 855 return 1;
846} 856}
847int 857int
848channel_check_window(Channel *c, fd_set * readset, fd_set * writeset) 858channel_check_window(Channel *c)
849{ 859{
850 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) && 860 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD)) &&
851 c->local_window < c->local_window_max/2 && 861 c->local_window < c->local_window_max/2 &&
@@ -876,7 +886,8 @@ channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset)
876 channel_handle_rfd(c, readset, writeset); 886 channel_handle_rfd(c, readset, writeset);
877 channel_handle_wfd(c, readset, writeset); 887 channel_handle_wfd(c, readset, writeset);
878 channel_handle_efd(c, readset, writeset); 888 channel_handle_efd(c, readset, writeset);
879 channel_check_window(c, readset, writeset); 889
890 channel_check_window(c);
880} 891}
881 892
882void 893void
@@ -984,7 +995,24 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
984 if (ftab[c->type] == NULL) 995 if (ftab[c->type] == NULL)
985 continue; 996 continue;
986 (*ftab[c->type])(c, readset, writeset); 997 (*ftab[c->type])(c, readset, writeset);
987 chan_delete_if_full_closed(c); 998 if (chan_is_dead(c)) {
999 /*
1000 * we have to remove the fd's from the select mask
1001 * before the channels are free'd and the fd's are
1002 * closed
1003 */
1004 if (c->wfd != -1)
1005 FD_CLR(c->wfd, writeset);
1006 if (c->rfd != -1)
1007 FD_CLR(c->rfd, readset);
1008 if (c->efd != -1) {
1009 if (c->extended_usage == CHAN_EXTENDED_READ)
1010 FD_CLR(c->efd, readset);
1011 if (c->extended_usage == CHAN_EXTENDED_WRITE)
1012 FD_CLR(c->efd, writeset);
1013 }
1014 channel_free(c->self);
1015 }
988 } 1016 }
989} 1017}
990 1018
@@ -1037,19 +1065,18 @@ channel_output_poll()
1037 } else { 1065 } else {
1038 if (c->type != SSH_CHANNEL_OPEN) 1066 if (c->type != SSH_CHANNEL_OPEN)
1039 continue; 1067 continue;
1040 if (c->istate != CHAN_INPUT_OPEN &&
1041 c->istate != CHAN_INPUT_WAIT_DRAIN)
1042 continue;
1043 } 1068 }
1044 if (compat20 && 1069 if (compat20 &&
1045 (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) { 1070 (c->flags & (CHAN_CLOSE_SENT|CHAN_CLOSE_RCVD))) {
1071 /* XXX is this true? */
1046 debug("channel: %d: no data after CLOSE", c->self); 1072 debug("channel: %d: no data after CLOSE", c->self);
1047 continue; 1073 continue;
1048 } 1074 }
1049 1075
1050 /* Get the amount of buffered data for this channel. */ 1076 /* Get the amount of buffered data for this channel. */
1051 len = buffer_len(&c->input); 1077 if ((c->istate == CHAN_INPUT_OPEN ||
1052 if (len > 0) { 1078 c->istate == CHAN_INPUT_WAIT_DRAIN) &&
1079 (len = buffer_len(&c->input)) > 0) {
1053 /* Send some data for the other side over the secure connection. */ 1080 /* Send some data for the other side over the secure connection. */
1054 if (compat20) { 1081 if (compat20) {
1055 if (len > c->remote_window) 1082 if (len > c->remote_window)
@@ -1089,6 +1116,9 @@ channel_output_poll()
1089 c->remote_window > 0 && 1116 c->remote_window > 0 &&
1090 (len = buffer_len(&c->extended)) > 0 && 1117 (len = buffer_len(&c->extended)) > 0 &&
1091 c->extended_usage == CHAN_EXTENDED_READ) { 1118 c->extended_usage == CHAN_EXTENDED_READ) {
1119 debug2("channel %d: rwin %d elen %d euse %d",
1120 c->self, c->remote_window, buffer_len(&c->extended),
1121 c->extended_usage);
1092 if (len > c->remote_window) 1122 if (len > c->remote_window)
1093 len = c->remote_window; 1123 len = c->remote_window;
1094 if (len > c->remote_maxpacket) 1124 if (len > c->remote_maxpacket)
@@ -1100,6 +1130,7 @@ channel_output_poll()
1100 packet_send(); 1130 packet_send();
1101 buffer_consume(&c->extended, len); 1131 buffer_consume(&c->extended, len);
1102 c->remote_window -= len; 1132 c->remote_window -= len;
1133 debug2("channel %d: sent ext data %d", c->self, len);
1103 } 1134 }
1104 } 1135 }
1105} 1136}
diff --git a/nchan.c b/nchan.c
index 6c347203d..d91217e54 100644
--- a/nchan.c
+++ b/nchan.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: nchan.c,v 1.22 2001/01/21 19:05:52 markus Exp $"); 26RCSID("$OpenBSD: nchan.c,v 1.23 2001/02/28 08:54:55 markus Exp $");
27 27
28#include "ssh1.h" 28#include "ssh1.h"
29#include "ssh2.h" 29#include "ssh2.h"
@@ -54,9 +54,6 @@ static void chan_send_oclose1(Channel *c);
54static void chan_send_close2(Channel *c); 54static void chan_send_close2(Channel *c);
55static void chan_send_eof2(Channel *c); 55static void chan_send_eof2(Channel *c);
56 56
57/* channel cleanup */
58chan_event_fn *chan_delete_if_full_closed = NULL;
59
60/* helper */ 57/* helper */
61static void chan_shutdown_write(Channel *c); 58static void chan_shutdown_write(Channel *c);
62static void chan_shutdown_read(Channel *c); 59static void chan_shutdown_read(Channel *c);
@@ -249,16 +246,6 @@ chan_send_oclose1(Channel *c)
249 break; 246 break;
250 } 247 }
251} 248}
252static void
253chan_delete_if_full_closed1(Channel *c)
254{
255 debug3("channel %d: chan_delete_if_full_closed1: istate %d ostate %d",
256 c->self, c->istate, c->ostate);
257 if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) {
258 debug("channel %d: full closed", c->self);
259 channel_free(c->self);
260 }
261}
262 249
263/* 250/*
264 * the same for SSH2 251 * the same for SSH2
@@ -401,24 +388,46 @@ chan_send_close2(Channel *c)
401 c->flags |= CHAN_CLOSE_SENT; 388 c->flags |= CHAN_CLOSE_SENT;
402 } 389 }
403} 390}
404static void 391
405chan_delete_if_full_closed2(Channel *c) 392/* shared */
393
394int
395chan_is_dead(Channel *c)
406{ 396{
407 debug3("channel %d: chan_delete_if_full_closed2: istate %d ostate %d", 397 if (c->istate != CHAN_INPUT_CLOSED || c->ostate != CHAN_OUTPUT_CLOSED)
408 c->self, c->istate, c->ostate); 398 return 0;
409 if (c->istate == CHAN_INPUT_CLOSED && c->ostate == CHAN_OUTPUT_CLOSED) { 399 if (!compat20) {
400 debug("channel %d: is dead", c->self);
401 return 1;
402 }
403 /*
404 * we have to delay the close message if the efd (for stderr) is
405 * still active
406 */
407 if (((c->extended_usage != CHAN_EXTENDED_IGNORE) &&
408 buffer_len(&c->extended) > 0)
409#if 0
410 || ((c->extended_usage == CHAN_EXTENDED_READ) &&
411 c->efd != -1)
412#endif
413 ) {
414 debug2("channel %d: active efd: %d len %d type %s",
415 c->self, c->efd, buffer_len(&c->extended),
416 c->extended_usage==CHAN_EXTENDED_READ ?
417 "read": "write");
418 } else {
410 if (!(c->flags & CHAN_CLOSE_SENT)) { 419 if (!(c->flags & CHAN_CLOSE_SENT)) {
411 chan_send_close2(c); 420 chan_send_close2(c);
412 } 421 }
413 if ((c->flags & CHAN_CLOSE_SENT) && 422 if ((c->flags & CHAN_CLOSE_SENT) &&
414 (c->flags & CHAN_CLOSE_RCVD)) { 423 (c->flags & CHAN_CLOSE_RCVD)) {
415 debug("channel %d: full closed2", c->self); 424 debug("channel %d: is dead", c->self);
416 channel_free(c->self); 425 return 1;
417 } 426 }
418 } 427 }
428 return 0;
419} 429}
420 430
421/* shared */
422void 431void
423chan_init_iostates(Channel *c) 432chan_init_iostates(Channel *c)
424{ 433{
@@ -439,8 +448,6 @@ chan_init(void)
439 chan_rcvd_ieof = chan_rcvd_ieof2; 448 chan_rcvd_ieof = chan_rcvd_ieof2;
440 chan_write_failed = chan_write_failed2; 449 chan_write_failed = chan_write_failed2;
441 chan_obuf_empty = chan_obuf_empty2; 450 chan_obuf_empty = chan_obuf_empty2;
442
443 chan_delete_if_full_closed = chan_delete_if_full_closed2;
444 } else { 451 } else {
445 chan_rcvd_oclose = chan_rcvd_oclose1; 452 chan_rcvd_oclose = chan_rcvd_oclose1;
446 chan_read_failed = chan_read_failed_12; 453 chan_read_failed = chan_read_failed_12;
@@ -449,8 +456,6 @@ chan_init(void)
449 chan_rcvd_ieof = chan_rcvd_ieof1; 456 chan_rcvd_ieof = chan_rcvd_ieof1;
450 chan_write_failed = chan_write_failed1; 457 chan_write_failed = chan_write_failed1;
451 chan_obuf_empty = chan_obuf_empty1; 458 chan_obuf_empty = chan_obuf_empty1;
452
453 chan_delete_if_full_closed = chan_delete_if_full_closed1;
454 } 459 }
455} 460}
456 461
diff --git a/nchan.h b/nchan.h
index 366b894ae..623ecccc3 100644
--- a/nchan.h
+++ b/nchan.h
@@ -22,7 +22,7 @@
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */ 23 */
24 24
25/* RCSID("$OpenBSD: nchan.h,v 1.9 2000/09/07 20:27:52 deraadt Exp $"); */ 25/* RCSID("$OpenBSD: nchan.h,v 1.10 2001/02/28 08:54:55 markus Exp $"); */
26 26
27#ifndef NCHAN_H 27#ifndef NCHAN_H
28#define NCHAN_H 28#define NCHAN_H
@@ -84,7 +84,7 @@ extern chan_event_fn *chan_rcvd_ieof;
84extern chan_event_fn *chan_write_failed; 84extern chan_event_fn *chan_write_failed;
85extern chan_event_fn *chan_obuf_empty; 85extern chan_event_fn *chan_obuf_empty;
86 86
87extern chan_event_fn *chan_delete_if_full_closed; 87int chan_is_dead(Channel * c);
88 88
89void chan_init_iostates(Channel * c); 89void chan_init_iostates(Channel * c);
90void chan_init(void); 90void chan_init(void);