mirror of
https://github.com/clearml/dropbear
synced 2025-05-31 18:38:21 +00:00
Leave non-interactive at default QoS class
Lower class levels are less well defined, and non-interactive SSH can carry various different types of applications. This change also sets lowdelay class (AF21) earlier in an an outbound dbclient session
This commit is contained in:
parent
14bdd5a8ae
commit
1c8f00bd59
10
channel.h
10
channel.h
@ -28,6 +28,7 @@
|
|||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "circbuffer.h"
|
#include "circbuffer.h"
|
||||||
|
#include "netio.h"
|
||||||
|
|
||||||
#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
|
#define SSH_OPEN_ADMINISTRATIVELY_PROHIBITED 1
|
||||||
#define SSH_OPEN_CONNECT_FAILED 2
|
#define SSH_OPEN_CONNECT_FAILED 2
|
||||||
@ -41,13 +42,6 @@
|
|||||||
|
|
||||||
struct ChanType;
|
struct ChanType;
|
||||||
|
|
||||||
enum dropbear_channel_prio {
|
|
||||||
DROPBEAR_CHANNEL_PRIO_INTERACTIVE, /* pty shell, x11 */
|
|
||||||
DROPBEAR_CHANNEL_PRIO_UNKNOWABLE, /* tcp - can't know what's being forwarded */
|
|
||||||
DROPBEAR_CHANNEL_PRIO_BULK, /* the rest - probably scp, rsync, git, or something */
|
|
||||||
DROPBEAR_CHANNEL_PRIO_EARLY, /* channel is still being set up */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Channel {
|
struct Channel {
|
||||||
|
|
||||||
unsigned int index; /* the local channel index */
|
unsigned int index; /* the local channel index */
|
||||||
@ -88,7 +82,7 @@ struct Channel {
|
|||||||
|
|
||||||
const struct ChanType* type;
|
const struct ChanType* type;
|
||||||
|
|
||||||
enum dropbear_channel_prio prio;
|
enum dropbear_prio prio;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ChanType {
|
struct ChanType {
|
||||||
|
@ -348,7 +348,6 @@ static int cli_init_stdpipe_sess(struct Channel *channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int cli_init_netcat(struct Channel *channel) {
|
static int cli_init_netcat(struct Channel *channel) {
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
|
||||||
return cli_init_stdpipe_sess(channel);
|
return cli_init_stdpipe_sess(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -361,12 +360,9 @@ static int cli_initchansess(struct Channel *channel) {
|
|||||||
cli_setup_agent(channel);
|
cli_setup_agent(channel);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (cli_opts.wantpty) {
|
if (cli_opts.wantpty) {
|
||||||
send_chansess_pty_req(channel);
|
send_chansess_pty_req(channel);
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_INTERACTIVE;
|
channel->prio = DROPBEAR_PRIO_LOWDELAY;
|
||||||
} else {
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_BULK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send_chansess_shell_req(channel);
|
send_chansess_shell_req(channel);
|
||||||
|
@ -85,7 +85,8 @@ int main(int argc, char ** argv) {
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
progress = connect_remote(cli_opts.remotehost, cli_opts.remoteport,
|
progress = connect_remote(cli_opts.remotehost, cli_opts.remoteport,
|
||||||
cli_connected, &ses, cli_opts.bind_address, cli_opts.bind_port);
|
cli_connected, &ses, cli_opts.bind_address, cli_opts.bind_port,
|
||||||
|
DROPBEAR_PRIO_LOWDELAY);
|
||||||
sock_in = sock_out = -1;
|
sock_in = sock_out = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +102,9 @@ void cli_connected(int result, int sock, void* userdata, const char *errstring)
|
|||||||
dropbear_exit("Connect failed: %s", errstring);
|
dropbear_exit("Connect failed: %s", errstring);
|
||||||
}
|
}
|
||||||
myses->sock_in = myses->sock_out = sock;
|
myses->sock_in = myses->sock_out = sock;
|
||||||
|
TRACE(("cli_connected"))
|
||||||
|
ses.socket_prio = DROPBEAR_PRIO_NORMAL;
|
||||||
|
/* switches to lowdelay */
|
||||||
update_channel_prio();
|
update_channel_prio();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ static int cli_localtcp(const char* listenaddr,
|
|||||||
unsigned int remoteport);
|
unsigned int remoteport);
|
||||||
static const struct ChanType cli_chan_tcplocal = {
|
static const struct ChanType cli_chan_tcplocal = {
|
||||||
"direct-tcpip",
|
"direct-tcpip",
|
||||||
tcp_prio_inithandler,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@ -272,10 +272,9 @@ static int newtcpforwarded(struct Channel * channel) {
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
|
||||||
|
|
||||||
snprintf(portstring, sizeof(portstring), "%u", fwd->connectport);
|
snprintf(portstring, sizeof(portstring), "%u", fwd->connectport);
|
||||||
channel->conn_pending = connect_remote(fwd->connectaddr, portstring, channel_connect_done, channel, NULL, NULL);
|
channel->conn_pending = connect_remote(fwd->connectaddr, portstring, channel_connect_done,
|
||||||
|
channel, NULL, NULL, DROPBEAR_PRIO_NORMAL);
|
||||||
|
|
||||||
err = SSH_OPEN_IN_PROGRESS;
|
err = SSH_OPEN_IN_PROGRESS;
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ static struct Channel* newchannel(unsigned int remotechan,
|
|||||||
newchan->recvdonelen = 0;
|
newchan->recvdonelen = 0;
|
||||||
newchan->recvmaxpacket = RECV_MAX_CHANNEL_DATA_LEN;
|
newchan->recvmaxpacket = RECV_MAX_CHANNEL_DATA_LEN;
|
||||||
|
|
||||||
newchan->prio = DROPBEAR_CHANNEL_PRIO_EARLY; /* inithandler sets it */
|
newchan->prio = DROPBEAR_PRIO_NORMAL;
|
||||||
|
|
||||||
ses.channels[i] = newchan;
|
ses.channels[i] = newchan;
|
||||||
ses.chancount++;
|
ses.chancount++;
|
||||||
@ -955,9 +955,7 @@ void recv_msg_channel_open() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
|
update_channel_prio();
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_BULK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
send_msg_channel_open_confirmation(channel, channel->recvwindow,
|
send_msg_channel_open_confirmation(channel, channel->recvwindow,
|
||||||
@ -971,8 +969,6 @@ failure:
|
|||||||
cleanup:
|
cleanup:
|
||||||
m_free(type);
|
m_free(type);
|
||||||
|
|
||||||
update_channel_prio();
|
|
||||||
|
|
||||||
TRACE(("leave recv_msg_channel_open"))
|
TRACE(("leave recv_msg_channel_open"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1166,9 +1162,6 @@ void recv_msg_channel_open_confirmation() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_BULK;
|
|
||||||
}
|
|
||||||
update_channel_prio();
|
update_channel_prio();
|
||||||
|
|
||||||
TRACE(("leave recv_msg_channel_open_confirmation"))
|
TRACE(("leave recv_msg_channel_open_confirmation"))
|
||||||
|
@ -64,7 +64,7 @@ void common_session_init(int sock_in, int sock_out) {
|
|||||||
setnonblocking(sock_out);
|
setnonblocking(sock_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
ses.socket_prio = DROPBEAR_PRIO_DEFAULT;
|
ses.socket_prio = DROPBEAR_PRIO_NORMAL;
|
||||||
/* Sets it to lowdelay */
|
/* Sets it to lowdelay */
|
||||||
update_channel_prio();
|
update_channel_prio();
|
||||||
|
|
||||||
@ -667,26 +667,16 @@ void update_channel_prio() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_prio = DROPBEAR_PRIO_BULK;
|
new_prio = DROPBEAR_PRIO_NORMAL;
|
||||||
for (i = 0; i < ses.chansize; i++) {
|
for (i = 0; i < ses.chansize; i++) {
|
||||||
struct Channel *channel = ses.channels[i];
|
struct Channel *channel = ses.channels[i];
|
||||||
if (!channel || channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
|
if (!channel) {
|
||||||
if (channel && channel->prio == DROPBEAR_CHANNEL_PRIO_EARLY) {
|
|
||||||
TRACE(("update_channel_prio: early %d", channel->index))
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
any = 1;
|
any = 1;
|
||||||
if (channel->prio == DROPBEAR_CHANNEL_PRIO_INTERACTIVE)
|
if (channel->prio == DROPBEAR_PRIO_LOWDELAY) {
|
||||||
{
|
|
||||||
TRACE(("update_channel_prio: lowdelay %d", channel->index))
|
|
||||||
new_prio = DROPBEAR_PRIO_LOWDELAY;
|
new_prio = DROPBEAR_PRIO_LOWDELAY;
|
||||||
break;
|
break;
|
||||||
} else if (channel->prio == DROPBEAR_CHANNEL_PRIO_UNKNOWABLE
|
|
||||||
&& new_prio == DROPBEAR_PRIO_BULK)
|
|
||||||
{
|
|
||||||
TRACE(("update_channel_prio: unknowable %d", channel->index))
|
|
||||||
new_prio = DROPBEAR_PRIO_DEFAULT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
15
netio.c
15
netio.c
@ -20,6 +20,7 @@ struct dropbear_progress_connection {
|
|||||||
|
|
||||||
char* errstring;
|
char* errstring;
|
||||||
char *bind_address, *bind_port;
|
char *bind_address, *bind_port;
|
||||||
|
enum dropbear_prio prio;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
|
/* Deallocate a progress connection. Removes from the pending list if iter!=NULL.
|
||||||
@ -110,6 +111,7 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
|
|||||||
|
|
||||||
ses.maxfd = MAX(ses.maxfd, c->sock);
|
ses.maxfd = MAX(ses.maxfd, c->sock);
|
||||||
set_sock_nodelay(c->sock);
|
set_sock_nodelay(c->sock);
|
||||||
|
set_sock_priority(c->sock, c->prio);
|
||||||
setnonblocking(c->sock);
|
setnonblocking(c->sock);
|
||||||
|
|
||||||
#if DROPBEAR_CLIENT_TCP_FAST_OPEN
|
#if DROPBEAR_CLIENT_TCP_FAST_OPEN
|
||||||
@ -173,7 +175,7 @@ static void connect_try_next(struct dropbear_progress_connection *c) {
|
|||||||
/* Connect via TCP to a host. */
|
/* Connect via TCP to a host. */
|
||||||
struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport,
|
struct dropbear_progress_connection *connect_remote(const char* remotehost, const char* remoteport,
|
||||||
connect_callback cb, void* cb_data,
|
connect_callback cb, void* cb_data,
|
||||||
const char* bind_address, const char* bind_port)
|
const char* bind_address, const char* bind_port, enum dropbear_prio prio)
|
||||||
{
|
{
|
||||||
struct dropbear_progress_connection *c = NULL;
|
struct dropbear_progress_connection *c = NULL;
|
||||||
int err;
|
int err;
|
||||||
@ -185,6 +187,7 @@ struct dropbear_progress_connection *connect_remote(const char* remotehost, cons
|
|||||||
c->sock = -1;
|
c->sock = -1;
|
||||||
c->cb = cb;
|
c->cb = cb;
|
||||||
c->cb_data = cb_data;
|
c->cb_data = cb_data;
|
||||||
|
c->prio = prio;
|
||||||
|
|
||||||
list_append(&ses.conn_pending, c);
|
list_append(&ses.conn_pending, c);
|
||||||
|
|
||||||
@ -378,10 +381,8 @@ void set_sock_priority(int sock, enum dropbear_prio prio) {
|
|||||||
/* Set the DSCP field for outbound IP packet priority.
|
/* Set the DSCP field for outbound IP packet priority.
|
||||||
rfc4594 has some guidance to meanings.
|
rfc4594 has some guidance to meanings.
|
||||||
|
|
||||||
We set AF21 as "Low-Latency" class for interactive (tty session).
|
We set AF21 as "Low-Latency" class for interactive (tty session,
|
||||||
Set AF11 "High-Throughput" for bulk data (which includes things
|
also handshake/setup packets). Other traffic is left at the default.
|
||||||
such as git over ssh). We usually want higher priority than
|
|
||||||
CS1/LE least effort.
|
|
||||||
|
|
||||||
OpenSSH at present uses AF21/CS1, rationale
|
OpenSSH at present uses AF21/CS1, rationale
|
||||||
https://cvsweb.openbsd.org/src/usr.bin/ssh/readconf.c#rev1.284
|
https://cvsweb.openbsd.org/src/usr.bin/ssh/readconf.c#rev1.284
|
||||||
@ -391,8 +392,6 @@ void set_sock_priority(int sock, enum dropbear_prio prio) {
|
|||||||
*/
|
*/
|
||||||
if (prio == DROPBEAR_PRIO_LOWDELAY) {
|
if (prio == DROPBEAR_PRIO_LOWDELAY) {
|
||||||
val = IPTOS_DSCP_AF21;
|
val = IPTOS_DSCP_AF21;
|
||||||
} else if (prio == DROPBEAR_PRIO_BULK) {
|
|
||||||
val = IPTOS_DSCP_AF11;
|
|
||||||
} else {
|
} else {
|
||||||
val = 0; /* default */
|
val = 0; /* default */
|
||||||
}
|
}
|
||||||
@ -412,8 +411,6 @@ void set_sock_priority(int sock, enum dropbear_prio prio) {
|
|||||||
/* Set scheduling priority within the local Linux network stack */
|
/* Set scheduling priority within the local Linux network stack */
|
||||||
if (prio == DROPBEAR_PRIO_LOWDELAY) {
|
if (prio == DROPBEAR_PRIO_LOWDELAY) {
|
||||||
val = TC_PRIO_INTERACTIVE;
|
val = TC_PRIO_INTERACTIVE;
|
||||||
} else if (prio == DROPBEAR_PRIO_BULK) {
|
|
||||||
val = TC_PRIO_BULK;
|
|
||||||
} else {
|
} else {
|
||||||
val = 0;
|
val = 0;
|
||||||
}
|
}
|
||||||
|
8
netio.h
8
netio.h
@ -6,9 +6,8 @@
|
|||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
|
||||||
enum dropbear_prio {
|
enum dropbear_prio {
|
||||||
DROPBEAR_PRIO_DEFAULT = 10,
|
DROPBEAR_PRIO_NORMAL = 0, /* the rest - tcp-fwd, scp, rsync, git, etc */
|
||||||
DROPBEAR_PRIO_LOWDELAY = 11,
|
DROPBEAR_PRIO_LOWDELAY, /* pty shell, x11 */
|
||||||
DROPBEAR_PRIO_BULK = 12,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void set_sock_nodelay(int sock);
|
void set_sock_nodelay(int sock);
|
||||||
@ -30,7 +29,8 @@ typedef void(*connect_callback)(int result, int sock, void* data, const char* er
|
|||||||
|
|
||||||
/* Always returns a progress connection, if it fails it will call the callback at a later point */
|
/* Always returns a progress connection, if it fails it will call the callback at a later point */
|
||||||
struct dropbear_progress_connection * connect_remote (const char* remotehost, const char* remoteport,
|
struct dropbear_progress_connection * connect_remote (const char* remotehost, const char* remoteport,
|
||||||
connect_callback cb, void *cb_data, const char* bind_address, const char* bind_port);
|
connect_callback cb, void *cb_data, const char* bind_address, const char* bind_port,
|
||||||
|
enum dropbear_prio prio);
|
||||||
|
|
||||||
/* Sets up for select() */
|
/* Sets up for select() */
|
||||||
void set_connect_fds(fd_set *writefd);
|
void set_connect_fds(fd_set *writefd);
|
||||||
|
@ -277,7 +277,8 @@ static int newchansess(struct Channel *channel) {
|
|||||||
chansess->agentdir = NULL;
|
chansess->agentdir = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_INTERACTIVE;
|
/* Will drop to DROPBEAR_PRIO_NORMAL if a non-tty command starts */
|
||||||
|
channel->prio = DROPBEAR_PRIO_LOWDELAY;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -734,7 +735,7 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
|
|||||||
/* no pty */
|
/* no pty */
|
||||||
ret = noptycommand(channel, chansess);
|
ret = noptycommand(channel, chansess);
|
||||||
if (ret == DROPBEAR_SUCCESS) {
|
if (ret == DROPBEAR_SUCCESS) {
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_BULK;
|
channel->prio = DROPBEAR_PRIO_NORMAL;
|
||||||
update_channel_prio();
|
update_channel_prio();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -60,7 +60,7 @@ static int newtcpdirect(struct Channel * channel);
|
|||||||
#if DROPBEAR_SVR_REMOTETCPFWD
|
#if DROPBEAR_SVR_REMOTETCPFWD
|
||||||
static const struct ChanType svr_chan_tcpremote = {
|
static const struct ChanType svr_chan_tcpremote = {
|
||||||
"forwarded-tcpip",
|
"forwarded-tcpip",
|
||||||
tcp_prio_inithandler,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@ -289,10 +289,9 @@ static int newtcpdirect(struct Channel * channel) {
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
|
||||||
|
|
||||||
snprintf(portstring, sizeof(portstring), "%u", destport);
|
snprintf(portstring, sizeof(portstring), "%u", destport);
|
||||||
channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done, channel, NULL, NULL);
|
channel->conn_pending = connect_remote(desthost, portstring, channel_connect_done,
|
||||||
|
channel, NULL, NULL, DROPBEAR_PRIO_NORMAL);
|
||||||
|
|
||||||
err = SSH_OPEN_IN_PROGRESS;
|
err = SSH_OPEN_IN_PROGRESS;
|
||||||
|
|
||||||
|
@ -45,13 +45,6 @@ static void cleanup_tcp(const struct Listener *listener) {
|
|||||||
m_free(tcpinfo);
|
m_free(tcpinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcp_prio_inithandler(struct Channel* channel)
|
|
||||||
{
|
|
||||||
TRACE(("tcp_prio_inithandler channel %d", channel->index))
|
|
||||||
channel->prio = DROPBEAR_CHANNEL_PRIO_UNKNOWABLE;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void tcp_acceptor(const struct Listener *listener, int sock) {
|
static void tcp_acceptor(const struct Listener *listener, int sock) {
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
|
1
tcpfwd.h
1
tcpfwd.h
@ -71,7 +71,6 @@ void cli_recv_msg_request_failure(void);
|
|||||||
|
|
||||||
/* Common */
|
/* Common */
|
||||||
int listen_tcpfwd(struct TCPListener* tcpinfo, struct Listener **ret_listener);
|
int listen_tcpfwd(struct TCPListener* tcpinfo, struct Listener **ret_listener);
|
||||||
int tcp_prio_inithandler(struct Channel* chan);
|
|
||||||
|
|
||||||
/* A random identifier */
|
/* A random identifier */
|
||||||
#define CHANNEL_ID_TCPFORWARDED 0x43612c67
|
#define CHANNEL_ID_TCPFORWARDED 0x43612c67
|
||||||
|
Loading…
Reference in New Issue
Block a user