diff options
author | Markus Friedl <markus@cvs.openbsd.org> | 2008-05-09 16:21:14 +0000 |
---|---|---|
committer | Markus Friedl <markus@cvs.openbsd.org> | 2008-05-09 16:21:14 +0000 |
commit | 23d2fc67f7eb4201b60e46921bd1b7079647b0d5 (patch) | |
tree | 4d45a7793813f77892b043d6287951664a35e03a | |
parent | 56f008890300a5261447bedef6b2d884ff84bc2a (diff) |
unbreak
ssh -2 localhost od /bin/ls | true
ignoring SIGPIPE by adding a new channel message (EOW) that signals
the peer that we're not interested in any data it might send.
fixes bz #85; discussion, debugging and ok djm@
-rw-r--r-- | usr.bin/ssh/channels.h | 3 | ||||
-rw-r--r-- | usr.bin/ssh/clientloop.c | 5 | ||||
-rw-r--r-- | usr.bin/ssh/nchan.c | 30 | ||||
-rw-r--r-- | usr.bin/ssh/serverloop.c | 7 |
4 files changed, 40 insertions, 5 deletions
diff --git a/usr.bin/ssh/channels.h b/usr.bin/ssh/channels.h index c1807df4c1e..e3c77a1ed9e 100644 --- a/usr.bin/ssh/channels.h +++ b/usr.bin/ssh/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.91 2008/05/09 04:55:56 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.92 2008/05/09 16:21:13 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> @@ -266,6 +266,7 @@ void chan_mark_dead(Channel *); /* channel events */ void chan_rcvd_oclose(Channel *); +void chan_rcvd_eow(Channel *); /* SSH2-only */ void chan_read_failed(Channel *); void chan_ibuf_empty(Channel *); diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 49177709014..2a0f186d61a 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.192 2008/05/09 14:18:44 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.193 2008/05/09 16:21:13 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1652,6 +1652,9 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) error("client_input_channel_req: request for channel -1"); } else if ((c = channel_lookup(id)) == NULL) { error("client_input_channel_req: channel %d: unknown channel", id); + } else if (strcmp(rtype, "eow@openssh.com") == 0) { + packet_check_eom(); + chan_rcvd_eow(c); } else if (strcmp(rtype, "exit-status") == 0) { exitval = packet_get_int(); if (id == session_ident) { diff --git a/usr.bin/ssh/nchan.c b/usr.bin/ssh/nchan.c index 78a83101460..1b62edc9c2a 100644 --- a/usr.bin/ssh/nchan.c +++ b/usr.bin/ssh/nchan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nchan.c,v 1.58 2008/05/08 12:02:23 djm Exp $ */ +/* $OpenBSD: nchan.c,v 1.59 2008/05/09 16:21:13 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -76,6 +76,7 @@ static void chan_send_ieof1(Channel *); static void chan_send_oclose1(Channel *); static void chan_send_close2(Channel *); static void chan_send_eof2(Channel *); +static void chan_send_eow2(Channel *); /* helper */ static void chan_shutdown_write(Channel *); @@ -304,6 +305,17 @@ chan_rcvd_close2(Channel *c) break; } } +void +chan_rcvd_eow(Channel *c) +{ + debug2("channel %d: rcvd eow", c->self); + switch (c->istate) { + case CHAN_INPUT_OPEN: + chan_shutdown_read(c); + chan_set_istate(c, CHAN_INPUT_CLOSED); + break; + } +} static void chan_rcvd_eof2(Channel *c) { @@ -320,6 +332,7 @@ chan_write_failed2(Channel *c) case CHAN_OUTPUT_OPEN: case CHAN_OUTPUT_WAIT_DRAIN: chan_shutdown_write(c); + chan_send_eow2(c); chan_set_ostate(c, CHAN_OUTPUT_CLOSED); break; default: @@ -362,6 +375,21 @@ chan_send_close2(Channel *c) c->flags |= CHAN_CLOSE_SENT; } } +static void +chan_send_eow2(Channel *c) +{ + debug2("channel %d: send eow", c->self); + if (c->ostate == CHAN_OUTPUT_CLOSED) { + error("channel %d: must not sent eow on closed output", + c->self); + return; + } + packet_start(SSH2_MSG_CHANNEL_REQUEST); + packet_put_int(c->remote_id); + packet_put_cstring("eow@openssh.com"); + packet_put_char(0); + packet_send(); +} /* shared */ diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index 5a72730e989..225a8657ce4 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.150 2008/05/09 04:55:56 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.151 2008/05/09 16:21:13 markus Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1122,7 +1122,10 @@ server_input_channel_req(int type, u_int32_t seq, void *ctxt) if ((c = channel_lookup(id)) == NULL) packet_disconnect("server_input_channel_req: " "unknown channel %d", id); - if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) + if (!strcmp(rtype, "eow@openssh.com")) { + packet_check_eom(); + chan_rcvd_eow(c); + } else if (c->type == SSH_CHANNEL_LARVAL || c->type == SSH_CHANNEL_OPEN) success = session_input_channel_req(c, rtype); if (reply) { packet_start(success ? |