diff --git a/cli-chansession.c b/cli-chansession.c index 6d610d4e2d4fe858269be292f5fedfa5d4629da0..c3e2f811c2d2d36ce667ff6907748427f69cd257 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 5cfd017fa60ba2707ab6252ce91d5821682afc3c..3db8f2ff4d0ece3ff8ae01f8ef3538aadb9a7081 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 4f150279f3712b74e1a228a6dd0dab8f379a08b0..082a5a20a63c6a63538800e0cbeef16f85376d8a 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 76658454877ec632fe4500c59a7f45ab1683a1c2..4c7b123779581bb3ae9fba97d900eca0d9d4dfc1 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 b912eaf014c1e948420e725f5edaa80ab3807365..dd9ea02b829458f909acf0291c54376e2bbd4527 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 c4b8c48867869f20736e6f1333988c8f6fdc5810..73b281baae7f622973c79ed9a65b57f8cd705985 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;