From 998d6cdfc48bbe9101b87457edbc0e3f2fe36fe0 Mon Sep 17 00:00:00 2001 From: Matt Johnston <matt@ucc.asn.au> Date: Tue, 3 Dec 2013 00:04:48 +0800 Subject: [PATCH] - Sockets are set to lowdelay priority initially to improve conneciton setup time - Set non-pty connections to bulk for client and server --- cli-chansession.c | 3 ++- cli-main.c | 3 +++ dbutil.c | 37 ++++++++++++++++++++++--------------- dbutil.h | 8 +++++++- svr-chansession.c | 3 +-- svr-main.c | 5 +++++ 6 files changed, 40 insertions(+), 19 deletions(-) diff --git a/cli-chansession.c b/cli-chansession.c index 6d610d4e..c3e2f811 100644 --- a/cli-chansession.c +++ b/cli-chansession.c @@ -369,7 +369,8 @@ static int cli_initchansess(struct Channel *channel) { if (cli_opts.wantpty) { send_chansess_pty_req(channel); - set_sock_priority(ses.sock_out); + } else { + set_sock_priority(ses.sock_out, DROPBEAR_PRIO_BULK); } send_chansess_shell_req(channel); diff --git a/cli-main.c b/cli-main.c index 5cfd017f..3db8f2ff 100644 --- a/cli-main.c +++ b/cli-main.c @@ -75,6 +75,9 @@ int main(int argc, char ** argv) { int sock = connect_remote(cli_opts.remotehost, cli_opts.remoteport, 0, &error); sock_in = sock_out = sock; + if (cli_opts.wantpty) { + set_sock_priority(sock, DROPBEAR_PRIO_LOWDELAY); + } } if (sock_in < 0) { diff --git a/dbutil.c b/dbutil.c index 4f150279..082a5a20 100644 --- a/dbutil.c +++ b/dbutil.c @@ -185,30 +185,37 @@ void set_sock_nodelay(int sock) { setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&val, sizeof(val)); } -void set_sock_priority(int sock) { +void set_sock_priority(int sock, enum dropbear_prio prio) { - int val, rc; + int iptos_val = 0, so_prio_val = 0, rc; /* set the TOS bit for either ipv4 or ipv6 */ #ifdef IPTOS_LOWDELAY - val = IPTOS_LOWDELAY; + if (prio == DROPBEAR_PRIO_LOWDELAY) { + iptos_val = IPTOS_LOWDELAY; + } else if (prio == DROPBEAR_PRIO_BULK) { + iptos_val = IPTOS_THROUGHPUT; + } #if defined(IPPROTO_IPV6) && defined(IPV6_TCLASS) - rc = setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, (void*)&val, sizeof(val)); - if (rc < 0) - dropbear_log(LOG_WARNING, "Couldn't set IPV6_TCLASS (%s)", - strerror(errno)); + rc = setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, (void*)&iptos_val, sizeof(iptos_val)); + if (rc < 0) { + TRACE(("Couldn't set IPV6_TCLASS (%s)", strerror(errno))); + } #endif - rc = setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&val, sizeof(val)); - if (rc < 0) - dropbear_log(LOG_WARNING, "Couldn't set IP_TOS (%s)", - strerror(errno)); + rc = setsockopt(sock, IPPROTO_IP, IP_TOS, (void*)&iptos_val, sizeof(iptos_val)); + if (rc < 0) { + TRACE(("Couldn't set IP_TOS (%s)", strerror(errno))); + } #endif #ifdef SO_PRIORITY - /* linux specific, sets QoS class. - * 6 looks to be optimal for interactive traffic (see tc-prio(8) ). */ - val = TC_PRIO_INTERACTIVE; - rc = setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &val, sizeof(val)); + if (prio == DROPBEAR_PRIO_LOWDELAY) { + so_prio_val = TC_PRIO_INTERACTIVE; + } else if (prio == DROPBEAR_PRIO_BULK) { + so_prio_val = TC_PRIO_BULK; + } + /* linux specific, sets QoS class. see tc-prio(8) */ + rc = setsockopt(sock, SOL_SOCKET, SO_PRIORITY, (void*) &so_prio_val, sizeof(so_prio_val)); if (rc < 0) dropbear_log(LOG_WARNING, "Couldn't set SO_PRIORITY (%s)", strerror(errno)); diff --git a/dbutil.h b/dbutil.h index 76658454..4c7b1237 100644 --- a/dbutil.h +++ b/dbutil.h @@ -61,13 +61,19 @@ void printmpint(const char *label, mp_int *mp); extern int debug_trace; #endif +enum dropbear_prio { + DROPBEAR_PRIO_DEFAULT, + DROPBEAR_PRIO_LOWDELAY, + DROPBEAR_PRIO_BULK, +}; + char * stripcontrol(const char * text); void get_socket_address(int fd, char **local_host, char **local_port, char **remote_host, char **remote_port, int host_lookup); void getaddrstring(struct sockaddr_storage* addr, char **ret_host, char **ret_port, int host_lookup); void set_sock_nodelay(int sock); -void set_sock_priority(int sock); +void set_sock_priority(int sock, enum dropbear_prio prio); int dropbear_listen(const char* address, const char* port, int *socks, unsigned int sockcount, char **errstring, int *maxfd); int spawn_command(void(*exec_fn)(void *user_data), void *exec_data, diff --git a/svr-chansession.c b/svr-chansession.c index b912eaf0..dd9ea02b 100644 --- a/svr-chansession.c +++ b/svr-chansession.c @@ -580,8 +580,6 @@ static int sessionpty(struct ChanSess * chansess) { /* Read the terminal modes */ get_termmodes(chansess); - set_sock_priority(ses.sock_out); - TRACE(("leave sessionpty")) return DROPBEAR_SUCCESS; } @@ -666,6 +664,7 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess, if (chansess->term == NULL) { /* no pty */ + set_sock_priority(ses.sock_out, DROPBEAR_PRIO_BULK); ret = noptycommand(channel, chansess); } else { /* want pty */ diff --git a/svr-main.c b/svr-main.c index c4b8c488..73b281ba 100644 --- a/svr-main.c +++ b/svr-main.c @@ -137,6 +137,11 @@ void main_noinetd() { dropbear_exit("No listening ports available."); } + for (i = 0; i < listensockcount; i++) { + set_sock_priority(listensocks[i], DROPBEAR_PRIO_LOWDELAY); + FD_SET(listensocks[i], &fds); + } + /* fork */ if (svr_opts.forkbg) { int closefds = 0; -- GitLab