Mercurial > dropbear
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 } |