Il 16/11/18 15:25, Matt Johnston ha scritto:
The problem is that waiting for the remote banner is still adding a round trip of
delay. That's fine for a local network, but me -> dropbear.nl is half a second,
that's no good.
As long as we let the Cisco speak first, it is happy.
So why don't we read a env var to optionally wait for incoming data before we
send our first packet?
All remains the same, we just swap who speaks first: it should not add any
relevant delay.
Cheers,
TRACE (6250) 0.000821: -> KEXINIT
TRACE2 (6250) 0.000824: update_timeout limit 0, now 19720, last 19720, timeout
28800
TRACE (6250) 0.000833: enter set_connect_fds
TRACE (6250) 0.000843: setnonblocking: 8
TRACE (6250) 0.000848: leave setnonblocking
TRACE (6250) 0.002446: maybe_empty_reply_queue - no data allowed
TRACE (6250) 0.002484: enter handle_connect_fds
TRACE (6250) 0.002500: handling 10.36.10.1 port 22 socket 8
TRACE (6250) 0.002525: update_channel_prio
TRACE (6250) 0.002543: update_channel_prio: not any
TRACE (6250) 0.002560: Dropbear priority transitioning 10 -> 11
TRACE (6250) 0.002612: Couldn't set IPV6_TCLASS (Protocol not available)
TRACE (6250) 0.002620: leave handle_connect_fds - success
TRACE2 (6250) 0.002624: enter cli_sessionloop
(the patch is here)
TRACE2 (6250) 0.002629: enter wait server
TRACE2 (6250) 0.004485: leave wait server: ok
TRACE2 (6250) 0.004521: exit cli_sessionloop: no real packets yet
TRACE2 (6250) 0.004545: enter write_packet
TRACE2 (6250) 0.004571: write_packet writev #0 type 0 len 26/26
TRACE2 (6250) 0.004591: write_packet writev #1 type 20 len 608/608
TRACE2 (6250) 0.004620: write_packet writev #2 type 30 len 48/48
TRACE (6250) 0.004688: empty queue dequeing
TRACE2 (6250) 0.004693: leave write_packet
TRACE2 (6250) 0.004700: update_timeout limit 0, now 19720, last 19720, timeout
28800
TRACE (6250) 0.004707: enter set_connect_fds
TRACE (6250) 0.004716: enter ident_readln
TRACE (6250) 0.004738: leave ident_readln: return 19
TRACE (6250) 0.004743: remoteident: SSH-2.0-Cisco-1.25
TRACE (6250) 0.004749: maybe_empty_reply_queue - no data allowed
TRACE (6250) 0.004754: enter handle_connect_fds
TRACE (6250) 0.004761: leave handle_connect_fds - end iter
TRACE2 (6250) 0.004765: enter cli_sessionloop
TRACE2 (6250) 0.004770: exit cli_sessionloop: no real packets yet
TRACE2 (6250) 0.004777: update_timeout limit 0, now 19720, last 19720, timeout
28800
TRACE (6250) 0.004785: enter set_connect_fds
TRACE2 (6250) 0.006470: enter read_packet
TRACE2 (6250) 0.006512: packet size is 312, block 8 mac 0
TRACE2 (6250) 0.006541: enter decrypt_packet
TRACE2 (6250) 0.006557: leave writemac
TRACE2 (6250) 0.006577: leave decrypt_packet
TRACE2 (6250) 0.006598: leave read_packet
TRACE2 (6250) 0.006617: enter process_packet
TRACE (6250) 0.006638: process_packet: packet type = 20, len 308
TRACE (6250) 0.006661: got expected packet 20 during kexinit
TRACE (6250) 0.006703: <- KEXINIT
diff -Naubr dropbear-2018.76.old/cli-session.c
dropbear-2018.76.new/cli-session.c
--- dropbear-2018.76.old/cli-session.c 2018-02-27 15:25:10.000000000 +0100
+++ dropbear-2018.76.new/cli-session.c 2018-11-16 19:35:07.781047284 +0100
@@ -140,6 +140,7 @@
#endif
static void cli_session_init(pid_t proxy_cmd_pid) {
+ char *wait;
cli_ses.state = STATE_NOTHING;
cli_ses.kex_state = KEX_NOTHING;
@@ -174,6 +175,11 @@
ses.packettypes = cli_packettypes;
ses.isserver = 0;
+ if ((wait = getenv("DROPBEAR_WAIT_SERVER"))) {
+ ses.waitserver = strtol(wait, NULL, 10);
+ } else {
+ ses.waitserver = 0;
+ }
#if DROPBEAR_KEX_FIRST_FOLLOWS
ses.send_kex_first_guess = cli_send_kex_first_guess;
@@ -201,10 +207,23 @@
/* This function drives the progress of the session - it initiates KEX,
* service, userauth and channel requests */
static void cli_sessionloop() {
+ struct timeval wait_to;
+ fd_set wait_fd;
TRACE2(("enter cli_sessionloop"))
if (ses.lastpacket == 0) {
+ /* Wait for the server to speak first, making Cisco SSH servers
happy */
+ if (ses.waitserver > 0) {
+ TRACE2(("enter wait server"))
+ wait_to.tv_sec = ses.waitserver < 600 ? ses.waitserver
: 600;
+ wait_to.tv_usec = 0;
+ FD_ZERO(&wait_fd);
+ FD_SET(ses.sock_in, &wait_fd);
+ ses.waitserver = select(ses.sock_in + 1, &wait_fd, NULL,
NULL, &wait_to);
+ TRACE2(("leave wait server: %s", ses.waitserver > 0 ? "ok" : ses.waitserver
== 0 ? "timeout" : "error"))
+ ses.waitserver = 0;
+ }
TRACE2(("exit cli_sessionloop: no real packets yet"))
return;
}
diff -Naubr dropbear-2018.76.old/session.h dropbear-2018.76.new/session.h
--- dropbear-2018.76.old/session.h 2018-02-27 15:25:12.000000000 +0100
+++ dropbear-2018.76.new/session.h 2018-11-16 19:26:14.372054883 +0100
@@ -105,6 +105,7 @@
/* Is it a client or server? */
unsigned char isserver;
+ time_t waitserver;
time_t connect_time; /* time the connection was established
(cleared after auth
once we're not
diff -Naubr dropbear-2018.76.old/svr-session.c
dropbear-2018.76.new/svr-session.c
--- dropbear-2018.76.old/svr-session.c 2018-02-27 15:25:12.000000000 +0100
+++ dropbear-2018.76.new/svr-session.c 2018-11-16 19:26:46.911688329 +0100
@@ -124,6 +124,7 @@
ses.packettypes = svr_packettypes;
ses.isserver = 1;
+ ses.waitserver = 0;
/* We're ready to go now */
ses.init_done = 1;
--
/\/ / /-<