diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | channels.h | 22 | ||||
-rw-r--r-- | nchan.c | 83 |
3 files changed, 59 insertions, 52 deletions
@@ -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 | ||
164 | 20020121 | 168 | 20020121 |
@@ -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 |
@@ -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", |