Improve handling lots of concurrent forwarded connections. Increase

connection backlog, avoid check_close() for channels that haven't had IO
This commit is contained in:
Matt Johnston 2014-06-25 23:42:39 +08:00
parent 6b5317e7cc
commit ca86726f9f
3 changed files with 17 additions and 4 deletions

View File

@ -208,11 +208,14 @@ struct Channel* getchannel() {
/* Iterate through the channels, performing IO if available */ /* Iterate through the channels, performing IO if available */
void channelio(fd_set *readfds, fd_set *writefds) { void channelio(fd_set *readfds, fd_set *writefds) {
/* Listeners such as TCP, X11, agent-auth */
struct Channel *channel; struct Channel *channel;
unsigned int i; unsigned int i;
/* foreach channel */ /* foreach channel */
for (i = 0; i < ses.chansize; i++) { 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]; channel = ses.channels[i];
if (channel == NULL) { if (channel == NULL) {
@ -224,6 +227,7 @@ void channelio(fd_set *readfds, fd_set *writefds) {
if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) { if (channel->readfd >= 0 && FD_ISSET(channel->readfd, readfds)) {
TRACE(("send normal readfd")) TRACE(("send normal readfd"))
send_msg_channel_data(channel, 0); send_msg_channel_data(channel, 0);
do_check_close = 1;
} }
/* read stderr data and send it over the wire */ /* 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)) { && FD_ISSET(channel->errfd, readfds)) {
TRACE(("send normal errfd")) TRACE(("send normal errfd"))
send_msg_channel_data(channel, 1); send_msg_channel_data(channel, 1);
do_check_close = 1;
} }
/* write to program/pipe stdin */ /* 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 */ check_in_progress(), as it may be NULL */
} }
writechannel(channel, channel->writefd, channel->writebuf); writechannel(channel, channel->writefd, channel->writebuf);
do_check_close = 1;
} }
/* stderr for client mode */ /* stderr for client mode */
if (ERRFD_IS_WRITE(channel) if (ERRFD_IS_WRITE(channel)
&& channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) { && channel->errfd >= 0 && FD_ISSET(channel->errfd, writefds)) {
writechannel(channel, channel->errfd, channel->extrabuf); writechannel(channel, channel->errfd, channel->extrabuf);
do_check_close = 1;
} }
/* handle any channel closing etc */ /* 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 #ifdef USING_LISTENERS
handle_listeners(readfds); handle_listeners(readfds);
#endif #endif

View File

@ -332,7 +332,7 @@ int dropbear_listen(const char* address, const char* port,
continue; continue;
} }
if (listen(sock, 20) < 0) { if (listen(sock, DROPBEAR_LISTEN_BACKLOG) < 0) {
err = errno; err = errno;
close(sock); close(sock);
TRACE(("listen() failed")) TRACE(("listen() failed"))

View File

@ -251,4 +251,10 @@
#define USE_VFORK #define USE_VFORK
#endif /* don't HAVE_FORK */ #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 */ /* no include guard for this file */