summaryrefslogtreecommitdiff
path: root/nchan.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2010-01-26 13:26:22 +1100
committerDamien Miller <djm@mindrot.org>2010-01-26 13:26:22 +1100
commite1537f951fa87e4d070adda82b474b25cf4902ec (patch)
tree3c9d794dcf7fca1d880ffd9db24b20038d3f800b /nchan.c
parentf589fd1ea8c352e6bf819733ecd505119a694c51 (diff)
- djm@cvs.openbsd.org 2010/01/26 01:28:35
[channels.c channels.h clientloop.c clientloop.h mux.c nchan.c ssh.c] rewrite ssh(1) multiplexing code to a more sensible protocol. The new multiplexing code uses channels for the listener and accepted control sockets to make the mux master non-blocking, so no stalls when processing messages from a slave. avoid use of fatal() in mux master protocol parsing so an errant slave process cannot take down a running master. implement requesting of port-forwards over multiplexed sessions. Any port forwards requested by the slave are added to those the master has established. add support for stdio forwarding ("ssh -W host:port ...") in mux slaves. document master/slave mux protocol so that other tools can use it to control a running ssh(1). Note: there are no guarantees that this protocol won't be incompatibly changed (though it is versioned). feedback Salvador Fandino, dtucker@ channel changes ok markus@
Diffstat (limited to 'nchan.c')
-rw-r--r--nchan.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/nchan.c b/nchan.c
index 160445e5a..20f6a2f49 100644
--- a/nchan.c
+++ b/nchan.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: nchan.c,v 1.62 2008/11/07 18:50:18 stevesk Exp $ */ 1/* $OpenBSD: nchan.c,v 1.63 2010/01/26 01:28:35 djm Exp $ */
2/* 2/*
3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. 3 * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
4 * 4 *
@@ -161,7 +161,7 @@ chan_ibuf_empty(Channel *c)
161 switch (c->istate) { 161 switch (c->istate) {
162 case CHAN_INPUT_WAIT_DRAIN: 162 case CHAN_INPUT_WAIT_DRAIN:
163 if (compat20) { 163 if (compat20) {
164 if (!(c->flags & CHAN_CLOSE_SENT)) 164 if (!(c->flags & (CHAN_CLOSE_SENT|CHAN_LOCAL)))
165 chan_send_eof2(c); 165 chan_send_eof2(c);
166 chan_set_istate(c, CHAN_INPUT_CLOSED); 166 chan_set_istate(c, CHAN_INPUT_CLOSED);
167 } else { 167 } else {
@@ -278,9 +278,12 @@ static void
278chan_rcvd_close2(Channel *c) 278chan_rcvd_close2(Channel *c)
279{ 279{
280 debug2("channel %d: rcvd close", c->self); 280 debug2("channel %d: rcvd close", c->self);
281 if (c->flags & CHAN_CLOSE_RCVD) 281 if (!(c->flags & CHAN_LOCAL)) {
282 error("channel %d: protocol error: close rcvd twice", c->self); 282 if (c->flags & CHAN_CLOSE_RCVD)
283 c->flags |= CHAN_CLOSE_RCVD; 283 error("channel %d: protocol error: close rcvd twice",
284 c->self);
285 c->flags |= CHAN_CLOSE_RCVD;
286 }
284 if (c->type == SSH_CHANNEL_LARVAL) { 287 if (c->type == SSH_CHANNEL_LARVAL) {
285 /* tear down larval channels immediately */ 288 /* tear down larval channels immediately */
286 chan_set_ostate(c, CHAN_OUTPUT_CLOSED); 289 chan_set_ostate(c, CHAN_OUTPUT_CLOSED);
@@ -302,11 +305,13 @@ chan_rcvd_close2(Channel *c)
302 chan_set_istate(c, CHAN_INPUT_CLOSED); 305 chan_set_istate(c, CHAN_INPUT_CLOSED);
303 break; 306 break;
304 case CHAN_INPUT_WAIT_DRAIN: 307 case CHAN_INPUT_WAIT_DRAIN:
305 chan_send_eof2(c); 308 if (!(c->flags & CHAN_LOCAL))
309 chan_send_eof2(c);
306 chan_set_istate(c, CHAN_INPUT_CLOSED); 310 chan_set_istate(c, CHAN_INPUT_CLOSED);
307 break; 311 break;
308 } 312 }
309} 313}
314
310void 315void
311chan_rcvd_eow(Channel *c) 316chan_rcvd_eow(Channel *c)
312{ 317{
@@ -454,6 +459,10 @@ chan_is_dead(Channel *c, int do_send)
454 c->self, c->efd, buffer_len(&c->extended)); 459 c->self, c->efd, buffer_len(&c->extended));
455 return 0; 460 return 0;
456 } 461 }
462 if (c->flags & CHAN_LOCAL) {
463 debug2("channel %d: is dead (local)", c->self);
464 return 1;
465 }
457 if (!(c->flags & CHAN_CLOSE_SENT)) { 466 if (!(c->flags & CHAN_CLOSE_SENT)) {
458 if (do_send) { 467 if (do_send) {
459 chan_send_close2(c); 468 chan_send_close2(c);