Mercurial > dropbear
diff common-session.c @ 454:7e43f5e473b9
- Add -K keepalive flag for dropbear and dbclient
- Try to reduce the frequency of select() timeouts
- Add a max receive window size of 1MB
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Wed, 08 Aug 2007 15:12:06 +0000 |
parents | 4cab61369879 |
children | e3db1f7a2e43 |
line wrap: on
line diff
--- a/common-session.c Sat Jul 28 08:59:24 2007 +0000 +++ b/common-session.c Wed Aug 08 15:12:06 2007 +0000 @@ -34,8 +34,10 @@ #include "kex.h" #include "channel.h" #include "atomicio.h" +#include "runopts.h" static void checktimeouts(); +static long select_timeout(); static int ident_readln(int fd, char* buf, int count); struct sshsession ses; /* GLOBAL */ @@ -59,7 +61,8 @@ ses.sock = sock; ses.maxfd = sock; - ses.connecttimeout = 0; + ses.connect_time = 0; + ses.last_packet_time = 0; if (pipe(ses.signal_pipe) < 0) { dropbear_exit("signal pipe failed"); @@ -129,7 +132,7 @@ /* main loop, select()s for all sockets in use */ for(;;) { - timeout.tv_sec = SELECT_TIMEOUT; + timeout.tv_sec = select_timeout(); timeout.tv_usec = 0; FD_ZERO(&writefd); FD_ZERO(&readfd); @@ -359,20 +362,22 @@ return pos+1; } +void send_msg_ignore() { + CHECKCLEARTOWRITE(); + buf_putbyte(ses.writepayload, SSH_MSG_IGNORE); + buf_putstring(ses.writepayload, "", 0); + encrypt_packet(); +} + /* Check all timeouts which are required. Currently these are the time for * user authentication, and the automatic rekeying. */ static void checktimeouts() { - struct timeval tv; - long secs; + time_t now; - if (gettimeofday(&tv, 0) < 0) { - dropbear_exit("Error getting time"); - } - - secs = tv.tv_sec; + now = time(NULL); - if (ses.connecttimeout != 0 && secs > ses.connecttimeout) { + if (ses.connect_time != 0 && now - ses.connect_time >= AUTH_TIMEOUT) { dropbear_close("Timeout before auth"); } @@ -382,10 +387,27 @@ } if (!ses.kexstate.sentkexinit - && (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT - || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){ + && (now - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT + || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)) { TRACE(("rekeying after timeout or max data reached")) send_msg_kexinit(); } + + if (opts.keepalive_secs > 0 + && now - ses.last_packet_time >= opts.keepalive_secs) { + send_msg_ignore(); + } } +static long select_timeout() { + /* determine the minimum timeout that might be required, so + as to avoid waking when unneccessary */ + long ret = LONG_MAX; + if (KEX_REKEY_TIMEOUT > 0) + ret = MIN(KEX_REKEY_TIMEOUT, ret); + if (AUTH_TIMEOUT > 0) + ret = MIN(AUTH_TIMEOUT, ret); + if (opts.keepalive_secs > 0) + ret = MIN(opts.keepalive_secs, ret); + return ret; +}