summaryrefslogtreecommitdiff
path: root/nchan.c
diff options
context:
space:
mode:
authorBen Lindstrom <mouring@eviladmin.org>2001-06-09 00:57:39 +0000
committerBen Lindstrom <mouring@eviladmin.org>2001-06-09 00:57:39 +0000
commit3b670d09a83d2d625a80e2c61dc206334fb84be4 (patch)
tree73ec4371fcdd24f576c557aa947f41cc2ca6accc /nchan.c
parenta6fc91e86e976905877e448c85eef3509a36fdc4 (diff)
- (bal) Ooops.. nchan.c resync from OpenBSD ssh Attic.
Diffstat (limited to 'nchan.c')
-rw-r--r--nchan.c97
1 files changed, 68 insertions, 29 deletions
diff --git a/nchan.c b/nchan.c
index 3f996f5b8..6871cd86b 100644
--- a/nchan.c
+++ b/nchan.c
@@ -30,10 +30,35 @@ RCSID("$OpenBSD: nchan.c,v 1.28 2001/05/31 10:30:16 markus Exp $");
30#include "buffer.h" 30#include "buffer.h"
31#include "packet.h" 31#include "packet.h"
32#include "channels.h" 32#include "channels.h"
33#include "nchan.h"
34#include "compat.h" 33#include "compat.h"
35#include "log.h" 34#include "log.h"
36 35
36/*
37 * SSH Protocol 1.5 aka New Channel Protocol
38 * Thanks to Martina, Axel and everyone who left Erlangen, leaving me bored.
39 * Written by Markus Friedl in October 1999
40 *
41 * Protocol versions 1.3 and 1.5 differ in the handshake protocol used for the
42 * tear down of channels:
43 *
44 * 1.3: strict request-ack-protocol:
45 * CLOSE ->
46 * <- CLOSE_CONFIRM
47 *
48 * 1.5: uses variations of:
49 * IEOF ->
50 * <- OCLOSE
51 * <- IEOF
52 * OCLOSE ->
53 * i.e. both sides have to close the channel
54 *
55 * 2.0: the EOF messages are optional
56 *
57 * See the debugging output from 'ssh -v' and 'sshd -d' of
58 * ssh-1.2.27 as an example.
59 *
60 */
61
37/* functions manipulating channel states */ 62/* functions manipulating channel states */
38/* 63/*
39 * EVENTS update channel input/output states execute ACTIONS 64 * EVENTS update channel input/output states execute ACTIONS
@@ -84,7 +109,7 @@ chan_rcvd_oclose1(Channel *c)
84 c->istate = CHAN_INPUT_CLOSED; 109 c->istate = CHAN_INPUT_CLOSED;
85 break; 110 break;
86 default: 111 default:
87 error("channel %d: protocol error: chan_rcvd_oclose for istate %d", 112 error("channel %d: protocol error: rcvd_oclose for istate %d",
88 c->self, c->istate); 113 c->self, c->istate);
89 return; 114 return;
90 } 115 }
@@ -98,13 +123,15 @@ chan_read_failed_12(Channel *c)
98 debug("channel %d: input open -> drain", c->self); 123 debug("channel %d: input open -> drain", c->self);
99 chan_shutdown_read(c); 124 chan_shutdown_read(c);
100 c->istate = CHAN_INPUT_WAIT_DRAIN; 125 c->istate = CHAN_INPUT_WAIT_DRAIN;
126#if 0
101 if (buffer_len(&c->input) == 0) { 127 if (buffer_len(&c->input) == 0) {
102 debug("channel %d: input: no drain shortcut", c->self); 128 debug("channel %d: input: no drain shortcut", c->self);
103 chan_ibuf_empty(c); 129 chan_ibuf_empty(c);
104 } 130 }
131#endif
105 break; 132 break;
106 default: 133 default:
107 error("channel %d: internal error: we do not read, but chan_read_failed for istate %d", 134 error("channel %d: chan_read_failed for istate %d",
108 c->self, c->istate); 135 c->self, c->istate);
109 break; 136 break;
110 } 137 }
@@ -114,7 +141,7 @@ chan_ibuf_empty1(Channel *c)
114{ 141{
115 debug("channel %d: ibuf empty", c->self); 142 debug("channel %d: ibuf empty", c->self);
116 if (buffer_len(&c->input)) { 143 if (buffer_len(&c->input)) {
117 error("channel %d: internal error: chan_ibuf_empty for non empty buffer", 144 error("channel %d: chan_ibuf_empty for non empty buffer",
118 c->self); 145 c->self);
119 return; 146 return;
120 } 147 }
@@ -125,7 +152,7 @@ chan_ibuf_empty1(Channel *c)
125 c->istate = CHAN_INPUT_WAIT_OCLOSE; 152 c->istate = CHAN_INPUT_WAIT_OCLOSE;
126 break; 153 break;
127 default: 154 default:
128 error("channel %d: internal error: chan_ibuf_empty for istate %d", 155 error("channel %d: chan_ibuf_empty for istate %d",
129 c->self, c->istate); 156 c->self, c->istate);
130 break; 157 break;
131 } 158 }
@@ -137,19 +164,23 @@ chan_rcvd_ieof1(Channel *c)
137 if (c->type != SSH_CHANNEL_OPEN) { 164 if (c->type != SSH_CHANNEL_OPEN) {
138 debug("channel %d: non-open", c->self); 165 debug("channel %d: non-open", c->self);
139 if (c->istate == CHAN_INPUT_OPEN) { 166 if (c->istate == CHAN_INPUT_OPEN) {
140 debug("channel %d: non-open: input open -> wait_oclose", c->self); 167 debug("channel %d: non-open: input open -> wait_oclose",
168 c->self);
141 chan_shutdown_read(c); 169 chan_shutdown_read(c);
142 chan_send_ieof1(c); 170 chan_send_ieof1(c);
143 c->istate = CHAN_INPUT_WAIT_OCLOSE; 171 c->istate = CHAN_INPUT_WAIT_OCLOSE;
144 } else { 172 } else {
145 error("channel %d: istate %d != open", c->self, c->istate); 173 error("channel %d: non-open: istate %d != open",
174 c->self, c->istate);
146 } 175 }
147 if (c->ostate == CHAN_OUTPUT_OPEN) { 176 if (c->ostate == CHAN_OUTPUT_OPEN) {
148 debug("channel %d: non-open: output open -> closed", c->self); 177 debug("channel %d: non-open: output open -> closed",
178 c->self);
149 chan_send_oclose1(c); 179 chan_send_oclose1(c);
150 c->ostate = CHAN_OUTPUT_CLOSED; 180 c->ostate = CHAN_OUTPUT_CLOSED;
151 } else { 181 } else {
152 error("channel %d: ostate %d != open", c->self, c->ostate); 182 error("channel %d: non-open: ostate %d != open",
183 c->self, c->ostate);
153 } 184 }
154 return; 185 return;
155 } 186 }
@@ -163,7 +194,7 @@ chan_rcvd_ieof1(Channel *c)
163 c->ostate = CHAN_OUTPUT_CLOSED; 194 c->ostate = CHAN_OUTPUT_CLOSED;
164 break; 195 break;
165 default: 196 default:
166 error("channel %d: protocol error: chan_rcvd_ieof for ostate %d", 197 error("channel %d: protocol error: rcvd_ieof for ostate %d",
167 c->self, c->ostate); 198 c->self, c->ostate);
168 break; 199 break;
169 } 200 }
@@ -184,7 +215,7 @@ chan_write_failed1(Channel *c)
184 c->ostate = CHAN_OUTPUT_CLOSED; 215 c->ostate = CHAN_OUTPUT_CLOSED;
185 break; 216 break;
186 default: 217 default:
187 error("channel %d: internal error: chan_write_failed for ostate %d", 218 error("channel %d: chan_write_failed for ostate %d",
188 c->self, c->ostate); 219 c->self, c->ostate);
189 break; 220 break;
190 } 221 }
@@ -194,7 +225,7 @@ chan_obuf_empty1(Channel *c)
194{ 225{
195 debug("channel %d: obuf empty", c->self); 226 debug("channel %d: obuf empty", c->self);
196 if (buffer_len(&c->output)) { 227 if (buffer_len(&c->output)) {
197 error("channel %d: internal error: chan_obuf_empty for non empty buffer", 228 error("channel %d: chan_obuf_empty for non empty buffer",
198 c->self); 229 c->self);
199 return; 230 return;
200 } 231 }
@@ -205,7 +236,7 @@ chan_obuf_empty1(Channel *c)
205 c->ostate = CHAN_OUTPUT_CLOSED; 236 c->ostate = CHAN_OUTPUT_CLOSED;
206 break; 237 break;
207 default: 238 default:
208 error("channel %d: internal error: chan_obuf_empty for ostate %d", 239 error("channel %d: internal error: obuf_empty for ostate %d",
209 c->self, c->ostate); 240 c->self, c->ostate);
210 break; 241 break;
211 } 242 }
@@ -222,7 +253,7 @@ chan_send_ieof1(Channel *c)
222 packet_send(); 253 packet_send();
223 break; 254 break;
224 default: 255 default:
225 error("channel %d: internal error: cannot send ieof for istate %d", 256 error("channel %d: cannot send ieof for istate %d",
226 c->self, c->istate); 257 c->self, c->istate);
227 break; 258 break;
228 } 259 }
@@ -241,7 +272,7 @@ chan_send_oclose1(Channel *c)
241 packet_send(); 272 packet_send();
242 break; 273 break;
243 default: 274 default:
244 error("channel %d: internal error: cannot send oclose for ostate %d", 275 error("channel %d: cannot send oclose for ostate %d",
245 c->self, c->ostate); 276 c->self, c->ostate);
246 break; 277 break;
247 } 278 }
@@ -265,7 +296,10 @@ chan_rcvd_oclose2(Channel *c)
265 } 296 }
266 switch (c->ostate) { 297 switch (c->ostate) {
267 case CHAN_OUTPUT_OPEN: 298 case CHAN_OUTPUT_OPEN:
268 /* wait until a data from the channel is consumed if a CLOSE is received */ 299 /*
300 * wait until a data from the channel is consumed if a CLOSE
301 * is received
302 */
269 debug("channel %d: output open -> drain", c->self); 303 debug("channel %d: output open -> drain", c->self);
270 c->ostate = CHAN_OUTPUT_WAIT_DRAIN; 304 c->ostate = CHAN_OUTPUT_WAIT_DRAIN;
271 break; 305 break;
@@ -287,7 +321,7 @@ chan_ibuf_empty2(Channel *c)
287{ 321{
288 debug("channel %d: ibuf empty", c->self); 322 debug("channel %d: ibuf empty", c->self);
289 if (buffer_len(&c->input)) { 323 if (buffer_len(&c->input)) {
290 error("channel %d: internal error: chan_ibuf_empty for non empty buffer", 324 error("channel %d: chan_ibuf_empty for non empty buffer",
291 c->self); 325 c->self);
292 return; 326 return;
293 } 327 }
@@ -299,7 +333,7 @@ chan_ibuf_empty2(Channel *c)
299 c->istate = CHAN_INPUT_CLOSED; 333 c->istate = CHAN_INPUT_CLOSED;
300 break; 334 break;
301 default: 335 default:
302 error("channel %d: internal error: chan_ibuf_empty for istate %d", 336 error("channel %d: chan_ibuf_empty for istate %d",
303 c->self, c->istate); 337 c->self, c->istate);
304 break; 338 break;
305 } 339 }
@@ -329,7 +363,7 @@ chan_write_failed2(Channel *c)
329 c->ostate = CHAN_OUTPUT_CLOSED; 363 c->ostate = CHAN_OUTPUT_CLOSED;
330 break; 364 break;
331 default: 365 default:
332 error("channel %d: internal error: chan_write_failed for ostate %d", 366 error("channel %d: chan_write_failed for ostate %d",
333 c->self, c->ostate); 367 c->self, c->ostate);
334 break; 368 break;
335 } 369 }
@@ -339,7 +373,7 @@ chan_obuf_empty2(Channel *c)
339{ 373{
340 debug("channel %d: obuf empty", c->self); 374 debug("channel %d: obuf empty", c->self);
341 if (buffer_len(&c->output)) { 375 if (buffer_len(&c->output)) {
342 error("internal error: chan_obuf_empty %d for non empty buffer", 376 error("channel %d: chan_obuf_empty for non empty buffer",
343 c->self); 377 c->self);
344 return; 378 return;
345 } 379 }
@@ -350,7 +384,7 @@ chan_obuf_empty2(Channel *c)
350 c->ostate = CHAN_OUTPUT_CLOSED; 384 c->ostate = CHAN_OUTPUT_CLOSED;
351 break; 385 break;
352 default: 386 default:
353 error("channel %d: internal error: chan_obuf_empty for ostate %d", 387 error("channel %d: chan_obuf_empty for ostate %d",
354 c->self, c->ostate); 388 c->self, c->ostate);
355 break; 389 break;
356 } 390 }
@@ -366,7 +400,7 @@ chan_send_eof2(Channel *c)
366 packet_send(); 400 packet_send();
367 break; 401 break;
368 default: 402 default:
369 error("channel %d: internal error: cannot send eof for istate %d", 403 error("channel %d: cannot send eof for istate %d",
370 c->self, c->istate); 404 c->self, c->istate);
371 break; 405 break;
372 } 406 }
@@ -377,10 +411,10 @@ chan_send_close2(Channel *c)
377 debug("channel %d: send close", c->self); 411 debug("channel %d: send close", c->self);
378 if (c->ostate != CHAN_OUTPUT_CLOSED || 412 if (c->ostate != CHAN_OUTPUT_CLOSED ||
379 c->istate != CHAN_INPUT_CLOSED) { 413 c->istate != CHAN_INPUT_CLOSED) {
380 error("channel %d: internal error: cannot send close for istate/ostate %d/%d", 414 error("channel %d: cannot send close for istate/ostate %d/%d",
381 c->self, c->istate, c->ostate); 415 c->self, c->istate, c->ostate);
382 } else if (c->flags & CHAN_CLOSE_SENT) { 416 } else if (c->flags & CHAN_CLOSE_SENT) {
383 error("channel %d: internal error: already sent close", c->self); 417 error("channel %d: already sent close", c->self);
384 } else { 418 } else {
385 packet_start(SSH2_MSG_CHANNEL_CLOSE); 419 packet_start(SSH2_MSG_CHANNEL_CLOSE);
386 packet_put_int(c->remote_id); 420 packet_put_int(c->remote_id);
@@ -480,11 +514,13 @@ chan_shutdown_write(Channel *c)
480 debug("channel %d: close_write", c->self); 514 debug("channel %d: close_write", c->self);
481 if (c->sock != -1) { 515 if (c->sock != -1) {
482 if (shutdown(c->sock, SHUT_WR) < 0) 516 if (shutdown(c->sock, SHUT_WR) < 0)
483 debug("channel %d: chan_shutdown_write: shutdown() failed for fd%d: %.100s", 517 debug("channel %d: chan_shutdown_write: "
518 "shutdown() failed for fd%d: %.100s",
484 c->self, c->sock, strerror(errno)); 519 c->self, c->sock, strerror(errno));
485 } else { 520 } else {
486 if (close(c->wfd) < 0) 521 if (close(c->wfd) < 0)
487 log("channel %d: chan_shutdown_write: close() failed for fd%d: %.100s", 522 log("channel %d: chan_shutdown_write: "
523 "close() failed for fd%d: %.100s",
488 c->self, c->wfd, strerror(errno)); 524 c->self, c->wfd, strerror(errno));
489 c->wfd = -1; 525 c->wfd = -1;
490 } 526 }
@@ -503,11 +539,14 @@ chan_shutdown_read(Channel *c)
503 */ 539 */
504 if (shutdown(c->sock, SHUT_RD) < 0 540 if (shutdown(c->sock, SHUT_RD) < 0
505 && (errno != ENOTCONN && errno != EINVAL)) 541 && (errno != ENOTCONN && errno != EINVAL))
506 error("channel %d: chan_shutdown_read: shutdown() failed for fd%d [i%d o%d]: %.100s", 542 error("channel %d: chan_shutdown_read: "
507 c->self, c->sock, c->istate, c->ostate, strerror(errno)); 543 "shutdown() failed for fd%d [i%d o%d]: %.100s",
544 c->self, c->sock, c->istate, c->ostate,
545 strerror(errno));
508 } else { 546 } else {
509 if (close(c->rfd) < 0) 547 if (close(c->rfd) < 0)
510 log("channel %d: chan_shutdown_read: close() failed for fd%d: %.100s", 548 log("channel %d: chan_shutdown_read: "
549 "close() failed for fd%d: %.100s",
511 c->self, c->rfd, strerror(errno)); 550 c->self, c->rfd, strerror(errno));
512 c->rfd = -1; 551 c->rfd = -1;
513 } 552 }