diff options
Diffstat (limited to 'nchan.c')
-rw-r--r-- | nchan.c | 83 |
1 files changed, 43 insertions, 40 deletions
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: nchan.c,v 1.36 2002/01/10 12:47:59 markus Exp $"); | 26 | RCSID("$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 *); | |||
83 | static void chan_shutdown_write(Channel *); | 83 | static void chan_shutdown_write(Channel *); |
84 | static void chan_shutdown_read(Channel *); | 84 | static void chan_shutdown_read(Channel *); |
85 | 85 | ||
86 | static char *ostates[] = { "open", "drain", "wait_ieof", "closed" }; | ||
87 | static char *istates[] = { "open", "drain", "wait_oclose", "closed" }; | ||
88 | |||
89 | static void | ||
90 | chan_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 | } | ||
98 | static void | ||
99 | chan_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 | } |
290 | static void | 299 | static void |
291 | chan_ibuf_empty2(Channel *c) | 300 | chan_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 | |||
313 | chan_rcvd_ieof2(Channel *c) | 321 | chan_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 | } |
321 | static void | 327 | static void |
322 | chan_write_failed2(Channel *c) | 328 | chan_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", |