summaryrefslogtreecommitdiff
path: root/mux.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2011-05-15 08:48:05 +1000
committerDamien Miller <djm@mindrot.org>2011-05-15 08:48:05 +1000
commit555f3b856f2681b46870a66386396b49426b9719 (patch)
tree88756b47f05c76c5afd5ce739aa26a7b3f124809 /mux.c
parentf4b32aad05cb65caa6eabe09049750b3c8a29cf3 (diff)
- djm@cvs.openbsd.org 2011/05/08 12:52:01
[PROTOCOL.mux clientloop.c clientloop.h mux.c] improve our behaviour when TTY allocation fails: if we are in RequestTTY=auto mode (the default), then do not treat at TTY allocation error as fatal but rather just restore the local TTY to cooked mode and continue. This is more graceful on devices that never allocate TTYs. If RequestTTY is set to "yes" or "force", then failure to allocate a TTY is fatal. ok markus@
Diffstat (limited to 'mux.c')
-rw-r--r--mux.c60
1 files changed, 48 insertions, 12 deletions
diff --git a/mux.c b/mux.c
index 1afd1bdf3..101d7524b 100644
--- a/mux.c
+++ b/mux.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: mux.c,v 1.27 2011/05/06 21:34:32 djm Exp $ */ 1/* $OpenBSD: mux.c,v 1.28 2011/05/08 12:52:01 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -153,6 +153,7 @@ struct mux_master_state {
153#define MUX_S_ALIVE 0x80000005 153#define MUX_S_ALIVE 0x80000005
154#define MUX_S_SESSION_OPENED 0x80000006 154#define MUX_S_SESSION_OPENED 0x80000006
155#define MUX_S_REMOTE_PORT 0x80000007 155#define MUX_S_REMOTE_PORT 0x80000007
156#define MUX_S_TTY_ALLOC_FAIL 0x80000008
156 157
157/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */ 158/* type codes for MUX_C_OPEN_FWD and MUX_C_CLOSE_FWD */
158#define MUX_FWD_LOCAL 1 159#define MUX_FWD_LOCAL 1
@@ -1054,6 +1055,27 @@ mux_exit_message(Channel *c, int exitval)
1054 buffer_free(&m); 1055 buffer_free(&m);
1055} 1056}
1056 1057
1058void
1059mux_tty_alloc_failed(Channel *c)
1060{
1061 Buffer m;
1062 Channel *mux_chan;
1063
1064 debug3("%s: channel %d: TTY alloc failed", __func__, c->self);
1065
1066 if ((mux_chan = channel_by_id(c->ctl_chan)) == NULL)
1067 fatal("%s: channel %d missing mux channel %d",
1068 __func__, c->self, c->ctl_chan);
1069
1070 /* Append exit message packet to control socket output queue */
1071 buffer_init(&m);
1072 buffer_put_int(&m, MUX_S_TTY_ALLOC_FAIL);
1073 buffer_put_int(&m, c->self);
1074
1075 buffer_put_string(&mux_chan->output, buffer_ptr(&m), buffer_len(&m));
1076 buffer_free(&m);
1077}
1078
1057/* Prepare a mux master to listen on a Unix domain socket. */ 1079/* Prepare a mux master to listen on a Unix domain socket. */
1058void 1080void
1059muxserver_listen(void) 1081muxserver_listen(void)
@@ -1612,7 +1634,7 @@ mux_client_request_session(int fd)
1612 char *e, *term; 1634 char *e, *term;
1613 u_int i, rid, sid, esid, exitval, type, exitval_seen; 1635 u_int i, rid, sid, esid, exitval, type, exitval_seen;
1614 extern char **environ; 1636 extern char **environ;
1615 int devnull; 1637 int devnull, rawmode;
1616 1638
1617 debug3("%s: entering", __func__); 1639 debug3("%s: entering", __func__);
1618 1640
@@ -1708,6 +1730,7 @@ mux_client_request_session(int fd)
1708 signal(SIGTERM, control_client_sighandler); 1730 signal(SIGTERM, control_client_sighandler);
1709 signal(SIGWINCH, control_client_sigrelay); 1731 signal(SIGWINCH, control_client_sigrelay);
1710 1732
1733 rawmode = tty_flag;
1711 if (tty_flag) 1734 if (tty_flag)
1712 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1735 enter_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1713 1736
@@ -1723,22 +1746,35 @@ mux_client_request_session(int fd)
1723 if (mux_client_read_packet(fd, &m) != 0) 1746 if (mux_client_read_packet(fd, &m) != 0)
1724 break; 1747 break;
1725 type = buffer_get_int(&m); 1748 type = buffer_get_int(&m);
1726 if (type != MUX_S_EXIT_MESSAGE) { 1749 switch (type) {
1750 case MUX_S_TTY_ALLOC_FAIL:
1751 if ((esid = buffer_get_int(&m)) != sid)
1752 fatal("%s: tty alloc fail on unknown session: "
1753 "my id %u theirs %u",
1754 __func__, sid, esid);
1755 leave_raw_mode(options.request_tty ==
1756 REQUEST_TTY_FORCE);
1757 rawmode = 0;
1758 continue;
1759 case MUX_S_EXIT_MESSAGE:
1760 if ((esid = buffer_get_int(&m)) != sid)
1761 fatal("%s: exit on unknown session: "
1762 "my id %u theirs %u",
1763 __func__, sid, esid);
1764 if (exitval_seen)
1765 fatal("%s: exitval sent twice", __func__);
1766 exitval = buffer_get_int(&m);
1767 exitval_seen = 1;
1768 continue;
1769 default:
1727 e = buffer_get_string(&m, NULL); 1770 e = buffer_get_string(&m, NULL);
1728 fatal("%s: master returned error: %s", __func__, e); 1771 fatal("%s: master returned error: %s", __func__, e);
1729 } 1772 }
1730 if ((esid = buffer_get_int(&m)) != sid)
1731 fatal("%s: exit on unknown session: my id %u theirs %u",
1732 __func__, sid, esid);
1733 debug("%s: master session id: %u", __func__, sid);
1734 if (exitval_seen)
1735 fatal("%s: exitval sent twice", __func__);
1736 exitval = buffer_get_int(&m);
1737 exitval_seen = 1;
1738 } 1773 }
1739 1774
1740 close(fd); 1775 close(fd);
1741 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE); 1776 if (rawmode)
1777 leave_raw_mode(options.request_tty == REQUEST_TTY_FORCE);
1742 1778
1743 if (muxclient_terminate) { 1779 if (muxclient_terminate) {
1744 debug2("Exiting on signal %d", muxclient_terminate); 1780 debug2("Exiting on signal %d", muxclient_terminate);