diff options
author | Ben Lindstrom <mouring@eviladmin.org> | 2001-03-05 06:16:11 +0000 |
---|---|---|
committer | Ben Lindstrom <mouring@eviladmin.org> | 2001-03-05 06:16:11 +0000 |
commit | 7fbd455c780e96065dc2bd8d96d21f0c017c0f99 (patch) | |
tree | 5e8bf350a8beaec98596e5f680b140006b123a8f | |
parent | e9613cf16d72fd78bda7ece0abd7f36c0fb266b6 (diff) |
- 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.
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | channels.c | 57 | ||||
-rw-r--r-- | nchan.c | 57 | ||||
-rw-r--r-- | nchan.h | 4 |
4 files changed, 82 insertions, 42 deletions
@@ -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 | ||
72 | 20010304 | 76 | 20010304 |
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" |
43 | RCSID("$OpenBSD: channels.c,v 1.92 2001/02/16 13:38:18 markus Exp $"); | 43 | RCSID("$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 | } |
847 | int | 857 | int |
848 | channel_check_window(Channel *c, fd_set * readset, fd_set * writeset) | 858 | channel_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 | ||
882 | void | 893 | void |
@@ -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 | } |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: nchan.c,v 1.22 2001/01/21 19:05:52 markus Exp $"); | 26 | RCSID("$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); | |||
54 | static void chan_send_close2(Channel *c); | 54 | static void chan_send_close2(Channel *c); |
55 | static void chan_send_eof2(Channel *c); | 55 | static void chan_send_eof2(Channel *c); |
56 | 56 | ||
57 | /* channel cleanup */ | ||
58 | chan_event_fn *chan_delete_if_full_closed = NULL; | ||
59 | |||
60 | /* helper */ | 57 | /* helper */ |
61 | static void chan_shutdown_write(Channel *c); | 58 | static void chan_shutdown_write(Channel *c); |
62 | static void chan_shutdown_read(Channel *c); | 59 | static void chan_shutdown_read(Channel *c); |
@@ -249,16 +246,6 @@ chan_send_oclose1(Channel *c) | |||
249 | break; | 246 | break; |
250 | } | 247 | } |
251 | } | 248 | } |
252 | static void | ||
253 | chan_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 | } |
404 | static void | 391 | |
405 | chan_delete_if_full_closed2(Channel *c) | 392 | /* shared */ |
393 | |||
394 | int | ||
395 | chan_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 */ | ||
422 | void | 431 | void |
423 | chan_init_iostates(Channel *c) | 432 | chan_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 | ||
@@ -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; | |||
84 | extern chan_event_fn *chan_write_failed; | 84 | extern chan_event_fn *chan_write_failed; |
85 | extern chan_event_fn *chan_obuf_empty; | 85 | extern chan_event_fn *chan_obuf_empty; |
86 | 86 | ||
87 | extern chan_event_fn *chan_delete_if_full_closed; | 87 | int chan_is_dead(Channel * c); |
88 | 88 | ||
89 | void chan_init_iostates(Channel * c); | 89 | void chan_init_iostates(Channel * c); |
90 | void chan_init(void); | 90 | void chan_init(void); |