From: mouring Date: Wed, 18 Jul 2001 16:01:46 +0000 (+0000) Subject: - markus@cvs.openbsd.org 2001/07/17 21:04:58 X-Git-Tag: V_2_9_9_P1~171 X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/commitdiff_plain/489aa2e90bdb9284a1e76bb90d9e9a9cf7f121e3 - markus@cvs.openbsd.org 2001/07/17 21:04:58 [channels.c channels.h clientloop.c nchan.c serverloop.c] keep track of both maxfd and the size of the malloc'ed fdsets. update maxfd if maxfd gets closed. --- diff --git a/ChangeLog b/ChangeLog index 7c4a5b0e..0dceecbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,10 @@ - markus@cvs.openbsd.org 2001/07/17 20:48:42 [ssh-agent.c] update maxfd if maxfd is closed; report from jmcelroy@dtgnet.com + - markus@cvs.openbsd.org 2001/07/17 21:04:58 + [channels.c channels.h clientloop.c nchan.c serverloop.c] + keep track of both maxfd and the size of the malloc'ed fdsets. + update maxfd if maxfd gets closed. 20010715 - (bal) Set "BROKEN_GETADDRINFO" for darwin platform. Reported by diff --git a/channels.c b/channels.c index 35edff6d..7bf127d9 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.131 2001/07/02 22:52:56 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.132 2001/07/17 21:04:56 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -266,6 +266,37 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, return c; } +static int +channel_find_maxfd(void) +{ + int i, max = 0; + Channel *c; + + for (i = 0; i < channels_alloc; i++) { + c = channels[i]; + if (c != NULL) { + max = MAX(max, c->rfd); + max = MAX(max, c->wfd); + max = MAX(max, c->efd); + } + } + return max; +} + +int +channel_close_fd(int *fdp) +{ + int ret = 0, fd = *fdp; + + if (fd != -1) { + ret = close(fd); + *fdp = -1; + if (fd == channel_max_fd) + channel_max_fd = channel_find_maxfd(); + } + return ret; +} + /* Close all channel fd/socket. */ static void @@ -274,22 +305,10 @@ channel_close_fds(Channel *c) debug3("channel_close_fds: channel %d: r %d w %d e %d", c->self, c->rfd, c->wfd, c->efd); - if (c->sock != -1) { - close(c->sock); - c->sock = -1; - } - if (c->rfd != -1) { - close(c->rfd); - c->rfd = -1; - } - if (c->wfd != -1) { - close(c->wfd); - c->wfd = -1; - } - if (c->efd != -1) { - close(c->efd); - c->efd = -1; - } + channel_close_fd(&c->sock); + channel_close_fd(&c->rfd); + channel_close_fd(&c->wfd); + channel_close_fd(&c->efd); } /* Free the channel and close its fd/socket. */ @@ -387,7 +406,7 @@ channel_stop_listening(void) case SSH_CHANNEL_PORT_LISTENER: case SSH_CHANNEL_RPORT_LISTENER: case SSH_CHANNEL_X11_LISTENER: - close(c->sock); + channel_close_fd(&c->sock); channel_free(c); break; } @@ -842,7 +861,7 @@ channel_pre_x11_open_13(Channel *c, fd_set * readset, fd_set * writeset) log("X11 connection rejected because of wrong authentication."); buffer_clear(&c->input); buffer_clear(&c->output); - close(c->sock); + channel_close_fd(&c->sock); c->sock = -1; c->type = SSH_CHANNEL_CLOSED; packet_start(SSH_MSG_CHANNEL_CLOSE); @@ -1333,8 +1352,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) if (len <= 0) { debug2("channel %d: closing write-efd %d", c->self, c->efd); - close(c->efd); - c->efd = -1; + channel_close_fd(&c->efd); } else { buffer_consume(&c->extended, len); c->local_consumed += len; @@ -1349,8 +1367,7 @@ channel_handle_efd(Channel *c, fd_set * readset, fd_set * writeset) if (len <= 0) { debug2("channel %d: closing read-efd %d", c->self, c->efd); - close(c->efd); - c->efd = -1; + channel_close_fd(&c->efd); } else { buffer_append(&c->extended, buf, len); } @@ -1532,7 +1549,7 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset) */ void channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, - int rekeying) + int *nallocp, int rekeying) { int n; u_int sz; @@ -1540,15 +1557,13 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp, n = MAX(*maxfdp, channel_max_fd); sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); - if (*readsetp == NULL || n > *maxfdp) { - if (*readsetp) - xfree(*readsetp); - if (*writesetp) - xfree(*writesetp); - *readsetp = xmalloc(sz); - *writesetp = xmalloc(sz); - *maxfdp = n; + /* perhaps check sz < nalloc/2 and shrink? */ + if (*readsetp == NULL || sz > *nallocp) { + *readsetp = xrealloc(*readsetp, sz); + *writesetp = xrealloc(*writesetp, sz); + *nallocp = sz; } + *maxfdp = n; memset(*readsetp, 0, sz); memset(*writesetp, 0, sz); diff --git a/channels.h b/channels.h index e4146b59..2ee1496c 100644 --- a/channels.h +++ b/channels.h @@ -32,7 +32,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* RCSID("$OpenBSD: channels.h,v 1.44 2001/07/02 22:52:57 markus Exp $"); */ +/* RCSID("$OpenBSD: channels.h,v 1.45 2001/07/17 21:04:57 markus Exp $"); */ #ifndef CHANNEL_H #define CHANNEL_H @@ -152,6 +152,7 @@ void channel_register_callback(int, int mtype, channel_callback_fn *, void *); void channel_register_cleanup(int, channel_callback_fn *); void channel_register_filter(int, channel_filter_fn *); void channel_cancel_cleanup(int); +int channel_close_fd(int *); /* protocol handler */ @@ -169,7 +170,7 @@ void channel_input_window_adjust(int, int, void *); /* file descriptor handling (read/write) */ -void channel_prepare_select(fd_set **, fd_set **, int *, int); +void channel_prepare_select(fd_set **, fd_set **, int *, int*, int); void channel_after_select(fd_set *, fd_set *); void channel_output_poll(void); diff --git a/clientloop.c b/clientloop.c index 83b2d4d8..41aff835 100644 --- a/clientloop.c +++ b/clientloop.c @@ -59,7 +59,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: clientloop.c,v 1.80 2001/06/30 18:08:40 stevesk Exp $"); +RCSID("$OpenBSD: clientloop.c,v 1.81 2001/07/17 21:04:57 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -318,10 +318,10 @@ client_check_window_change(void) static void client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, - int *maxfdp, int rekeying) + int *maxfdp, int *nallocp, int rekeying) { /* Add any selections by the channel mechanism. */ - channel_prepare_select(readsetp, writesetp, maxfdp, rekeying); + channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, rekeying); if (!compat20) { /* Read from the connection, unless our buffers are full. */ @@ -770,7 +770,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) { fd_set *readset = NULL, *writeset = NULL; double start_time, total_time; - int max_fd = 0, len, rekeying = 0; + int max_fd = 0, max_fd2 = 0, len, rekeying = 0, nalloc = 0; char buf[100]; debug("Entering interactive session."); @@ -877,8 +877,9 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) * Wait until we have something to do (something becomes * available on one of the descriptors). */ + max_fd2 = max_fd; client_wait_until_can_do_something(&readset, &writeset, - &max_fd, rekeying); + &max_fd2, &nalloc, rekeying); if (quit_pending) break; diff --git a/nchan.c b/nchan.c index 8e1be2d3..43d80bf2 100644 --- a/nchan.c +++ b/nchan.c @@ -23,7 +23,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: nchan.c,v 1.30 2001/06/25 08:25:38 markus Exp $"); +RCSID("$OpenBSD: nchan.c,v 1.31 2001/07/17 21:04:57 markus Exp $"); #include "ssh1.h" #include "ssh2.h" @@ -518,11 +518,10 @@ chan_shutdown_write(Channel *c) "shutdown() failed for fd%d: %.100s", c->self, c->sock, strerror(errno)); } else { - if (close(c->wfd) < 0) + if (channel_close_fd(&c->wfd) < 0) log("channel %d: chan_shutdown_write: " "close() failed for fd%d: %.100s", c->self, c->wfd, strerror(errno)); - c->wfd = -1; } } static void @@ -544,10 +543,9 @@ chan_shutdown_read(Channel *c) c->self, c->sock, c->istate, c->ostate, strerror(errno)); } else { - if (close(c->rfd) < 0) + if (channel_close_fd(&c->rfd) < 0) log("channel %d: chan_shutdown_read: " "close() failed for fd%d: %.100s", c->self, c->rfd, strerror(errno)); - c->rfd = -1; } } diff --git a/serverloop.c b/serverloop.c index f826c6cb..d9791274 100644 --- a/serverloop.c +++ b/serverloop.c @@ -35,7 +35,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: serverloop.c,v 1.75 2001/07/15 16:17:08 markus Exp $"); +RCSID("$OpenBSD: serverloop.c,v 1.76 2001/07/17 21:04:58 markus Exp $"); #include "xmalloc.h" #include "packet.h" @@ -169,7 +169,7 @@ make_packets_from_stdout_data(void) */ static void wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, - u_int max_time_milliseconds) + int *nallocp, u_int max_time_milliseconds) { struct timeval tv, *tvp; int ret; @@ -193,7 +193,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp, retry_select: /* Allocate and update select() masks for channel descriptors. */ - channel_prepare_select(readsetp, writesetp, maxfdp, 0); + channel_prepare_select(readsetp, writesetp, maxfdp, nallocp, 0); if (compat20) { /* wrong: bad condition XXX */ @@ -435,7 +435,7 @@ void server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) { fd_set *readset = NULL, *writeset = NULL; - int max_fd; + int max_fd = 0, nalloc = 0; int wait_status; /* Status returned by wait(). */ pid_t wait_pid; /* pid returned by wait(). */ int waiting_termination = 0; /* Have displayed waiting close message. */ @@ -476,12 +476,14 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) else buffer_high = 64 * 1024; +#if 0 /* Initialize max_fd to the maximum of the known file descriptors. */ - max_fd = MAX(fdin, fdout); + max_fd = MAX(connection_in, connection_out); + max_fd = MAX(max_fd, fdin); + max_fd = MAX(max_fd, fdout); if (fderr != -1) max_fd = MAX(max_fd, fderr); - max_fd = MAX(max_fd, connection_in); - max_fd = MAX(max_fd, connection_out); +#endif /* Initialize Initialize buffers. */ buffer_init(&stdin_buffer); @@ -567,9 +569,14 @@ server_loop(pid_t pid, int fdin_arg, int fdout_arg, int fderr_arg) xfree(cp); } } + max_fd = MAX(connection_in, connection_out); + max_fd = MAX(max_fd, fdin); + max_fd = MAX(max_fd, fdout); + max_fd = MAX(max_fd, fderr); + /* Sleep in select() until we can do something. */ wait_until_can_do_something(&readset, &writeset, &max_fd, - max_time_milliseconds); + &nalloc, max_time_milliseconds); /* Process any channel events. */ channel_after_select(readset, writeset); @@ -662,7 +669,7 @@ void server_loop2(Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; - int rekeying = 0, max_fd, status; + int rekeying = 0, max_fd, status, nalloc = 0; pid_t pid; debug("Entering interactive session for SSH2."); @@ -685,7 +692,7 @@ server_loop2(Authctxt *authctxt) if (!rekeying && packet_not_very_much_data_to_write()) channel_output_poll(); wait_until_can_do_something(&readset, &writeset, &max_fd, - rekeying); + &nalloc, 0); if (child_terminated) { while ((pid = waitpid(-1, &status, WNOHANG)) > 0) session_close_by_pid(pid, status);