diff options
Diffstat (limited to 'common-session.c')
-rw-r--r-- | common-session.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/common-session.c b/common-session.c index 164dc85..8ec7516 100644 --- a/common-session.c +++ b/common-session.c @@ -1,7 +1,7 @@ /* * Dropbear - a SSH2 server * - * Copyright (c) 2002,2003 Matt Johnston + * Copyright (c) Matt Johnston * All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy @@ -64,6 +64,13 @@ void common_session_init(int sock_in, int sock_out) { ses.sock_out = sock_out; ses.maxfd = MAX(sock_in, sock_out); + if (sock_in >= 0) { + setnonblocking(sock_in); + } + if (sock_out >= 0) { + setnonblocking(sock_out); + } + ses.socket_prio = DROPBEAR_PRIO_DEFAULT; /* Sets it to lowdelay */ update_channel_prio(); @@ -83,8 +90,6 @@ void common_session_init(int sock_in, int sock_out) { ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[0]); ses.maxfd = MAX(ses.maxfd, ses.signal_pipe[1]); - kexfirstinitialise(); /* initialise the kex state */ - ses.writepayload = buf_new(TRANS_MAX_PAYLOAD_LEN); ses.transseq = 0; @@ -145,6 +150,7 @@ void session_loop(void(*loophandler)()) { /* main loop, select()s for all sockets in use */ for(;;) { + const int writequeue_has_space = (ses.writequeue_len <= 2*TRANS_MAX_PAYLOAD_LEN); timeout.tv_sec = select_timeout(); timeout.tv_usec = 0; @@ -155,8 +161,12 @@ void session_loop(void(*loophandler)()) { /* We delay reading from the input socket during initial setup until after we have written out our initial KEXINIT packet (empty writequeue). This means our initial packet can be in-flight while we're doing a blocking - read for the remote ident */ - if (ses.sock_in != -1 && (ses.remoteident || isempty(&ses.writequeue))) { + read for the remote ident. + We also avoid reading from the socket if the writequeue is full, that avoids + replies backing up */ + if (ses.sock_in != -1 + && (ses.remoteident || isempty(&ses.writequeue)) + && writequeue_has_space) { FD_SET(ses.sock_in, &readfd); } if (ses.sock_out != -1 && !isempty(&ses.writequeue)) { @@ -168,7 +178,7 @@ void session_loop(void(*loophandler)()) { FD_SET(ses.signal_pipe[0], &readfd); /* set up for channels which can be read/written */ - setchannelfds(&readfd, &writefd); + setchannelfds(&readfd, &writefd, writequeue_has_space); /* Pending connections to test */ set_connect_fds(&writefd); @@ -268,7 +278,7 @@ void session_cleanup() { return; } - /* Beware of changing order of functions here. */ + /* BEWARE of changing order of functions here. */ /* Must be before extra_session_cleanup() */ chancleanup(); @@ -277,7 +287,7 @@ void session_cleanup() { ses.extra_session_cleanup(); } - /* After these are freed most functions will exit */ + /* After these are freed most functions will fail */ #ifdef DROPBEAR_CLEANUP /* listeners call cleanup functions, this should occur before other session state is freed. */ @@ -317,10 +327,8 @@ void session_cleanup() { void send_session_identification() { buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1); - buf_putbytes(writebuf, LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n")); - buf_putbyte(writebuf, 0x0); /* packet type */ - buf_setpos(writebuf, 0); - enqueue(&ses.writequeue, writebuf); + buf_putbytes(writebuf, (const unsigned char *) LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n")); + writebuf_enqueue(writebuf, 0); } static void read_session_identification() { |