From ca86726f9f943b2b18e5694b442d3d2e1c0fa903 Mon Sep 17 00:00:00 2001 From: Matt Johnston <matt@ucc.asn.au> Date: Wed, 25 Jun 2014 23:42:39 +0800 Subject: [PATCH] Improve handling lots of concurrent forwarded connections. Increase connection backlog, avoid check_close() for channels that haven't had IO --- common-channel.c | 13 ++++++++++--- dbutil.c | 2 +- sysoptions.h | 6 ++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/common-channel.c b/common-channel.c index 91629809..62e4be1c 100644 --- a/common-channel.c +++ b/common-channel.c @@ -208,11 +208,14 @@ struct Channel* getchannel() { /* Iterate through the channels, performing IO if available */ void channelio(fd_set *readfds, fd_set *writefds) { + /* Listeners such as TCP, X11, agent-auth */ struct Channel *channel; unsigned int i; /* foreach channel */ for (i = 0; i < ses.chansize; i++) { + /* Close checking only needs to occur for channels that had IO events */ + int do_check_close = 0; channel = ses.channels[i]; if (channel == NULL) { @@ -224,6 +227,7 @@ void channelio(fd_set *readfds, fd_set *writefds) { if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) { TRACE(("send normal readfd")) send_msg_channel_data(channel, 0); + do_check_close = 1; } /* read stderr data and send it over the wire */ @@ -231,6 +235,7 @@ void channelio(fd_set *readfds, fd_set *writefds) { && FD_ISSET(channel->errfd, readfds)) { TRACE(("send normal errfd")) send_msg_channel_data(channel, 1); + do_check_close = 1; } /* write to program/pipe stdin */ @@ -242,20 +247,22 @@ void channelio(fd_set *readfds, fd_set *writefds) { check_in_progress(), as it may be NULL */ } writechannel(channel, channel->writefd, channel->writebuf); + do_check_close = 1; } /* stderr for client mode */ if (ERRFD_IS_WRITE(channel) && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) { writechannel(channel, channel->errfd, channel->extrabuf); + do_check_close = 1; } /* handle any channel closing etc */ - check_close(channel); - + if (do_check_close) { + check_close(channel); + } } - /* Listeners such as TCP, X11, agent-auth */ #ifdef USING_LISTENERS handle_listeners(readfds); #endif diff --git a/dbutil.c b/dbutil.c index 145bc332..2ea52ace 100644 --- a/dbutil.c +++ b/dbutil.c @@ -332,7 +332,7 @@ int dropbear_listen(const char* address, const char* port, continue; } - if (listen(sock, 20) < 0) { + if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0) { err = errno; close(sock); TRACE(("listen() failed")) diff --git a/sysoptions.h b/sysoptions.h index a587762f..8a359fb5 100644 --- a/sysoptions.h +++ b/sysoptions.h @@ -251,4 +251,10 @@ #define USE_VFORK #endif /* don't HAVE_FORK */ +#if MAX_UNAUTH_CLIENTS > MAX_CHANNELS +#define DROPBEAR_LISTEN_BACKLOG MAX_UNAUTH_CLIENTS +#else +#define DROPBEAR_LISTEN_BACKLOG MAX_CHANNELS +#endif + /* no include guard for this file */ -- GitLab