Mercurial > dropbear
diff common-session.c @ 1074:10f198d4a308
Make main socket nonblocking. Limit writequeue size.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 20 Mar 2015 23:36:42 +0800 |
parents | 4c733310c21d |
children | acf444bcb115 |
line wrap: on
line diff
--- a/common-session.c Fri Mar 20 23:33:45 2015 +0800 +++ b/common-session.c Fri Mar 20 23:36:42 2015 +0800 @@ -64,6 +64,13 @@ 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(); @@ -145,6 +152,7 @@ /* 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 +163,12 @@ /* 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 +180,7 @@ 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); @@ -318,9 +330,7 @@ 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); + writebuf_enqueue(writebuf, 0); } static void read_session_identification() {