comparison 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
comparison
equal deleted inserted replaced
1073:88043f9d40bd 1074:10f198d4a308
62 62
63 ses.sock_in = sock_in; 63 ses.sock_in = sock_in;
64 ses.sock_out = sock_out; 64 ses.sock_out = sock_out;
65 ses.maxfd = MAX(sock_in, sock_out); 65 ses.maxfd = MAX(sock_in, sock_out);
66 66
67 if (sock_in >= 0) {
68 setnonblocking(sock_in);
69 }
70 if (sock_out >= 0) {
71 setnonblocking(sock_out);
72 }
73
67 ses.socket_prio = DROPBEAR_PRIO_DEFAULT; 74 ses.socket_prio = DROPBEAR_PRIO_DEFAULT;
68 /* Sets it to lowdelay */ 75 /* Sets it to lowdelay */
69 update_channel_prio(); 76 update_channel_prio();
70 77
71 now = monotonic_now(); 78 now = monotonic_now();
143 struct timeval timeout; 150 struct timeval timeout;
144 int val; 151 int val;
145 152
146 /* main loop, select()s for all sockets in use */ 153 /* main loop, select()s for all sockets in use */
147 for(;;) { 154 for(;;) {
155 const int writequeue_has_space = (ses.writequeue_len <= 2*TRANS_MAX_PAYLOAD_LEN);
148 156
149 timeout.tv_sec = select_timeout(); 157 timeout.tv_sec = select_timeout();
150 timeout.tv_usec = 0; 158 timeout.tv_usec = 0;
151 FD_ZERO(&writefd); 159 FD_ZERO(&writefd);
152 FD_ZERO(&readfd); 160 FD_ZERO(&readfd);
153 dropbear_assert(ses.payload == NULL); 161 dropbear_assert(ses.payload == NULL);
154 162
155 /* We delay reading from the input socket during initial setup until 163 /* We delay reading from the input socket during initial setup until
156 after we have written out our initial KEXINIT packet (empty writequeue). 164 after we have written out our initial KEXINIT packet (empty writequeue).
157 This means our initial packet can be in-flight while we're doing a blocking 165 This means our initial packet can be in-flight while we're doing a blocking
158 read for the remote ident */ 166 read for the remote ident.
159 if (ses.sock_in != -1 && (ses.remoteident || isempty(&ses.writequeue))) { 167 We also avoid reading from the socket if the writequeue is full, that avoids
168 replies backing up */
169 if (ses.sock_in != -1
170 && (ses.remoteident || isempty(&ses.writequeue))
171 && writequeue_has_space) {
160 FD_SET(ses.sock_in, &readfd); 172 FD_SET(ses.sock_in, &readfd);
161 } 173 }
162 if (ses.sock_out != -1 && !isempty(&ses.writequeue)) { 174 if (ses.sock_out != -1 && !isempty(&ses.writequeue)) {
163 FD_SET(ses.sock_out, &writefd); 175 FD_SET(ses.sock_out, &writefd);
164 } 176 }
166 /* We get woken up when signal handlers write to this pipe. 178 /* We get woken up when signal handlers write to this pipe.
167 SIGCHLD in svr-chansession is the only one currently. */ 179 SIGCHLD in svr-chansession is the only one currently. */
168 FD_SET(ses.signal_pipe[0], &readfd); 180 FD_SET(ses.signal_pipe[0], &readfd);
169 181
170 /* set up for channels which can be read/written */ 182 /* set up for channels which can be read/written */
171 setchannelfds(&readfd, &writefd); 183 setchannelfds(&readfd, &writefd, writequeue_has_space);
172 184
173 /* Pending connections to test */ 185 /* Pending connections to test */
174 set_connect_fds(&writefd); 186 set_connect_fds(&writefd);
175 187
176 val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout); 188 val = select(ses.maxfd+1, &readfd, &writefd, NULL, &timeout);
316 } 328 }
317 329
318 void send_session_identification() { 330 void send_session_identification() {
319 buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1); 331 buffer *writebuf = buf_new(strlen(LOCAL_IDENT "\r\n") + 1);
320 buf_putbytes(writebuf, LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n")); 332 buf_putbytes(writebuf, LOCAL_IDENT "\r\n", strlen(LOCAL_IDENT "\r\n"));
321 buf_putbyte(writebuf, 0x0); /* packet type */ 333 writebuf_enqueue(writebuf, 0);
322 buf_setpos(writebuf, 0);
323 enqueue(&ses.writequeue, writebuf);
324 } 334 }
325 335
326 static void read_session_identification() { 336 static void read_session_identification() {
327 /* max length of 255 chars */ 337 /* max length of 255 chars */
328 char linebuf[256]; 338 char linebuf[256];