summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--cli-chansession.c2
-rw-r--r--cli-runopts.c17
-rw-r--r--common-channel.c11
-rw-r--r--dbclient.15
-rw-r--r--dropbear.85
-rw-r--r--options.h8
-rw-r--r--runopts.h1
-rw-r--r--svr-runopts.c19
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()"))
diff --git a/dbclient.1 b/dbclient.1
index 4145342..3e67c08 100644
--- a/dbclient.1
+++ b/dbclient.1
@@ -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
diff --git a/dropbear.8 b/dropbear.8
index ef0caf3..70dfb3e 100644
--- a/dropbear.8
+++ b/dropbear.8
@@ -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
diff --git a/options.h b/options.h
index 15d4522..939206a 100644
--- a/options.h
+++ b/options.h
@@ -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
diff --git a/runopts.h b/runopts.h
index ed34658..e430371 100644
--- a/runopts.h
+++ b/runopts.h
@@ -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) {