summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-03-05 06:16:11 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-03-05 06:16:11 +0000
commit7fbd455c780e96065dc2bd8d96d21f0c017c0f99 (patch)
tree5e8bf350a8beaec98596e5f680b140006b123a8f /channels.c
parente9613cf16d72fd78bda7ece0abd7f36c0fb266b6 (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.
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c57
1 files changed, 44 insertions, 13 deletions
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}