summaryrefslogtreecommitdiffhomepage
path: root/common-session.c
diff options
context:
space:
mode:
Diffstat (limited to 'common-session.c')
-rw-r--r--common-session.c32
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() {