Mercurial > dropbear
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]; |