# HG changeset patch # User Matt Johnston # Date 1633938134 -28800 # Node ID a7cc3332d8abea9dc420c2b4b9b2ffb2b627c4a8 # Parent 3f0ac6bc58a180ed2e2cd0bbe0807d4b8d0cbdea Replace ChanType.sepfds with Channel.bidir_fd This handles the case where a svrchansess has separate FDs for nopty, but a single FD for pty mode. The use of sepfds was also previously incorrect for X11 and agent forwarding diff -r 3f0ac6bc58a1 -r a7cc3332d8ab channel.h --- a/channel.h Mon Oct 11 15:16:54 2021 +0800 +++ b/channel.h Mon Oct 11 15:42:14 2021 +0800 @@ -60,6 +60,9 @@ int readfd; /* read from insecure side, written to wire */ int errfd; /* used like writefd or readfd, depending if it's client or server. Doesn't exactly belong here, but is cleaner here */ + int bidir_fd; /* a boolean indicating that writefd/readfd are the same + file descriptor (bidirectional), such as a network socket or PTY. + That is handled differently when closing FDs */ circbuffer *writebuf; /* data from the wire, for local consumption. Can be initially NULL */ circbuffer *extrabuf; /* extended-data for the program - used like writebuf @@ -87,7 +90,6 @@ struct ChanType { - int sepfds; /* Whether this channel has separate pipes for in/out or not */ const char *name; /* Sets up the channel */ int (*inithandler)(struct Channel*); diff -r 3f0ac6bc58a1 -r a7cc3332d8ab cli-agentfwd.c --- a/cli-agentfwd.c Mon Oct 11 15:16:54 2021 +0800 +++ b/cli-agentfwd.c Mon Oct 11 15:42:14 2021 +0800 @@ -47,7 +47,6 @@ static int new_agent_chan(struct Channel * channel); const struct ChanType cli_chan_agent = { - 0, /* sepfds */ "auth-agent@openssh.com", new_agent_chan, NULL, @@ -94,6 +93,7 @@ channel->readfd = fd; channel->writefd = fd; + channel->bidir_fd = 1; return 0; } diff -r 3f0ac6bc58a1 -r a7cc3332d8ab cli-chansession.c --- a/cli-chansession.c Mon Oct 11 15:16:54 2021 +0800 +++ b/cli-chansession.c Mon Oct 11 15:42:14 2021 +0800 @@ -46,7 +46,6 @@ static void cli_tty_setup(void); const struct ChanType clichansess = { - 0, /* sepfds */ "session", /* name */ cli_initchansess, /* inithandler */ NULL, /* checkclosehandler */ @@ -344,6 +343,7 @@ setnonblocking(STDERR_FILENO); channel->extrabuf = cbuf_new(opts.recv_window); + channel->bidir_fd = 0; return 0; } @@ -383,7 +383,6 @@ #if DROPBEAR_CLI_NETCAT static const struct ChanType cli_chan_netcat = { - 0, /* sepfds */ "direct-tcpip", cli_init_netcat, /* inithandler */ NULL, diff -r 3f0ac6bc58a1 -r a7cc3332d8ab cli-tcpfwd.c --- a/cli-tcpfwd.c Mon Oct 11 15:16:54 2021 +0800 +++ b/cli-tcpfwd.c Mon Oct 11 15:42:14 2021 +0800 @@ -35,7 +35,6 @@ static int newtcpforwarded(struct Channel * channel); const struct ChanType cli_chan_tcpremote = { - 1, /* sepfds */ "forwarded-tcpip", newtcpforwarded, NULL, @@ -51,7 +50,6 @@ const char* remoteaddr, unsigned int remoteport); static const struct ChanType cli_chan_tcplocal = { - 1, /* sepfds */ "direct-tcpip", tcp_prio_inithandler, NULL, @@ -275,10 +273,10 @@ } channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE; - + snprintf(portstring, sizeof(portstring), "%u", fwd->connectport); channel->conn_pending = connect_remote(fwd->connectaddr, portstring, channel_connect_done, channel, NULL, NULL); - + err = SSH_OPEN_IN_PROGRESS; out: diff -r 3f0ac6bc58a1 -r a7cc3332d8ab common-channel.c --- a/common-channel.c Mon Oct 11 15:16:54 2021 +0800 +++ b/common-channel.c Mon Oct 11 15:42:14 2021 +0800 @@ -339,6 +339,7 @@ if (result == DROPBEAR_SUCCESS) { channel->readfd = channel->writefd = sock; + channel->bidir_fd = 1; channel->conn_pending = NULL; send_msg_channel_open_confirmation(channel, channel->recvwindow, channel->recvmaxpacket); @@ -1039,7 +1040,7 @@ int closein = 0, closeout = 0; - if (channel->type->sepfds) { + if (channel->bidir_fd) { TRACE(("SHUTDOWN(%d, %d)", fd, how)) shutdown(fd, how); if (how == 0) { @@ -1069,7 +1070,7 @@ /* if we called shutdown on it and all references are gone, then we * need to close() it to stop it lingering */ - if (channel->type->sepfds && channel->readfd == FD_CLOSED + if (channel->bidir_fd && channel->readfd == FD_CLOSED && channel->writefd == FD_CLOSED && channel->errfd == FD_CLOSED) { TRACE(("CLOSE (finally) of %d", fd)) m_close(fd); @@ -1102,6 +1103,7 @@ chan->writefd = chan->readfd = fd; ses.maxfd = MAX(ses.maxfd, fd); + chan->bidir_fd = 1; chan->await_open = 1; diff -r 3f0ac6bc58a1 -r a7cc3332d8ab svr-agentfwd.c --- a/svr-agentfwd.c Mon Oct 11 15:16:54 2021 +0800 +++ b/svr-agentfwd.c Mon Oct 11 15:42:14 2021 +0800 @@ -186,7 +186,6 @@ } static const struct ChanType chan_svr_agent = { - 0, /* sepfds */ "auth-agent@openssh.com", NULL, NULL, diff -r 3f0ac6bc58a1 -r a7cc3332d8ab svr-chansession.c --- a/svr-chansession.c Mon Oct 11 15:16:54 2021 +0800 +++ b/svr-chansession.c Mon Oct 11 15:42:14 2021 +0800 @@ -64,7 +64,6 @@ static void get_termmodes(const struct ChanSess *chansess); const struct ChanType svrchansess = { - 0, /* sepfds */ "session", /* name */ newchansess, /* inithandler */ sesscheckclose, /* checkclosehandler */ @@ -769,6 +768,7 @@ ses.maxfd = MAX(ses.maxfd, channel->writefd); ses.maxfd = MAX(ses.maxfd, channel->readfd); ses.maxfd = MAX(ses.maxfd, channel->errfd); + channel->bidir_fd = 0; addchildpid(chansess, chansess->pid); @@ -895,6 +895,7 @@ channel->readfd = chansess->master; /* don't need to set stderr here */ ses.maxfd = MAX(ses.maxfd, chansess->master); + channel->bidir_fd = 1; setnonblocking(chansess->master); diff -r 3f0ac6bc58a1 -r a7cc3332d8ab svr-tcpfwd.c --- a/svr-tcpfwd.c Mon Oct 11 15:16:54 2021 +0800 +++ b/svr-tcpfwd.c Mon Oct 11 15:42:14 2021 +0800 @@ -59,7 +59,6 @@ #if DROPBEAR_SVR_REMOTETCPFWD static const struct ChanType svr_chan_tcpremote = { - 1, /* sepfds */ "forwarded-tcpip", tcp_prio_inithandler, NULL, @@ -241,7 +240,6 @@ #if DROPBEAR_SVR_LOCALTCPFWD const struct ChanType svr_chan_tcpdirect = { - 1, /* sepfds */ "direct-tcpip", newtcpdirect, /* init */ NULL, /* checkclose */ diff -r 3f0ac6bc58a1 -r a7cc3332d8ab svr-x11fwd.c --- a/svr-x11fwd.c Mon Oct 11 15:16:54 2021 +0800 +++ b/svr-x11fwd.c Mon Oct 11 15:42:14 2021 +0800 @@ -211,7 +211,6 @@ } static const struct ChanType chan_x11 = { - 0, /* sepfds */ "x11", x11_inithandler, /* inithandler */ NULL, /* checkclose */