Mercurial > dropbear
comparison 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 |
comparison
equal
deleted
inserted
replaced
453:29953de278ae | 454:7e43f5e473b9 |
---|---|
32 #include "ssh.h" | 32 #include "ssh.h" |
33 #include "random.h" | 33 #include "random.h" |
34 #include "kex.h" | 34 #include "kex.h" |
35 #include "channel.h" | 35 #include "channel.h" |
36 #include "atomicio.h" | 36 #include "atomicio.h" |
37 #include "runopts.h" | |
37 | 38 |
38 static void checktimeouts(); | 39 static void checktimeouts(); |
40 static long select_timeout(); | |
39 static int ident_readln(int fd, char* buf, int count); | 41 static int ident_readln(int fd, char* buf, int count); |
40 | 42 |
41 struct sshsession ses; /* GLOBAL */ | 43 struct sshsession ses; /* GLOBAL */ |
42 | 44 |
43 /* need to know if the session struct has been initialised, this way isn't the | 45 /* need to know if the session struct has been initialised, this way isn't the |
57 ses.remotehost = remotehost; | 59 ses.remotehost = remotehost; |
58 | 60 |
59 ses.sock = sock; | 61 ses.sock = sock; |
60 ses.maxfd = sock; | 62 ses.maxfd = sock; |
61 | 63 |
62 ses.connecttimeout = 0; | 64 ses.connect_time = 0; |
65 ses.last_packet_time = 0; | |
63 | 66 |
64 if (pipe(ses.signal_pipe) < 0) { | 67 if (pipe(ses.signal_pipe) < 0) { |
65 dropbear_exit("signal pipe failed"); | 68 dropbear_exit("signal pipe failed"); |
66 } | 69 } |
67 setnonblocking(ses.signal_pipe[0]); | 70 setnonblocking(ses.signal_pipe[0]); |
127 int val; | 130 int val; |
128 | 131 |
129 /* main loop, select()s for all sockets in use */ | 132 /* main loop, select()s for all sockets in use */ |
130 for(;;) { | 133 for(;;) { |
131 | 134 |
132 timeout.tv_sec = SELECT_TIMEOUT; | 135 timeout.tv_sec = select_timeout(); |
133 timeout.tv_usec = 0; | 136 timeout.tv_usec = 0; |
134 FD_ZERO(&writefd); | 137 FD_ZERO(&writefd); |
135 FD_ZERO(&readfd); | 138 FD_ZERO(&readfd); |
136 dropbear_assert(ses.payload == NULL); | 139 dropbear_assert(ses.payload == NULL); |
137 if (ses.sock != -1) { | 140 if (ses.sock != -1) { |
357 buf[pos] = '\0'; | 360 buf[pos] = '\0'; |
358 TRACE(("leave ident_readln: return %d", pos+1)) | 361 TRACE(("leave ident_readln: return %d", pos+1)) |
359 return pos+1; | 362 return pos+1; |
360 } | 363 } |
361 | 364 |
365 void send_msg_ignore() { | |
366 CHECKCLEARTOWRITE(); | |
367 buf_putbyte(ses.writepayload, SSH_MSG_IGNORE); | |
368 buf_putstring(ses.writepayload, "", 0); | |
369 encrypt_packet(); | |
370 } | |
371 | |
362 /* Check all timeouts which are required. Currently these are the time for | 372 /* Check all timeouts which are required. Currently these are the time for |
363 * user authentication, and the automatic rekeying. */ | 373 * user authentication, and the automatic rekeying. */ |
364 static void checktimeouts() { | 374 static void checktimeouts() { |
365 | 375 |
366 struct timeval tv; | 376 time_t now; |
367 long secs; | 377 |
368 | 378 now = time(NULL); |
369 if (gettimeofday(&tv, 0) < 0) { | 379 |
370 dropbear_exit("Error getting time"); | 380 if (ses.connect_time != 0 && now - ses.connect_time >= AUTH_TIMEOUT) { |
371 } | |
372 | |
373 secs = tv.tv_sec; | |
374 | |
375 if (ses.connecttimeout != 0 && secs > ses.connecttimeout) { | |
376 dropbear_close("Timeout before auth"); | 381 dropbear_close("Timeout before auth"); |
377 } | 382 } |
378 | 383 |
379 /* we can't rekey if we haven't done remote ident exchange yet */ | 384 /* we can't rekey if we haven't done remote ident exchange yet */ |
380 if (ses.remoteident == NULL) { | 385 if (ses.remoteident == NULL) { |
381 return; | 386 return; |
382 } | 387 } |
383 | 388 |
384 if (!ses.kexstate.sentkexinit | 389 if (!ses.kexstate.sentkexinit |
385 && (secs - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT | 390 && (now - ses.kexstate.lastkextime >= KEX_REKEY_TIMEOUT |
386 || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)){ | 391 || ses.kexstate.datarecv+ses.kexstate.datatrans >= KEX_REKEY_DATA)) { |
387 TRACE(("rekeying after timeout or max data reached")) | 392 TRACE(("rekeying after timeout or max data reached")) |
388 send_msg_kexinit(); | 393 send_msg_kexinit(); |
389 } | 394 } |
390 } | 395 |
391 | 396 if (opts.keepalive_secs > 0 |
397 && now - ses.last_packet_time >= opts.keepalive_secs) { | |
398 send_msg_ignore(); | |
399 } | |
400 } | |
401 | |
402 static long select_timeout() { | |
403 /* determine the minimum timeout that might be required, so | |
404 as to avoid waking when unneccessary */ | |
405 long ret = LONG_MAX; | |
406 if (KEX_REKEY_TIMEOUT > 0) | |
407 ret = MIN(KEX_REKEY_TIMEOUT, ret); | |
408 if (AUTH_TIMEOUT > 0) | |
409 ret = MIN(AUTH_TIMEOUT, ret); | |
410 if (opts.keepalive_secs > 0) | |
411 ret = MIN(opts.keepalive_secs, ret); | |
412 return ret; | |
413 } |