comparison svr-main.c @ 62:20563735e8b5

just checkpointing
author Matt Johnston <matt@ucc.asn.au>
date Tue, 10 Aug 2004 17:09:52 +0000
parents 223b0f5f8dce
children dcc43965928f
comparison
equal deleted inserted replaced
61:3a4f0ef1e8c3 62:20563735e8b5
27 #include "session.h" 27 #include "session.h"
28 #include "buffer.h" 28 #include "buffer.h"
29 #include "signkey.h" 29 #include "signkey.h"
30 #include "runopts.h" 30 #include "runopts.h"
31 31
32 static int listensockets(int *sock, int *maxfd); 32 static int listensockets(int *sock, int sockcount, int *maxfd);
33 static void sigchld_handler(int dummy); 33 static void sigchld_handler(int dummy);
34 static void sigsegv_handler(int); 34 static void sigsegv_handler(int);
35 static void sigintterm_handler(int fish); 35 static void sigintterm_handler(int fish);
36 36
37 static int childpipes[MAX_UNAUTH_CLIENTS]; 37 static int childpipes[MAX_UNAUTH_CLIENTS];
47 fd_set fds; 47 fd_set fds;
48 struct timeval seltimeout; 48 struct timeval seltimeout;
49 unsigned int i, j; 49 unsigned int i, j;
50 int val; 50 int val;
51 int maxsock = -1; 51 int maxsock = -1;
52 struct sockaddr remoteaddr; 52 struct sockaddr_storage remoteaddr;
53 int remoteaddrlen; 53 int remoteaddrlen;
54 int listensocks[MAX_LISTEN_ADDR]; 54 int listensocks[MAX_LISTEN_ADDR];
55 unsigned int listensockcount = 0; 55 int listensockcount = 0;
56 FILE * pidfile; 56 FILE * pidfile;
57 57
58 int childsock; 58 int childsock;
59 pid_t childpid; 59 pid_t childpid;
60 int childpipe[2]; 60 int childpipe[2];
125 childpipes[i] = -1; 125 childpipes[i] = -1;
126 } 126 }
127 127
128 /* Set up the listening sockets */ 128 /* Set up the listening sockets */
129 /* XXX XXX ports */ 129 /* XXX XXX ports */
130 listensockcount = listensockets(listensocks, &maxsock); 130 listensockcount = listensockets(listensocks, MAX_LISTEN_ADDR, &maxsock);
131 if (listensockcount < 0) {
132 dropbear_exit("No listening ports available.");
133 }
131 134
132 /* incoming connection select loop */ 135 /* incoming connection select loop */
133 for(;;) { 136 for(;;) {
134 137
135 FD_ZERO(&fds); 138 FD_ZERO(&fds);
136 139
137 seltimeout.tv_sec = 60; 140 seltimeout.tv_sec = 60;
138 seltimeout.tv_usec = 0; 141 seltimeout.tv_usec = 0;
139 142
140 /* listening sockets */ 143 /* listening sockets */
141 for (i = 0; i < listensockcount; i++) { 144 for (i = 0; i < (unsigned int)listensockcount; i++) {
142 FD_SET(listensocks[i], &fds); 145 FD_SET(listensocks[i], &fds);
143 } 146 }
144 147
145 /* pre-authentication clients */ 148 /* pre-authentication clients */
146 for (i = 0; i < MAX_UNAUTH_CLIENTS; i++) { 149 for (i = 0; i < MAX_UNAUTH_CLIENTS; i++) {
177 childpipes[i] = -1; 180 childpipes[i] = -1;
178 } 181 }
179 } 182 }
180 183
181 /* handle each socket which has something to say */ 184 /* handle each socket which has something to say */
182 for (i = 0; i < listensockcount; i++) { 185 for (i = 0; i < (unsigned int)listensockcount; i++) {
183 if (!FD_ISSET(listensocks[i], &fds)) 186 if (!FD_ISSET(listensocks[i], &fds))
184 continue; 187 continue;
185 188
186 /* child connection XXX - ip6 stuff here */ 189 /* child connection XXX - ip6 stuff here */
187 remoteaddrlen = sizeof(struct sockaddr_in); 190 remoteaddrlen = sizeof(remoteaddr);
188 childsock = accept(listensocks[i], &remoteaddr, &remoteaddrlen); 191 childsock = accept(listensocks[i], &remoteaddr, &remoteaddrlen);
189 192
190 if (childsock < 0) { 193 if (childsock < 0) {
191 /* accept failed */ 194 /* accept failed */
192 continue; 195 continue;
220 #ifdef DEBUG_FORKGPROF 223 #ifdef DEBUG_FORKGPROF
221 extern void _start(void), etext(void); 224 extern void _start(void), etext(void);
222 monstartup((u_long)&_start, (u_long)&etext); 225 monstartup((u_long)&_start, (u_long)&etext);
223 #endif /* DEBUG_FORKGPROF */ 226 #endif /* DEBUG_FORKGPROF */
224 227
225 addrstring = getaddrstring(&remoteaddr); 228 addrstring = getaddrstring(&remoteaddr, 1);
226 dropbear_log(LOG_INFO, "Child connection from %s", addrstring); 229 dropbear_log(LOG_INFO, "Child connection from %s", addrstring);
227 m_free(addrstring); 230 m_free(addrstring);
228 231
229 if (setsid() < 0) { 232 if (setsid() < 0) {
230 dropbear_exit("setsid: %s", strerror(errno)); 233 dropbear_exit("setsid: %s", strerror(errno));
231 } 234 }
232 235
233 /* make sure we close sockets */ 236 /* make sure we close sockets */
234 for (i = 0; i < listensockcount; i++) { 237 for (i = 0; i < (unsigned int)listensockcount; i++) {
235 if (m_close(listensocks[i]) == DROPBEAR_FAILURE) { 238 if (m_close(listensocks[i]) == DROPBEAR_FAILURE) {
236 dropbear_exit("Couldn't close socket"); 239 dropbear_exit("Couldn't close socket");
237 } 240 }
238 } 241 }
239 242
287 290
288 exitflag = 1; 291 exitflag = 1;
289 } 292 }
290 293
291 /* Set up listening sockets for all the requested ports */ 294 /* Set up listening sockets for all the requested ports */
292 static int listensockets(int *sock, int *maxfd) { 295 static int listensockets(int *sock, int sockcount, int *maxfd) {
293 296
294 int listensock; /* listening fd */
295 struct sockaddr_in listen_addr;
296 struct linger linger;
297 unsigned int i; 297 unsigned int i;
298 int val; 298 char portstring[6];
299 char* errstring = NULL;
300 unsigned int sockpos = 0;
301 int nsock;
299 302
300 for (i = 0; i < svr_opts.portcount; i++) { 303 for (i = 0; i < svr_opts.portcount; i++) {
301 304
302 /* iterate through all the sockets to listen on */ 305 snprintf(portstring, sizeof(portstring), "%d", svr_opts.ports[i]);
303 listensock = socket(PF_INET, SOCK_STREAM, 0); 306 nsock = dropbear_listen(NULL, portstring, &sock[sockpos],
304 if (listensock < 0) { 307 sockcount - sockpos,
305 dropbear_exit("Failed to create socket"); 308 &errstring, maxfd);
306 } 309
307 310 if (nsock < 0) {
308 val = 1; 311 dropbear_log(LOG_WARNING, "Failed listening on port %s: %s",
309 /* set to reuse, quick timeout */ 312 portstring, errstring);
310 setsockopt(listensock, SOL_SOCKET, SO_REUSEADDR, 313 m_free(errstring);
311 (void*) &val, sizeof(val)); 314 continue;
312 linger.l_onoff = 1; 315 }
313 linger.l_linger = 5; 316
314 setsockopt(listensock, SOL_SOCKET, SO_LINGER, 317 sockpos += nsock;
315 (void*)&linger, sizeof(linger)); 318
316 319 }
317 /* disable nagle */ 320 return sockpos;
318 setsockopt(listensock, IPPROTO_TCP, TCP_NODELAY, 321 }
319 (void*)&val, sizeof(val));
320
321 memset((void*)&listen_addr, 0x0, sizeof(listen_addr));
322 listen_addr.sin_family = AF_INET;
323 listen_addr.sin_port = htons(svr_opts.ports[i]);
324 listen_addr.sin_addr.s_addr = htonl(INADDR_ANY);
325 memset(&(listen_addr.sin_zero), '\0', 8);
326
327 if (bind(listensock, (struct sockaddr *)&listen_addr,
328 sizeof(listen_addr)) < 0) {
329 dropbear_exit("Bind failed port %d", svr_opts.ports[i]);
330 }
331
332 /* listen */
333 if (listen(listensock, 20) < 0) { /* TODO set listen count */
334 dropbear_exit("Listen failed");
335 }
336
337 /* nonblock */
338 if (fcntl(listensock, F_SETFL, O_NONBLOCK) < 0) {
339 dropbear_exit("Failed to set non-blocking");
340 }
341
342 sock[i] = listensock;
343 *maxfd = MAX(listensock, *maxfd);
344 }
345
346 return svr_opts.portcount;
347 }