summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--channels.h22
-rw-r--r--nchan.c83
3 files changed, 59 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index e688d4f02..c9bc5f1ff 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -159,6 +159,10 @@
159 [auth2.c auth2-chall.c compat.c sshconnect2.c sshd.c] 159 [auth2.c auth2-chall.c compat.c sshconnect2.c sshd.c]
160 use buffer API and avoid static strings of fixed size; 160 use buffer API and avoid static strings of fixed size;
161 ok provos@/mouring@ 161 ok provos@/mouring@
162 - markus@cvs.openbsd.org 2002/01/13 21:31:20
163 [channels.h nchan.c]
164 add chan_set_[io]state(), order states, state is now an u_int,
165 simplifies debugging messages; ok provos@
162 166
163 167
16420020121 16820020121
@@ -7307,4 +7311,4 @@
7307 - Wrote replacements for strlcpy and mkdtemp 7311 - Wrote replacements for strlcpy and mkdtemp
7308 - Released 1.0pre1 7312 - Released 1.0pre1
7309 7313
7310$Id: ChangeLog,v 1.1768 2002/01/22 12:26:38 djm Exp $ 7314$Id: ChangeLog,v 1.1769 2002/01/22 12:27:11 djm Exp $
diff --git a/channels.h b/channels.h
index 40142c509..a857db11e 100644
--- a/channels.h
+++ b/channels.h
@@ -32,7 +32,7 @@
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35/* RCSID("$OpenBSD: channels.h,v 1.56 2001/12/28 15:06:00 markus Exp $"); */ 35/* RCSID("$OpenBSD: channels.h,v 1.57 2002/01/13 21:31:20 markus Exp $"); */
36 36
37#ifndef CHANNEL_H 37#ifndef CHANNEL_H
38#define CHANNEL_H 38#define CHANNEL_H
@@ -68,8 +68,8 @@ struct Channel {
68 int type; /* channel type/state */ 68 int type; /* channel type/state */
69 int self; /* my own channel identifier */ 69 int self; /* my own channel identifier */
70 int remote_id; /* channel identifier for remote peer */ 70 int remote_id; /* channel identifier for remote peer */
71 int istate; /* input from channel (state of receive half) */ 71 u_int istate; /* input from channel (state of receive half) */
72 int ostate; /* output to channel (state of transmit half) */ 72 u_int ostate; /* output to channel (state of transmit half) */
73 int flags; /* close sent/rcvd */ 73 int flags; /* close sent/rcvd */
74 int rfd; /* read fd */ 74 int rfd; /* read fd */
75 int wfd; /* write fd */ 75 int wfd; /* write fd */
@@ -123,16 +123,16 @@ struct Channel {
123#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2) 123#define CHAN_X11_PACKET_DEFAULT (CHAN_X11_WINDOW_DEFAULT/2)
124 124
125/* possible input states */ 125/* possible input states */
126#define CHAN_INPUT_OPEN 0x01 126#define CHAN_INPUT_OPEN 0
127#define CHAN_INPUT_WAIT_DRAIN 0x02 127#define CHAN_INPUT_WAIT_DRAIN 1
128#define CHAN_INPUT_WAIT_OCLOSE 0x04 128#define CHAN_INPUT_WAIT_OCLOSE 2
129#define CHAN_INPUT_CLOSED 0x08 129#define CHAN_INPUT_CLOSED 3
130 130
131/* possible output states */ 131/* possible output states */
132#define CHAN_OUTPUT_OPEN 0x10 132#define CHAN_OUTPUT_OPEN 0
133#define CHAN_OUTPUT_WAIT_DRAIN 0x20 133#define CHAN_OUTPUT_WAIT_DRAIN 1
134#define CHAN_OUTPUT_WAIT_IEOF 0x40 134#define CHAN_OUTPUT_WAIT_IEOF 2
135#define CHAN_OUTPUT_CLOSED 0x80 135#define CHAN_OUTPUT_CLOSED 3
136 136
137#define CHAN_CLOSE_SENT 0x01 137#define CHAN_CLOSE_SENT 0x01
138#define CHAN_CLOSE_RCVD 0x02 138#define CHAN_CLOSE_RCVD 0x02
diff --git a/nchan.c b/nchan.c
index 905379b07..04266d326 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.36 2002/01/10 12:47:59 markus Exp $"); 26RCSID("$OpenBSD: nchan.c,v 1.37 2002/01/13 21:31:20 markus Exp $");
27 27
28#include "ssh1.h" 28#include "ssh1.h"
29#include "ssh2.h" 29#include "ssh2.h"
@@ -83,6 +83,28 @@ static void chan_send_eof2(Channel *);
83static void chan_shutdown_write(Channel *); 83static void chan_shutdown_write(Channel *);
84static void chan_shutdown_read(Channel *); 84static void chan_shutdown_read(Channel *);
85 85
86static char *ostates[] = { "open", "drain", "wait_ieof", "closed" };
87static char *istates[] = { "open", "drain", "wait_oclose", "closed" };
88
89static void
90chan_set_istate(Channel *c, u_int next)
91{
92 if (c->istate > CHAN_INPUT_CLOSED || next > CHAN_INPUT_CLOSED)
93 fatal("chan_set_istate: bad state %d -> %d", c->istate, next);
94 debug("channel %d: input %s -> %s", c->self, istates[c->istate],
95 istates[next]);
96 c->istate = next;
97}
98static void
99chan_set_ostate(Channel *c, u_int next)
100{
101 if (c->ostate > CHAN_OUTPUT_CLOSED || next > CHAN_OUTPUT_CLOSED)
102 fatal("chan_set_ostate: bad state %d -> %d", c->ostate, next);
103 debug("channel %d: output %s -> %s", c->self, ostates[c->ostate],
104 ostates[next]);
105 c->ostate = next;
106}
107
86/* 108/*
87 * SSH1 specific implementation of event functions 109 * SSH1 specific implementation of event functions
88 */ 110 */
@@ -93,20 +115,17 @@ chan_rcvd_oclose1(Channel *c)
93 debug("channel %d: rcvd oclose", c->self); 115 debug("channel %d: rcvd oclose", c->self);
94 switch (c->istate) { 116 switch (c->istate) {
95 case CHAN_INPUT_WAIT_OCLOSE: 117 case CHAN_INPUT_WAIT_OCLOSE:
96 debug("channel %d: input wait_oclose -> closed", c->self); 118 chan_set_istate(c, CHAN_INPUT_CLOSED);
97 c->istate = CHAN_INPUT_CLOSED;
98 break; 119 break;
99 case CHAN_INPUT_OPEN: 120 case CHAN_INPUT_OPEN:
100 debug("channel %d: input open -> closed", c->self);
101 chan_shutdown_read(c); 121 chan_shutdown_read(c);
102 chan_send_ieof1(c); 122 chan_send_ieof1(c);
103 c->istate = CHAN_INPUT_CLOSED; 123 chan_set_istate(c, CHAN_INPUT_CLOSED);
104 break; 124 break;
105 case CHAN_INPUT_WAIT_DRAIN: 125 case CHAN_INPUT_WAIT_DRAIN:
106 /* both local read_failed and remote write_failed */ 126 /* both local read_failed and remote write_failed */
107 log("channel %d: input drain -> closed", c->self);
108 chan_send_ieof1(c); 127 chan_send_ieof1(c);
109 c->istate = CHAN_INPUT_CLOSED; 128 chan_set_istate(c, CHAN_INPUT_CLOSED);
110 break; 129 break;
111 default: 130 default:
112 error("channel %d: protocol error: rcvd_oclose for istate %d", 131 error("channel %d: protocol error: rcvd_oclose for istate %d",
@@ -120,9 +139,8 @@ chan_read_failed_12(Channel *c)
120 debug("channel %d: read failed", c->self); 139 debug("channel %d: read failed", c->self);
121 switch (c->istate) { 140 switch (c->istate) {
122 case CHAN_INPUT_OPEN: 141 case CHAN_INPUT_OPEN:
123 debug("channel %d: input open -> drain", c->self);
124 chan_shutdown_read(c); 142 chan_shutdown_read(c);
125 c->istate = CHAN_INPUT_WAIT_DRAIN; 143 chan_set_istate(c, CHAN_INPUT_WAIT_DRAIN);
126 break; 144 break;
127 default: 145 default:
128 error("channel %d: chan_read_failed for istate %d", 146 error("channel %d: chan_read_failed for istate %d",
@@ -141,9 +159,8 @@ chan_ibuf_empty1(Channel *c)
141 } 159 }
142 switch (c->istate) { 160 switch (c->istate) {
143 case CHAN_INPUT_WAIT_DRAIN: 161 case CHAN_INPUT_WAIT_DRAIN:
144 debug("channel %d: input drain -> wait_oclose", c->self);
145 chan_send_ieof1(c); 162 chan_send_ieof1(c);
146 c->istate = CHAN_INPUT_WAIT_OCLOSE; 163 chan_set_istate(c, CHAN_INPUT_WAIT_OCLOSE);
147 break; 164 break;
148 default: 165 default:
149 error("channel %d: chan_ibuf_empty for istate %d", 166 error("channel %d: chan_ibuf_empty for istate %d",
@@ -157,12 +174,10 @@ chan_rcvd_ieof1(Channel *c)
157 debug("channel %d: rcvd ieof", c->self); 174 debug("channel %d: rcvd ieof", c->self);
158 switch (c->ostate) { 175 switch (c->ostate) {
159 case CHAN_OUTPUT_OPEN: 176 case CHAN_OUTPUT_OPEN:
160 debug("channel %d: output open -> drain", c->self); 177 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
161 c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
162 break; 178 break;
163 case CHAN_OUTPUT_WAIT_IEOF: 179 case CHAN_OUTPUT_WAIT_IEOF:
164 debug("channel %d: output wait_ieof -> closed", c->self); 180 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
165 c->ostate = CHAN_OUTPUT_CLOSED;
166 break; 181 break;
167 default: 182 default:
168 error("channel %d: protocol error: rcvd_ieof for ostate %d", 183 error("channel %d: protocol error: rcvd_ieof for ostate %d",
@@ -176,14 +191,12 @@ chan_write_failed1(Channel *c)
176 debug("channel %d: write failed", c->self); 191 debug("channel %d: write failed", c->self);
177 switch (c->ostate) { 192 switch (c->ostate) {
178 case CHAN_OUTPUT_OPEN: 193 case CHAN_OUTPUT_OPEN:
179 debug("channel %d: output open -> wait_ieof", c->self);
180 chan_send_oclose1(c); 194 chan_send_oclose1(c);
181 c->ostate = CHAN_OUTPUT_WAIT_IEOF; 195 chan_set_ostate(c, CHAN_OUTPUT_WAIT_IEOF);
182 break; 196 break;
183 case CHAN_OUTPUT_WAIT_DRAIN: 197 case CHAN_OUTPUT_WAIT_DRAIN:
184 debug("channel %d: output wait_drain -> closed", c->self);
185 chan_send_oclose1(c); 198 chan_send_oclose1(c);
186 c->ostate = CHAN_OUTPUT_CLOSED; 199 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
187 break; 200 break;
188 default: 201 default:
189 error("channel %d: chan_write_failed for ostate %d", 202 error("channel %d: chan_write_failed for ostate %d",
@@ -202,9 +215,8 @@ chan_obuf_empty1(Channel *c)
202 } 215 }
203 switch (c->ostate) { 216 switch (c->ostate) {
204 case CHAN_OUTPUT_WAIT_DRAIN: 217 case CHAN_OUTPUT_WAIT_DRAIN:
205 debug("channel %d: output drain -> closed", c->self);
206 chan_send_oclose1(c); 218 chan_send_oclose1(c);
207 c->ostate = CHAN_OUTPUT_CLOSED; 219 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
208 break; 220 break;
209 default: 221 default:
210 error("channel %d: internal error: obuf_empty for ostate %d", 222 error("channel %d: internal error: obuf_empty for ostate %d",
@@ -261,8 +273,8 @@ chan_rcvd_oclose2(Channel *c)
261 c->flags |= CHAN_CLOSE_RCVD; 273 c->flags |= CHAN_CLOSE_RCVD;
262 if (c->type == SSH_CHANNEL_LARVAL) { 274 if (c->type == SSH_CHANNEL_LARVAL) {
263 /* tear down larval channels immediately */ 275 /* tear down larval channels immediately */
264 c->ostate = CHAN_OUTPUT_CLOSED; 276 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
265 c->istate = CHAN_INPUT_CLOSED; 277 chan_set_istate(c, CHAN_INPUT_CLOSED);
266 return; 278 return;
267 } 279 }
268 switch (c->ostate) { 280 switch (c->ostate) {
@@ -271,21 +283,18 @@ chan_rcvd_oclose2(Channel *c)
271 * wait until a data from the channel is consumed if a CLOSE 283 * wait until a data from the channel is consumed if a CLOSE
272 * is received 284 * is received
273 */ 285 */
274 debug("channel %d: output open -> drain", c->self); 286 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
275 c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
276 break; 287 break;
277 } 288 }
278 switch (c->istate) { 289 switch (c->istate) {
279 case CHAN_INPUT_OPEN: 290 case CHAN_INPUT_OPEN:
280 debug("channel %d: input open -> closed", c->self);
281 chan_shutdown_read(c); 291 chan_shutdown_read(c);
282 break; 292 break;
283 case CHAN_INPUT_WAIT_DRAIN: 293 case CHAN_INPUT_WAIT_DRAIN:
284 debug("channel %d: input drain -> closed", c->self);
285 chan_send_eof2(c); 294 chan_send_eof2(c);
286 break; 295 break;
287 } 296 }
288 c->istate = CHAN_INPUT_CLOSED; 297 chan_set_istate(c, CHAN_INPUT_CLOSED);
289} 298}
290static void 299static void
291chan_ibuf_empty2(Channel *c) 300chan_ibuf_empty2(Channel *c)
@@ -298,10 +307,9 @@ chan_ibuf_empty2(Channel *c)
298 } 307 }
299 switch (c->istate) { 308 switch (c->istate) {
300 case CHAN_INPUT_WAIT_DRAIN: 309 case CHAN_INPUT_WAIT_DRAIN:
301 debug("channel %d: input drain -> closed", c->self);
302 if (!(c->flags & CHAN_CLOSE_SENT)) 310 if (!(c->flags & CHAN_CLOSE_SENT))
303 chan_send_eof2(c); 311 chan_send_eof2(c);
304 c->istate = CHAN_INPUT_CLOSED; 312 chan_set_istate(c, CHAN_INPUT_CLOSED);
305 break; 313 break;
306 default: 314 default:
307 error("channel %d: chan_ibuf_empty for istate %d", 315 error("channel %d: chan_ibuf_empty for istate %d",
@@ -313,10 +321,8 @@ static void
313chan_rcvd_ieof2(Channel *c) 321chan_rcvd_ieof2(Channel *c)
314{ 322{
315 debug("channel %d: rcvd eof", c->self); 323 debug("channel %d: rcvd eof", c->self);
316 if (c->ostate == CHAN_OUTPUT_OPEN) { 324 if (c->ostate == CHAN_OUTPUT_OPEN)
317 debug("channel %d: output open -> drain", c->self); 325 chan_set_ostate(c, CHAN_OUTPUT_WAIT_DRAIN);
318 c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
319 }
320} 326}
321static void 327static void
322chan_write_failed2(Channel *c) 328chan_write_failed2(Channel *c)
@@ -324,14 +330,12 @@ chan_write_failed2(Channel *c)
324 debug("channel %d: write failed", c->self); 330 debug("channel %d: write failed", c->self);
325 switch (c->ostate) { 331 switch (c->ostate) {
326 case CHAN_OUTPUT_OPEN: 332 case CHAN_OUTPUT_OPEN:
327 debug("channel %d: output open -> closed", c->self);
328 chan_shutdown_write(c); /* ?? */ 333 chan_shutdown_write(c); /* ?? */
329 c->ostate = CHAN_OUTPUT_CLOSED; 334 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
330 break; 335 break;
331 case CHAN_OUTPUT_WAIT_DRAIN: 336 case CHAN_OUTPUT_WAIT_DRAIN:
332 debug("channel %d: output drain -> closed", c->self);
333 chan_shutdown_write(c); 337 chan_shutdown_write(c);
334 c->ostate = CHAN_OUTPUT_CLOSED; 338 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
335 break; 339 break;
336 default: 340 default:
337 error("channel %d: chan_write_failed for ostate %d", 341 error("channel %d: chan_write_failed for ostate %d",
@@ -350,9 +354,8 @@ chan_obuf_empty2(Channel *c)
350 } 354 }
351 switch (c->ostate) { 355 switch (c->ostate) {
352 case CHAN_OUTPUT_WAIT_DRAIN: 356 case CHAN_OUTPUT_WAIT_DRAIN:
353 debug("channel %d: output drain -> closed", c->self);
354 chan_shutdown_write(c); 357 chan_shutdown_write(c);
355 c->ostate = CHAN_OUTPUT_CLOSED; 358 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
356 break; 359 break;
357 default: 360 default:
358 error("channel %d: chan_obuf_empty for ostate %d", 361 error("channel %d: chan_obuf_empty for ostate %d",