diff options
-rw-r--r-- | cli-chansession.c | 2 | ||||
-rw-r--r-- | cli-runopts.c | 17 | ||||
-rw-r--r-- | common-channel.c | 11 | ||||
-rw-r--r-- | dbclient.1 | 5 | ||||
-rw-r--r-- | dropbear.8 | 5 | ||||
-rw-r--r-- | options.h | 8 | ||||
-rw-r--r-- | runopts.h | 1 | ||||
-rw-r--r-- | svr-runopts.c | 19 |
8 files changed, 56 insertions, 12 deletions
diff --git a/cli-chansession.c b/cli-chansession.c index e4ec45c..c92f902 100644 --- a/cli-chansession.c +++ b/cli-chansession.c @@ -350,7 +350,7 @@ static int cli_initchansess(struct Channel *channel) { channel->errfd = STDERR_FILENO; setnonblocking(STDERR_FILENO); - channel->extrabuf = cbuf_new(RECV_MAX_WINDOW); + channel->extrabuf = cbuf_new(opts.recv_window); if (cli_opts.wantpty) { send_chansess_pty_req(channel); diff --git a/cli-runopts.c b/cli-runopts.c index 3e9b5ab..f38ccd2 100644 --- a/cli-runopts.c +++ b/cli-runopts.c @@ -63,10 +63,11 @@ static void printhelp() { #ifdef ENABLE_CLI_REMOTETCPFWD "-R <listenport:remotehost:remoteport> Remote port forwarding\n" #endif + "-W <receive_window_buffer> (default %d, larger may be faster)\n" #ifdef DEBUG_TRACE "-v verbose\n" #endif - ,DROPBEAR_VERSION, cli_opts.progname); + ,DROPBEAR_VERSION, cli_opts.progname, DEFAULT_RECV_WINDOW); } void cli_getopts(int argc, char ** argv) { @@ -109,6 +110,8 @@ void cli_getopts(int argc, char ** argv) { opts.ipv4 = 1; opts.ipv6 = 1; */ + opts.recv_window = DEFAULT_RECV_WINDOW; + char* recv_window_arg = NULL; /* Iterate all the arguments */ for (i = 1; i < (unsigned int)argc; i++) { @@ -201,6 +204,9 @@ void cli_getopts(int argc, char ** argv) { case 'u': /* backwards compatibility with old urandom option */ break; + case 'W': + next = &recv_window_arg; + break; #ifdef DEBUG_TRACE case 'v': debug_trace = 1; @@ -292,6 +298,15 @@ void cli_getopts(int argc, char ** argv) { && cli_opts.no_cmd == 0) { dropbear_exit("command required for -f"); } + + if (recv_window_arg) + { + opts.recv_window = atol(recv_window_arg); + if (opts.recv_window == 0) + { + dropbear_exit("Bad recv window '%s'", recv_window_arg); + } + } } #ifdef ENABLE_CLI_PUBKEY_AUTH diff --git a/common-channel.c b/common-channel.c index ed6e5a2..97fd4a8 100644 --- a/common-channel.c +++ b/common-channel.c @@ -34,6 +34,7 @@ #include "channel.h" #include "ssh.h" #include "listener.h" +#include "runopts.h" static void send_msg_channel_open_failure(unsigned int remotechan, int reason, const unsigned char *text, const unsigned char *lang); @@ -150,9 +151,9 @@ struct Channel* newchannel(unsigned int remotechan, newchan->await_open = 0; newchan->flushing = 0; - newchan->writebuf = cbuf_new(RECV_MAX_WINDOW); + newchan->writebuf = cbuf_new(opts.recv_window); newchan->extrabuf = NULL; /* The user code can set it up */ - newchan->recvwindow = RECV_MAX_WINDOW; + newchan->recvwindow = opts.recv_window; newchan->recvdonelen = 0; newchan->recvmaxpacket = RECV_MAX_PAYLOAD_LEN; @@ -421,7 +422,7 @@ static void writechannel(struct Channel* channel, int fd, circbuffer *cbuf) { channel->recvdonelen = 0; } - dropbear_assert(channel->recvwindow <= RECV_MAX_WINDOW); + dropbear_assert(channel->recvwindow <= opts.recv_window); dropbear_assert(channel->recvwindow <= cbuf_getavail(channel->writebuf)); dropbear_assert(channel->extrabuf == NULL || channel->recvwindow <= cbuf_getavail(channel->extrabuf)); @@ -710,7 +711,7 @@ void common_recv_msg_channel_data(struct Channel *channel, int fd, dropbear_assert(channel->recvwindow >= datalen); channel->recvwindow -= datalen; - dropbear_assert(channel->recvwindow <= RECV_MAX_WINDOW); + dropbear_assert(channel->recvwindow <= opts.recv_window); TRACE(("leave recv_msg_channel_data")) } @@ -970,7 +971,7 @@ int send_msg_channel_open_init(int fd, const struct ChanType *type) { buf_putbyte(ses.writepayload, SSH_MSG_CHANNEL_OPEN); buf_putstring(ses.writepayload, type->name, strlen(type->name)); buf_putint(ses.writepayload, chan->index); - buf_putint(ses.writepayload, RECV_MAX_WINDOW); + buf_putint(ses.writepayload, opts.recv_window); buf_putint(ses.writepayload, RECV_MAX_PAYLOAD_LEN); TRACE(("leave send_msg_channel_open_init()")) @@ -74,6 +74,11 @@ by the ssh server. .B \-y Always accept hostkeys if they are unknown. If a hostkey mismatch occurs the connection will abort as normal. +.TP +.B \-W \fIwindowsize +Specify the per-channel receive window buffer size. Increasing this +may improve network performance at the expense of memory use. Use -h to see the +default buffer size. .SH AUTHOR Matt Johnston (matt@ucc.asn.au). .br @@ -82,6 +82,11 @@ default is /var/run/dropbear.pid .TP .B \-a Allow remote hosts to connect to forwarded ports. +.TP +.B \-W \fIwindowsize +Specify the per-channel receive window buffer size. Increasing this +may improve network performance at the expense of memory use. Use -h to see the +default buffer size. .SH AUTHOR Matt Johnston (matt@ucc.asn.au). .br @@ -220,8 +220,10 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ usage and network performance: */ /* Size of the network receive window. This amount of memory is allocated as a per-channel receive buffer. Increasing this value can make a - significant difference to network performance. */ -#define RECV_MAX_WINDOW 8192 + significant difference to network performance. 24kB was empirically + chosen for a 100mbit ethernet network. The value can be altered at + runtime with the -W argument. */ +#define DEFAULT_RECV_WINDOW 24576 /* Maximum size of a received SSH data packet - this _MUST_ be >= 32768 in order to interoperate with other implementations */ #define RECV_MAX_PAYLOAD_LEN 32768 @@ -339,7 +341,7 @@ etc) slower (perhaps by 50%). Recommended for most small systems. */ #define TRANS_MAX_WINDOW 500000000 /* 500MB is sufficient, stopping overflow */ #define TRANS_MAX_WIN_INCR 500000000 /* overflow prevention */ -#define RECV_WINDOWEXTEND (RECV_MAX_WINDOW / 3) /* We send a "window extend" every +#define RECV_WINDOWEXTEND (opts.recv_window / 3) /* We send a "window extend" every RECV_WINDOWEXTEND bytes */ #define MAX_CHANNELS 100 /* simple mem restriction, includes each tcp/x11 @@ -36,6 +36,7 @@ typedef struct runopts { #if defined(ENABLE_SVR_REMOTETCPFWD) || defined(ENABLE_CLI_LOCALTCPFWD) int listen_fwd_all; #endif + unsigned int recv_window; } runopts; diff --git a/svr-runopts.c b/svr-runopts.c index dde0b07..f78461b 100644 --- a/svr-runopts.c +++ b/svr-runopts.c @@ -80,6 +80,7 @@ static void printhelp(const char * progname) { #ifdef INETD_MODE "-i Start for inetd\n" #endif + "-W <receive_window_buffer> (default %d, larger may be faster)\n" #ifdef DEBUG_TRACE "-v verbose\n" #endif @@ -90,7 +91,7 @@ static void printhelp(const char * progname) { #ifdef DROPBEAR_RSA RSA_PRIV_FILENAME, #endif - DROPBEAR_MAX_PORTS, DROPBEAR_DEFPORT, DROPBEAR_PIDFILE); + DROPBEAR_MAX_PORTS, DROPBEAR_DEFPORT, DROPBEAR_PIDFILE, DEFAULT_RECV_WINDOW); } void svr_getopts(int argc, char ** argv) { @@ -128,6 +129,8 @@ void svr_getopts(int argc, char ** argv) { #ifndef DISABLE_SYSLOG svr_opts.usingsyslog = 1; #endif + opts.recv_window = DEFAULT_RECV_WINDOW; + char* recv_window_arg = NULL; #ifdef ENABLE_SVR_REMOTETCPFWD opts.listen_fwd_all = 0; #endif @@ -204,6 +207,9 @@ void svr_getopts(int argc, char ** argv) { case 'w': svr_opts.norootlogin = 1; break; + case 'W': + next = &recv_window_arg; + break; #if defined(ENABLE_SVR_PASSWORD_AUTH) || defined(ENABLE_SVR_PAM_AUTH) case 's': svr_opts.noauthpass = 1; @@ -265,8 +271,17 @@ void svr_getopts(int argc, char ** argv) { svr_opts.bannerfile); } buf_setpos(svr_opts.banner, 0); - } + } + + if (recv_window_arg) + { + opts.recv_window = atol(recv_window_arg); + if (opts.recv_window == 0) + { + dropbear_exit("Bad recv window '%s'", recv_window_arg); + } + } } static void addportandaddress(char* spec) { |