diff options
author | Damien Miller <djm@mindrot.org> | 2011-05-15 08:48:05 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2011-05-15 08:48:05 +1000 |
commit | 555f3b856f2681b46870a66386396b49426b9719 (patch) | |
tree | 88756b47f05c76c5afd5ce739aa26a7b3f124809 /mux.c | |
parent | f4b32aad05cb65caa6eabe09049750b3c8a29cf3 (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.c | 60 |
1 files changed, 48 insertions, 12 deletions
@@ -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 | ||
1058 | void | ||
1059 | mux_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. */ |
1058 | void | 1080 | void |
1059 | muxserver_listen(void) | 1081 | muxserver_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); |