1 #ifdef MULTI_THREADED
2 #ifndef _GNU_SOURCE
3 #define _GNU_SOURCE
4 #endif
5 #include <pthread.h>
6 #include <numa.h>
7 #include <sched.h>
8 #endif
9 
10 #include "server.h"
11 #include "buffer.h"
12 #include "network.h"
13 #include "log.h"
14 #include "keyvalue.h"
15 #include "response.h"
16 #include "request.h"
17 #include "chunk.h"
18 #include "http_chunk.h"
19 #include "fdevent.h"
20 #include "connections.h"
21 #include "stat_cache.h"
22 #include "plugin.h"
23 #include "joblist.h"
24 #include "network_backends.h"
25 #include "version.h"
26 
27 #include <sys/types.h>
28 #include <sys/time.h>
29 #include <sys/stat.h>
30 
31 #include <string.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <stdlib.h>
36 #include <time.h>
37 #include <signal.h>
38 #include <assert.h>
39 #include <locale.h>
40 
41 #include <stdio.h>
42 
43 #ifdef HAVE_GETOPT_H
44 # include <getopt.h>
45 #endif
46 
47 #ifdef HAVE_VALGRIND_VALGRIND_H
48 # include <valgrind/valgrind.h>
49 #endif
50 
51 #ifdef HAVE_SYS_WAIT_H
52 # include <sys/wait.h>
53 #endif
54 
55 #ifdef HAVE_PWD_H
56 # include <grp.h>
57 # include <pwd.h>
58 #endif
59 
60 #ifdef HAVE_SYS_RESOURCE_H
61 # include <sys/resource.h>
62 #endif
63 
64 #ifdef HAVE_SYS_PRCTL_H
65 # include <sys/prctl.h>
66 #endif
67 
68 #ifdef USE_OPENSSL
69 # include <openssl/err.h>
70 #endif
71 /*----------------------------------------------------------------------------*/
72 #ifndef __sgi
73 /* IRIX doesn't like the alarm based time() optimization */
74 /* #define USE_ALARM */
75 #endif
76 
77 #ifdef HAVE_GETUID
78 # ifndef HAVE_ISSETUGID
79 
80 static int
l_issetugid(void)81 l_issetugid(void) {
82 	return (geteuid() != getuid() || getegid() != getgid());
83 }
84 
85 #  define issetugid l_issetugid
86 # endif
87 #endif
88 
89 static volatile sig_atomic_t srv_shutdown = 0;
90 static volatile sig_atomic_t graceful_shutdown = 0;
91 static volatile sig_atomic_t handle_sig_alarm = 1;
92 static volatile sig_atomic_t handle_sig_hup = 0;
93 static volatile sig_atomic_t forwarded_sig_hup = 0;
94 
95 #if defined(HAVE_SIGACTION) && defined(SA_SIGINFO)
96 static volatile siginfo_t last_sigterm_info;
97 static volatile siginfo_t last_sighup_info;
98 /*----------------------------------------------------------------------------*/
99 static void
sigaction_handler(int sig,siginfo_t * si,void * context)100 sigaction_handler(int sig, siginfo_t *si, void *context) {
101 	static siginfo_t empty_siginfo;
102 	UNUSED(context);
103 
104 	if (!si) si = &empty_siginfo;
105 
106 	switch (sig) {
107 	case SIGTERM:
108 		srv_shutdown = 1;
109 		last_sigterm_info = *si;
110 		break;
111 	case SIGINT:
112 		if (graceful_shutdown) {
113 			srv_shutdown = 1;
114 		} else {
115 			graceful_shutdown = 1;
116 		}
117 		last_sigterm_info = *si;
118 
119 		break;
120 	case SIGALRM:
121 		handle_sig_alarm = 1;
122 		break;
123 	case SIGHUP:
124 		/**
125 		 * we send the SIGHUP to all procs in the process-group
126 		 * this includes ourself
127 		 *
128 		 * make sure we only send it once and don't create a
129 		 * infinite loop
130 		 */
131 		if (!forwarded_sig_hup) {
132 			handle_sig_hup = 1;
133 			last_sighup_info = *si;
134 		} else {
135 			forwarded_sig_hup = 0;
136 		}
137 		break;
138 	case SIGCHLD:
139 		break;
140 	}
141 }
142 /*----------------------------------------------------------------------------*/
143 #elif defined(HAVE_SIGNAL) || defined(HAVE_SIGACTION)
144 static void
signal_handler(int sig)145 signal_handler(int sig) {
146 	switch (sig) {
147 	case SIGTERM: srv_shutdown = 1; break;
148 	case SIGINT:
149 	     if (graceful_shutdown) srv_shutdown = 1;
150 	     else graceful_shutdown = 1;
151 	     break;
152 	case SIGALRM: handle_sig_alarm = 1; break;
153 	case SIGHUP:  handle_sig_hup = 1; break;
154 	case SIGCHLD:  break;
155 	}
156 }
157 #endif
158 /*----------------------------------------------------------------------------*/
159 #ifdef MULTI_THREADED
160 /* TODO - signal handling logic will be revised in future revisions */
161 static void
signal_handler(int sig)162 signal_handler(int sig) {
163 	switch (sig) {
164 	case SIGTERM: srv_shutdown = 1; break;
165 	case SIGINT:
166 		if (graceful_shutdown) srv_shutdown = 1;
167 		else graceful_shutdown = 1;
168 
169 		break;
170 	case SIGALRM: handle_sig_alarm = 1; break;
171 	case SIGHUP:  handle_sig_hup = 1; break;
172 	case SIGCHLD:  break;
173 	}
174 #ifdef HAVE_LIBDPDK
175         exit(EXIT_SUCCESS);
176 #endif
177 }
178 #endif
179 /*----------------------------------------------------------------------------*/
180 #ifdef HAVE_FORK
181 static void
daemonize(void)182 daemonize(void) {
183 #ifdef SIGTTOU
184 	signal(SIGTTOU, SIG_IGN);
185 #endif
186 #ifdef SIGTTIN
187 	signal(SIGTTIN, SIG_IGN);
188 #endif
189 #ifdef SIGTSTP
190 	signal(SIGTSTP, SIG_IGN);
191 #endif
192 	if (0 != fork()) exit(EXIT_SUCCESS);
193 
194 	if (-1 == setsid()) exit(EXIT_SUCCESS);
195 
196 	signal(SIGHUP, SIG_IGN);
197 
198 	if (0 != fork()) exit(EXIT_SUCCESS);
199 
200 	if (0 != chdir("/")) exit(EXIT_SUCCESS);
201 }
202 #endif
203 /*----------------------------------------------------------------------------*/
204 static server *
server_init(void)205 server_init(void) {
206 	int i;
207 	FILE *frandom = NULL;
208 
209 	server *srv = calloc(1, sizeof(*srv));
210 	assert(srv);
211 #define CLEAN(x)				\
212 	srv->x = buffer_init();
213 
214 	CLEAN(response_header);
215 	CLEAN(parse_full_path);
216 	CLEAN(ts_debug_str);
217 	CLEAN(ts_date_str);
218 	CLEAN(errorlog_buf);
219 	CLEAN(response_range);
220 	CLEAN(tmp_buf);
221 	srv->empty_string = buffer_init_string("");
222 	CLEAN(cond_check_buf);
223 
224 	CLEAN(srvconf.errorlog_file);
225 	CLEAN(srvconf.breakagelog_file);
226 	CLEAN(srvconf.groupname);
227 	CLEAN(srvconf.username);
228 	CLEAN(srvconf.changeroot);
229 	CLEAN(srvconf.bindhost);
230 	CLEAN(srvconf.event_handler);
231 	CLEAN(srvconf.pid_file);
232 
233 	CLEAN(tmp_chunk_len);
234 #undef CLEAN
235 
236 #define CLEAN(x) \
237 	srv->x = array_init();
238 
239 	CLEAN(config_context);
240 	CLEAN(config_touched);
241 	CLEAN(status);
242 #undef CLEAN
243 
244 	for (i = 0; i < FILE_CACHE_MAX; i++) {
245 		srv->mtime_cache[i].mtime = (time_t)-1;
246 		srv->mtime_cache[i].str = buffer_init();
247 	}
248 
249 	if ((NULL != (frandom = fopen("/dev/urandom", "rb")) || NULL != (frandom = fopen("/dev/random", "rb")))
250 	            && 1 == fread(srv->entropy, sizeof(srv->entropy), 1, frandom)) {
251 		unsigned int e;
252 		memcpy(&e, srv->entropy, sizeof(e) < sizeof(srv->entropy) ? sizeof(e) : sizeof(srv->entropy));
253 		srand(e);
254 		srv->is_real_entropy = 1;
255 	} else {
256 		unsigned int j;
257 		srand(time(NULL) ^ getpid());
258 		srv->is_real_entropy = 0;
259 		for (j = 0; j < sizeof(srv->entropy); j++)
260 			srv->entropy[j] = rand();
261 	}
262 	if (frandom) fclose(frandom);
263 
264 	srv->cur_ts = time(NULL);
265 	srv->startup_ts = srv->cur_ts;
266 
267 	srv->conns = calloc(1, sizeof(*srv->conns));
268 	assert(srv->conns);
269 
270 	srv->joblist = calloc(1, sizeof(*srv->joblist));
271 	assert(srv->joblist);
272 
273 	srv->fdwaitqueue = calloc(1, sizeof(*srv->fdwaitqueue));
274 	assert(srv->fdwaitqueue);
275 
276 	srv->srvconf.modules = array_init();
277 	srv->srvconf.modules_dir = buffer_init_string(LIBRARY_DIR);
278 	srv->srvconf.network_backend = buffer_init();
279 	srv->srvconf.upload_tempdirs = array_init();
280 	srv->srvconf.reject_expect_100_with_417 = 1;
281 
282 	/* use syslog */
283 	srv->errorlog_fd = STDERR_FILENO;
284 	srv->errorlog_mode = ERRORLOG_FD;
285 
286 	srv->split_vals = array_init();
287 
288 	return srv;
289 }
290 /*----------------------------------------------------------------------------*/
291 static void
server_free(server * srv)292 server_free(server *srv) {
293 	size_t i;
294 
295 	for (i = 0; i < FILE_CACHE_MAX; i++) {
296 		buffer_free(srv->mtime_cache[i].str);
297 	}
298 
299 #define CLEAN(x) \
300 	buffer_free(srv->x);
301 
302 	CLEAN(response_header);
303 	CLEAN(parse_full_path);
304 	CLEAN(ts_debug_str);
305 	CLEAN(ts_date_str);
306 	CLEAN(errorlog_buf);
307 	CLEAN(response_range);
308 	CLEAN(tmp_buf);
309 	CLEAN(empty_string);
310 	CLEAN(cond_check_buf);
311 
312 	CLEAN(srvconf.errorlog_file);
313 	CLEAN(srvconf.breakagelog_file);
314 	CLEAN(srvconf.groupname);
315 	CLEAN(srvconf.username);
316 	CLEAN(srvconf.changeroot);
317 	CLEAN(srvconf.bindhost);
318 	CLEAN(srvconf.event_handler);
319 	CLEAN(srvconf.pid_file);
320 	CLEAN(srvconf.modules_dir);
321 	CLEAN(srvconf.network_backend);
322 
323 	CLEAN(tmp_chunk_len);
324 #undef CLEAN
325 
326 #if 0
327 	fdevent_unregister(srv->ev, srv->fd);
328 #endif
329 	fdevent_free(srv->ev);
330 
331 	free(srv->conns);
332 
333 	if (srv->config_storage) {
334 		for (i = 0; i < srv->config_context->used; i++) {
335 			specific_config *s = srv->config_storage[i];
336 
337 			if (!s) continue;
338 
339 			buffer_free(s->document_root);
340 			buffer_free(s->server_name);
341 			buffer_free(s->server_tag);
342 			buffer_free(s->ssl_pemfile);
343 			buffer_free(s->ssl_ca_file);
344 			buffer_free(s->ssl_cipher_list);
345 			buffer_free(s->ssl_dh_file);
346 			buffer_free(s->ssl_ec_curve);
347 			buffer_free(s->error_handler);
348 			buffer_free(s->errorfile_prefix);
349 			array_free(s->mimetypes);
350 			buffer_free(s->ssl_verifyclient_username);
351 #ifdef USE_OPENSSL
352 			SSL_CTX_free(s->ssl_ctx);
353 #endif
354 			free(s);
355 		}
356 		free(srv->config_storage);
357 		srv->config_storage = NULL;
358 	}
359 
360 #define CLEAN(x) \
361 	array_free(srv->x);
362 
363 	CLEAN(config_context);
364 	CLEAN(config_touched);
365 	CLEAN(status);
366 	CLEAN(srvconf.upload_tempdirs);
367 #undef CLEAN
368 
369 	joblist_free(srv, srv->joblist);
370 	fdwaitqueue_free(srv, srv->fdwaitqueue);
371 
372 	if (srv->stat_cache) {
373 		stat_cache_free(srv->stat_cache);
374 	}
375 
376 	array_free(srv->srvconf.modules);
377 	array_free(srv->split_vals);
378 
379 #ifdef USE_OPENSSL
380 	if (srv->ssl_is_init) {
381 		CRYPTO_cleanup_all_ex_data();
382 		ERR_free_strings();
383 		ERR_remove_state(0);
384 		EVP_cleanup();
385 	}
386 #endif
387 
388 	free(srv);
389 }
390 /*----------------------------------------------------------------------------*/
391 static inline void
load_plugins(server * srv)392 load_plugins(server *srv)
393 {
394 	if (HANDLER_GO_ON != plugins_call_init(srv)) {
395 		log_error_write(srv, __FILE__, __LINE__, "s",
396 				"Initialization of plugins failed. Going down.");
397 		exit(EXIT_FAILURE);
398 	}
399 
400 }
401 /*----------------------------------------------------------------------------*/
402 static inline void
set_max_conns(server * srv,int restrict_limit)403 set_max_conns(server *srv, int restrict_limit)
404 {
405 	if (restrict_limit) {
406 		if (srv->srvconf.max_conns > srv->max_fds/2) {
407 			/* we can't have more connections than max-fds/2 */
408 			log_error_write(srv, __FILE__, __LINE__, "sdd",
409 					"can't have more connections than fds/2: ",
410 					srv->srvconf.max_conns, srv->max_fds);
411 			srv->max_conns = srv->max_fds/2;
412 		} else if (srv->srvconf.max_conns) {
413 			/* otherwise respect the wishes of the user */
414 			srv->max_conns = srv->srvconf.max_conns;
415 		} else {
416 			/* or use the default: we really don't want to hit max-fds */
417 			srv->max_conns = srv->max_fds/3;
418 		}
419 	} else {
420 		srv->max_conns = srv->srvconf.max_conns;
421 	}
422 }
423 /*----------------------------------------------------------------------------*/
424 static inline void
initialize_fd_framework(server * srv)425 initialize_fd_framework(server *srv)
426 {
427 	size_t i;
428 
429 	/* the 2nd arg of fdevent_init in case of libmtcp is ignored */
430 	if (NULL == (srv->ev = fdevent_init(srv, srv->max_fds + 1, srv->event_handler))) {
431 		log_error_write(srv, __FILE__, __LINE__,
432 				"s", "fdevent_init failed");
433 		exit(EXIT_FAILURE);
434 	}
435 
436 	/*
437 	 * kqueue() is called here, select resets its internals,
438 	 * all server sockets get their handlers
439 	 *
440 	 * */
441 	if (0 != network_register_fdevents(srv)) {
442 		exit(EXIT_FAILURE);
443 	}
444 
445 	/* might fail if user is using fam (not gamin) and famd isn't running */
446 	if (NULL == (srv->stat_cache = stat_cache_init())) {
447 		log_error_write(srv, __FILE__, __LINE__, "s",
448 			"stat-cache could not be setup, dieing.");
449 		exit(EXIT_FAILURE);
450 	}
451 
452 #ifdef HAVE_FAM_H
453 i hope this does not work
454 	/* setup FAM */
455 	if (srv->srvconf.stat_cache_engine == STAT_CACHE_ENGINE_FAM) {
456 		if (0 != FAMOpen2(srv->stat_cache->fam, "lighttpd")) {
457 			log_error_write(srv, __FILE__, __LINE__, "s",
458 					 "could not open a fam connection, dieing.");
459 			exit(EXIT_FAILURE);
460 		}
461 #ifdef HAVE_FAMNOEXISTS
462 		FAMNoExists(srv->stat_cache->fam);
463 #endif
464 
465 		srv->stat_cache->fam_fcce_ndx = -1;
466 		fdevent_register(srv->ev, FAMCONNECTION_GETFD(srv->stat_cache->fam), stat_cache_handle_fdevent, NULL);
467 		fdevent_event_set(srv->ev, &(srv->stat_cache->fam_fcce_ndx), FAMCONNECTION_GETFD(srv->stat_cache->fam), FDEVENT_IN);
468 	}
469 #endif
470 
471 
472 	/* get the current number of FDs */
473 	srv->cur_fds = open("/dev/null", O_RDONLY);
474 	close(srv->cur_fds);
475 
476 	for (i = 0; i < srv->srv_sockets.used; i++) {
477 		server_socket *srv_socket = srv->srv_sockets.ptr[i];
478 		if (-1 == fdevent_fcntl_set(srv->ev, srv_socket->fd)) {
479 			log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed:", strerror(errno));
480 			exit(EXIT_FAILURE);
481 		}
482 	}
483 }
484 /*----------------------------------------------------------------------------*/
485 #ifdef MULTI_THREADED
486 #ifdef USE_MTCP
487 static inline void
set_listen_backlog(server * srv)488 set_listen_backlog(server *srv)
489 {
490 	fprintf(stderr, "Applying listen_backlog: %d\n", srv->srvconf.listen_backlog);
491 	srv->listen_backlog = srv->srvconf.listen_backlog;
492 }
493 #endif
494 /*----------------------------------------------------------------------------*/
495 int
core_affinitize(int cpu)496 core_affinitize(int cpu)
497 {
498 	cpu_set_t *cmask;
499 	struct bitmask *bmask;
500 	size_t n;
501 	int ret;
502 
503 	n = sysconf(_SC_NPROCESSORS_ONLN);
504 
505 	if (cpu < 0 || cpu >= (int) n) {
506 		errno = -EINVAL;
507 		return -1;
508 	}
509 
510 	cmask = CPU_ALLOC(n);
511 	if (cmask == NULL)
512 		return -1;
513 
514 	CPU_ZERO_S(n, cmask);
515 	CPU_SET_S(cpu, n, cmask);
516 
517 	ret = sched_setaffinity(0, n, cmask);
518 
519 	CPU_FREE(cmask);
520 
521 	if (numa_max_node() == 0)
522 		return ret;
523 
524 	bmask = numa_bitmask_alloc(16);
525 	assert(bmask);
526 
527 	numa_bitmask_setbit(bmask, cpu % 2);
528 	numa_set_membind(bmask);
529 	numa_bitmask_free(bmask);
530 
531 	return ret;
532 }
533 /*----------------------------------------------------------------------------*/
534 static int
get_num_cpus(const char * strnum)535 get_num_cpus(const char *strnum)
536 {
537 	return strtol(strnum, (char **) NULL, 10);
538 }
539 /*----------------------------------------------------------------------------*/
540 static void
init_server_states(server *** srv_states,int cpus,server * first_entry,const char * conf_file)541 init_server_states(server ***srv_states, int cpus,
542 		   server *first_entry, const char *conf_file)
543 {
544 	int i;
545 
546 	/* initialize the array */
547 	*srv_states = (server **)calloc(cpus, sizeof(server *));
548 	if (NULL == *srv_states) {
549 		fprintf(stderr, "%s: %d(%s) - Can't allocate memory for srv_states\n",
550 			__FUNCTION__, __LINE__, __FILE__);
551 		exit(EXIT_FAILURE);
552 	}
553 	/* put the first entry on index 0 */
554 	(*srv_states)[0] = first_entry;
555 #if !(defined USE_MTCP || defined REUSEPORT)
556 	//#ifndef USE_MTCP
557 	((*srv_states)[0])->first_entry = first_entry;
558 #else
559 #ifdef USE_MTCP
560 	/* set listen-backlog */
561 	set_listen_backlog(first_entry);
562 #endif
563 #endif
564 
565 	/* now do the same for all remaining reserved cpus */
566 	for (i = 1; i < cpus; i++) {
567 		/* initialize it */
568 		if (NULL == ((*srv_states)[i] = server_init())) {
569 			fprintf(stderr, "%s: %d(%s) - Can't allocate memory for %dth srv_state entry\n",
570 				__FUNCTION__, __LINE__, __FILE__, i);
571 			goto release_everything;
572 		}
573 		((*srv_states)[i])->srvconf.port = 0;
574 		((*srv_states)[i])->srvconf.dont_daemonize =
575 			first_entry->srvconf.dont_daemonize;
576 #if !(defined USE_MTCP || defined REUSEPORT)
577 		//#ifndef USE_MTCP
578 		((*srv_states)[i])->first_entry = first_entry;
579 #endif
580 
581 		/* set the struct by reading the conf file again... */
582 		if (config_read(((*srv_states)[i]), conf_file))
583 			goto release_everything;
584 		buffer_copy_string(((*srv_states)[i])->srvconf.modules_dir,
585 				   first_entry->srvconf.modules_dir->ptr);
586 		/* ... and set the remaining as default. */
587 		if (0 != config_set_defaults((*srv_states)[i])) {
588 			log_error_write((*srv_states)[i], __FILE__, __LINE__, "s",
589 					"setting default values failed");
590 			goto release_everything;
591 		}
592 		/* load the plugins... i hope it doesn't mess things up */
593 		if (plugins_load((*srv_states)[i])) {
594 			log_error_write((*srv_states)[i], __FILE__, __LINE__, "s",
595 					"loading plugins finally failed");
596 			goto release_everything;
597 		}
598 		/* clone max_fds as well */
599 		((*srv_states)[i])->max_fds = first_entry->max_fds;
600 		/* clone max_conns as well */
601 		((*srv_states)[i])->max_conns = first_entry->max_conns;
602 #ifdef USE_MTCP
603 		/* clone listen backlog limit */
604 		((*srv_states)[i])->listen_backlog = first_entry->listen_backlog;
605 #endif
606 	}
607 	return;
608  release_everything:
609 	/* release everything in reverse then */
610 	while (i >= 0) {
611 		server_free((*srv_states)[i]);
612 		plugins_free((*srv_states)[i]);
613 		i--;
614 	}
615 	free(*srv_states);
616 	exit(EXIT_FAILURE);
617 }
618 /*----------------------------------------------------------------------------*/
619 void *
start_server(void * svrptr)620 start_server(void *svrptr)
621 {
622 	server *srv = (server *)svrptr;
623 	size_t cpu = srv->cpu;
624 	size_t i;
625 
626 	/* affinitize server to core `cpu' */
627 	core_affinitize(cpu);
628 
629 #ifdef USE_MTCP
630 	/* initialize the per-cpu mctx context */
631 	/* creating mtcp context first */
632 	srv->mctx = mtcp_create_context(cpu);
633 	if (!srv->mctx) {
634 		fprintf(stderr, "Failed to create mtcp context!\n");
635 		exit(EXIT_FAILURE);
636 	}
637 
638 	/* adjust max fds to max_conns * 3 */
639 	srv->max_fds = srv->max_conns * 3;
640 #else
641 	/* register SIGINT signal handler */
642 	signal(SIGINT, signal_handler);
643 
644 #endif /* !USE_MTCP */
645 
646 	/* network backend initialization */
647 	if (network_init(srv) == -1)
648 		exit(EXIT_FAILURE);
649 #ifdef USE_MTCP
650 	set_max_conns(srv, 0);
651 #else
652 	set_max_conns(srv, 1);
653 #endif
654 	load_plugins(srv);
655 
656 	/* Close stderr ASAP in the child process to make sure that nothing
657 	 * is being written to that fd which may not be valid anymore. */
658 	if (-1 == log_error_open(srv)) {
659 		log_error_write(srv, __FILE__, __LINE__, "s",
660 				"Opening errorlog failed. Going down.");
661 		exit(EXIT_FAILURE);
662 	}
663 
664 	if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
665 		log_error_write(srv, __FILE__, __LINE__, "s",
666 				"Configuration of plugins failed. Going down.");
667 		exit(EXIT_FAILURE);
668 	}
669 
670 	/* register fdevent framework first */
671 	initialize_fd_framework(srv);
672 
673 	/* and... finally the 'main-loop' */
674 	/*-------------------------------------------------------------------------------*/
675 	/* main-loop */
676 	while (!srv_shutdown) {
677 		int n;
678 		size_t ndx;
679 		time_t min_ts;
680 
681 		if (handle_sig_hup) {
682 			handler_t r;
683 
684 			/* reset notification */
685 			handle_sig_hup = 0;
686 
687 
688 			/* cycle logfiles */
689 
690 			switch(r = plugins_call_handle_sighup(srv)) {
691 			case HANDLER_GO_ON:
692 				break;
693 			default:
694 				log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
695 				break;
696 			}
697 
698 			if (-1 == log_error_cycle(srv)) {
699 				log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
700 
701 				exit(EXIT_FAILURE);
702 			} else {
703 #ifdef HAVE_SIGACTION
704 				log_error_write(srv, __FILE__, __LINE__, "sdsd",
705 					"logfiles cycled UID =",
706 					last_sighup_info.si_uid,
707 					"PID =",
708 					last_sighup_info.si_pid);
709 #else
710 				log_error_write(srv, __FILE__, __LINE__, "s",
711 					"logfiles cycled");
712 #endif
713 			}
714 		}
715 
716 		if (handle_sig_alarm) {
717 			/* a new second */
718 
719 #ifdef USE_ALARM
720 			/* reset notification */
721 			handle_sig_alarm = 0;
722 #endif
723 
724 			/* get current time */
725 			min_ts = time(NULL);
726 
727 			if (min_ts != srv->cur_ts) {
728 				int cs = 0;
729 				connections *conns = srv->conns;
730 				handler_t r;
731 
732 				switch(r = plugins_call_handle_trigger(srv)) {
733 				case HANDLER_GO_ON:
734 					break;
735 				case HANDLER_ERROR:
736 					log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
737 					break;
738 				default:
739 					log_error_write(srv, __FILE__, __LINE__, "d", r);
740 					break;
741 				}
742 
743 				/* trigger waitpid */
744 				srv->cur_ts = min_ts;
745 
746 				/* cleanup stat-cache */
747 				stat_cache_trigger_cleanup(srv);
748 				/**
749 				 * check all connections for timeouts
750 				 *
751 				 */
752 				for (ndx = 0; ndx < conns->used; ndx++) {
753 					int changed = 0;
754 					connection *con;
755 					int t_diff;
756 
757 					con = conns->ptr[ndx];
758 
759 					if (con->state == CON_STATE_READ ||
760 					    con->state == CON_STATE_READ_POST) {
761 						if (con->request_count == 1) {
762 							if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
763 								/* time - out */
764 #if 0
765 								log_error_write(srv, __FILE__, __LINE__, "sd",
766 										"connection closed - read-timeout:", con->fd);
767 #endif
768 								connection_set_state(srv, con, CON_STATE_ERROR);
769 								changed = 1;
770 							}
771 						} else {
772 							if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
773 								/* time - out */
774 #if 0
775 								log_error_write(srv, __FILE__, __LINE__, "sd",
776 										"connection closed - read-timeout:", con->fd);
777 #endif
778 								connection_set_state(srv, con, CON_STATE_ERROR);
779 								changed = 1;
780 							}
781 						}
782 					}
783 
784 					if ((con->state == CON_STATE_WRITE) &&
785 					    (con->write_request_ts != 0)) {
786 #if 0
787 						if (srv->cur_ts - con->write_request_ts > 60) {
788 							log_error_write(srv, __FILE__, __LINE__, "sdd",
789 									"connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
790 						}
791 #endif
792 
793 						if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
794 							/* time - out */
795 							if (con->conf.log_timeouts) {
796 								log_error_write(srv, __FILE__, __LINE__, "sbsosds",
797 									"NOTE: a request for",
798 									con->request.uri,
799 									"timed out after writing",
800 									con->bytes_written,
801 									"bytes. We waited",
802 									(int)con->conf.max_write_idle,
803 									"seconds. If this a problem increase server.max-write-idle");
804 							}
805 							connection_set_state(srv, con, CON_STATE_ERROR);
806 							changed = 1;
807 						}
808 					}
809 
810 					if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
811 						changed = 1;
812 					}
813 
814 					/* we don't like div by zero */
815 					if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
816 
817 					if (con->traffic_limit_reached &&
818 					    (con->conf.kbytes_per_second == 0 ||
819 					     ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
820 						/* enable connection again */
821 						con->traffic_limit_reached = 0;
822 
823 						changed = 1;
824 					}
825 
826 					if (changed) {
827 						connection_state_machine(srv, con);
828 					}
829 					con->bytes_written_cur_second = 0;
830 					*(con->conf.global_bytes_per_second_cnt_ptr) = 0;
831 
832 #if 0
833 					if (cs == 0) {
834 						fprintf(stderr, "connection-state: ");
835 						cs = 1;
836 					}
837 
838 					fprintf(stderr, "c[%d,%d]: %s ",
839 						con->fd,
840 						con->fcgi.fd,
841 						connection_get_state(con->state));
842 #endif
843 				}
844 
845 				if (cs == 1) fprintf(stderr, "\n");
846 			}
847 		}
848 
849 		if (srv->sockets_disabled) {
850 			/* our server sockets are disabled, why ? */
851 
852 			if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
853 			    (srv->conns->used <= srv->max_conns * 9 / 10) &&
854 			    (0 == graceful_shutdown)) {
855 				for (i = 0; i < srv->srv_sockets.used; i++) {
856 					server_socket *srv_socket = srv->srv_sockets.ptr[i];
857 					fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
858 				}
859 
860 				log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
861 
862 				srv->sockets_disabled = 0;
863 			}
864 		} else {
865 			if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
866 			    (srv->conns->used >= srv->max_conns) || /* out of connections */
867 			    (graceful_shutdown)) { /* graceful_shutdown */
868 
869 				/* disable server-fds */
870 
871 				for (i = 0; i < srv->srv_sockets.used; i++) {
872 					server_socket *srv_socket = srv->srv_sockets.ptr[i];
873 					fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
874 
875 					if (graceful_shutdown) {
876 						/* we don't want this socket anymore,
877 						 *
878 						 * closing it right away will make it possible for
879 						 * the next lighttpd to take over (graceful restart)
880 						 *  */
881 
882 						fdevent_unregister(srv->ev, srv_socket->fd);
883 #ifdef USE_MTCP
884 						mtcp_close(srv->mctx, srv_socket->fd);
885 #else
886 						close(srv_socket->fd);
887 #endif
888 						srv_socket->fd = -1;
889 
890 						/* network_close() will cleanup after us */
891 
892 						if (srv->srvconf.pid_file->used &&
893 						    srv->srvconf.changeroot->used == 0) {
894 							if (0 != unlink(srv->srvconf.pid_file->ptr)) {
895 								if (errno != EACCES && errno != EPERM) {
896 									log_error_write(srv, __FILE__, __LINE__, "sbds",
897 											"unlink failed for:",
898 											srv->srvconf.pid_file,
899 											errno,
900 											strerror(errno));
901 								}
902 							}
903 						}
904 					}
905 				}
906 
907 				if (graceful_shutdown) {
908 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
909 				} else if (srv->conns->used >= srv->max_conns) {
910 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
911 				} else {
912 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
913 				}
914 
915 				srv->sockets_disabled = 1;
916 			}
917 		}
918 
919 		if (graceful_shutdown && srv->conns->used == 0) {
920 			/* we are in graceful shutdown phase and all connections are closed
921 			 * we are ready to terminate without harming anyone */
922 			srv_shutdown = 1;
923 		}
924 
925 		/* we still have some fds to share */
926 		if (srv->want_fds) {
927 			/* check the fdwaitqueue for waiting fds */
928 			int free_fds = srv->max_fds - srv->cur_fds - 16;
929 			connection *con;
930 
931 			for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
932 				connection_state_machine(srv, con);
933 
934 				srv->want_fds--;
935 			}
936 		}
937 
938 		if ((n = fdevent_poll(srv->ev, -1/*1000*/)) > 0) {
939 			/* n is the number of events */
940 			int revents;
941 			int fd_ndx;
942 #if 0
943 			if (n > 0) {
944 				log_error_write(srv, __FILE__, __LINE__, "sd",
945 						"polls:", n);
946 			}
947 #endif
948 			fd_ndx = -1;
949 			do {
950 				fdevent_handler handler;
951 				void *context;
952 				handler_t r;
953 				int fd;
954 
955 				fd_ndx  = fdevent_event_next_fdndx (srv->ev, fd_ndx);
956 				if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
957 
958 				revents = fdevent_event_get_revent (srv->ev, fd_ndx);
959 				fd      = fdevent_event_get_fd     (srv->ev, fd_ndx);
960 				handler = fdevent_get_handler(srv->ev, fd);
961 				context = fdevent_get_context(srv->ev, fd);
962 
963 				/* connection_handle_fdevent needs a joblist_append */
964 #if 0
965 				log_error_write(srv, __FILE__, __LINE__, "sdd",
966 						"event for", fd, revents);
967 #endif
968 				switch (r = (*handler)(srv, context, revents)) {
969 				case HANDLER_FINISHED:
970 				case HANDLER_GO_ON:
971 				case HANDLER_WAIT_FOR_EVENT:
972 				case HANDLER_WAIT_FOR_FD:
973 					break;
974 				case HANDLER_ERROR:
975 					/* should never happen */
976 					SEGFAULT();
977 					break;
978 				default:
979 					log_error_write(srv, __FILE__, __LINE__, "d", r);
980 					break;
981 				}
982 			} while (--n > 0);
983 		} else if (n < 0 && errno != EINTR) {
984 			log_error_write(srv, __FILE__, __LINE__, "ss",
985 					"fdevent_poll failed:",
986 					strerror(errno));
987 		}
988 
989 		for (ndx = 0; ndx < srv->joblist->used; ndx++) {
990 			connection *con = srv->joblist->ptr[ndx];
991 			handler_t r;
992 
993 			connection_state_machine(srv, con);
994 
995 			switch(r = plugins_call_handle_joblist(srv, con)) {
996 			case HANDLER_FINISHED:
997 			case HANDLER_GO_ON:
998 				break;
999 			default:
1000 				log_error_write(srv, __FILE__, __LINE__, "d", r);
1001 				break;
1002 			}
1003 
1004 			con->in_joblist = 0;
1005 		}
1006 
1007 		srv->joblist->used = 0;
1008 	} /* end of `while (!srv_shutdown)` */
1009 	/*-------------------------------------------------------------------------------*/
1010 #ifdef USE_MTCP
1011 	/* TODO - this will go somewhere else */
1012 	mtcp_destroy_context(srv->mctx);
1013 #endif
1014 	pthread_exit(NULL);
1015 
1016 	return NULL;
1017 }
1018 #endif /* !MULTI_THREADED */
1019 /*----------------------------------------------------------------------------*/
1020 static void
show_version(void)1021 show_version (void) {
1022 #ifdef USE_OPENSSL
1023 # define TEXT_SSL " (ssl)"
1024 #else
1025 # define TEXT_SSL
1026 #endif
1027 	char *b = PACKAGE_DESC TEXT_SSL \
1028 " - a light and fast webserver\n" \
1029 "Build-Date: " __DATE__ " " __TIME__ "\n";
1030 ;
1031 #undef TEXT_SSL
1032 	write(STDOUT_FILENO, b, strlen(b));
1033 }
1034 /*----------------------------------------------------------------------------*/
1035 static void
show_features(void)1036 show_features(void) {
1037 	const char features[] = ""
1038 #ifdef USE_SELECT
1039 		"\t+ select (generic)\n"
1040 #else
1041 		"\t- select (generic)\n"
1042 #endif
1043 #ifdef USE_POLL
1044 		"\t+ poll (Unix)\n"
1045 #else
1046 		"\t- poll (Unix)\n"
1047 #endif
1048 #ifdef USE_LINUX_SIGIO
1049 		"\t+ rt-signals (Linux 2.4+)\n"
1050 #else
1051 		"\t- rt-signals (Linux 2.4+)\n"
1052 #endif
1053 #ifdef USE_LINUX_EPOLL
1054 		"\t+ epoll (Linux 2.6)\n"
1055 #else
1056 		"\t- epoll (Linux 2.6)\n"
1057 #endif
1058 #ifdef USE_SOLARIS_DEVPOLL
1059 		"\t+ /dev/poll (Solaris)\n"
1060 #else
1061 		"\t- /dev/poll (Solaris)\n"
1062 #endif
1063 #ifdef USE_SOLARIS_PORT
1064 		"\t+ eventports (Solaris)\n"
1065 #else
1066 		"\t- eventports (Solaris)\n"
1067 #endif
1068 #ifdef USE_FREEBSD_KQUEUE
1069 		"\t+ kqueue (FreeBSD)\n"
1070 #else
1071 		"\t- kqueue (FreeBSD)\n"
1072 #endif
1073 #ifdef USE_LIBEV
1074 		"\t+ libev (generic)\n"
1075 #else
1076 		"\t- libev (generic)\n"
1077 #endif
1078 		"\nNetwork handler:\n\n"
1079 #if defined USE_LINUX_SENDFILE
1080 		"\t+ linux-sendfile\n"
1081 #else
1082 		"\t- linux-sendfile\n"
1083 #endif
1084 #if defined USE_FREEBSD_SENDFILE
1085 		"\t+ freebsd-sendfile\n"
1086 #else
1087 		"\t- freebsd-sendfile\n"
1088 #endif
1089 #if defined USE_SOLARIS_SENDFILEV
1090 		"\t+ solaris-sendfilev\n"
1091 #else
1092 		"\t- solaris-sendfilev\n"
1093 #endif
1094 #if defined USE_WRITEV
1095 		"\t+ writev\n"
1096 #else
1097 		"\t- writev\n"
1098 #endif
1099 		"\t+ write\n"
1100 #ifdef USE_MMAP
1101 		"\t+ mmap support\n"
1102 #else
1103 		"\t- mmap support\n"
1104 #endif
1105 		"\nFeatures:\n\n"
1106 #ifdef HAVE_IPV6
1107 		"\t+ IPv6 support\n"
1108 #else
1109 		"\t- IPv6 support\n"
1110 #endif
1111 #if defined HAVE_ZLIB_H && defined HAVE_LIBZ
1112 		"\t+ zlib support\n"
1113 #else
1114 		"\t- zlib support\n"
1115 #endif
1116 #if defined HAVE_BZLIB_H && defined HAVE_LIBBZ2
1117 		"\t+ bzip2 support\n"
1118 #else
1119 		"\t- bzip2 support\n"
1120 #endif
1121 #ifdef HAVE_LIBCRYPT
1122 		"\t+ crypt support\n"
1123 #else
1124 		"\t- crypt support\n"
1125 #endif
1126 #ifdef USE_OPENSSL
1127 		"\t+ SSL Support\n"
1128 #else
1129 		"\t- SSL Support\n"
1130 #endif
1131 #ifdef USE_MTCP
1132 		"\t+ MTCP Support\n"
1133 #else
1134 		"\t- MTCP Support\n"
1135 #endif
1136 #ifdef HAVE_LIBPCRE
1137 		"\t+ PCRE support\n"
1138 #else
1139 		"\t- PCRE support\n"
1140 #endif
1141 #ifdef HAVE_MYSQL
1142 		"\t+ mySQL support\n"
1143 #else
1144 		"\t- mySQL support\n"
1145 #endif
1146 #if defined(HAVE_LDAP_H) && defined(HAVE_LBER_H) && defined(HAVE_LIBLDAP) && defined(HAVE_LIBLBER)
1147 		"\t+ LDAP support\n"
1148 #else
1149 		"\t- LDAP support\n"
1150 #endif
1151 #ifdef HAVE_MEMCACHE_H
1152 		"\t+ memcached support\n"
1153 #else
1154 		"\t- memcached support\n"
1155 #endif
1156 #ifdef HAVE_FAM_H
1157 		"\t+ FAM support\n"
1158 #else
1159 		"\t- FAM support\n"
1160 #endif
1161 #ifdef HAVE_LUA_H
1162 		"\t+ LUA support\n"
1163 #else
1164 		"\t- LUA support\n"
1165 #endif
1166 #ifdef HAVE_LIBXML_H
1167 		"\t+ xml support\n"
1168 #else
1169 		"\t- xml support\n"
1170 #endif
1171 #ifdef HAVE_SQLITE3_H
1172 		"\t+ SQLite support\n"
1173 #else
1174 		"\t- SQLite support\n"
1175 #endif
1176 #ifdef HAVE_GDBM_H
1177 		"\t+ GDBM support\n"
1178 #else
1179 		"\t- GDBM support\n"
1180 #endif
1181 		"\n";
1182 	show_version();
1183 	printf("\nEvent Handlers:\n\n%s", features);
1184 }
1185 /*----------------------------------------------------------------------------*/
1186 static void
show_help(void)1187 show_help(void) {
1188 #ifdef USE_OPENSSL
1189 # define TEXT_SSL " (ssl)"
1190 #else
1191 # define TEXT_SSL
1192 #endif
1193 	char *b = PACKAGE_DESC TEXT_SSL " ("__DATE__ " " __TIME__ ")" \
1194 " - a light and fast webserver\n" \
1195 "usage:\n" \
1196 " -f <name>  filename of the config-file\n" \
1197 " -m <name>  module directory (default: "LIBRARY_DIR")\n" \
1198 " -p         print the parsed config-file in internal form, and exit\n" \
1199 " -n <#cpus> number of cpu cores that lighttpd will use\n" \
1200 " -t         test the config-file, and exit\n" \
1201 " -D         don't go to background (default: go to background)\n" \
1202 " -v         show version\n" \
1203 " -V         show compile-time features\n" \
1204 " -h         show this help\n" \
1205 "\n"
1206 ;
1207 #undef TEXT_SSL
1208 #undef TEXT_IPV6
1209 	write(STDOUT_FILENO, b, strlen(b));
1210 }
1211 /*----------------------------------------------------------------------------*/
1212 int
main(int argc,char ** argv)1213 main(int argc, char **argv) {
1214 #ifdef MULTI_THREADED
1215 	server **srv_states = NULL;
1216 	char *conf_file = NULL;
1217 #ifdef USE_MTCP
1218 	struct mtcp_conf mcfg;
1219 #endif
1220 #endif
1221 	/*
1222 	 * The introduction of MTCP slightly changes the purpose of *srv.
1223 	 * *srv will always hold the srv state info for core 0.
1224 	 *
1225 	 * When compiled without --lib-mtcp, *srv is used as the default
1226 	 * version.
1227 	 */
1228 	server *srv = NULL;
1229 	int print_config = 0;
1230 	int test_config = 0;
1231 	int i_am_root;
1232 	int o;
1233 	int num_childs = 0;
1234 	int pid_fd = -1;
1235 	size_t i;
1236 	struct group *grp = NULL;
1237 	struct passwd *pwd = NULL;
1238 #ifdef HAVE_SIGACTION
1239 	struct sigaction act;
1240 #endif
1241 #ifdef HAVE_GETRLIMIT
1242 	struct rlimit rlim;
1243 #endif
1244 
1245 #ifdef USE_ALARM
1246 	struct itimerval interval;
1247 
1248 	interval.it_interval.tv_sec = 1;
1249 	interval.it_interval.tv_usec = 0;
1250 	interval.it_value.tv_sec = 1;
1251 	interval.it_value.tv_usec = 0;
1252 #endif
1253 #ifdef MULTI_THREADED
1254 	/* create the cpu variable to facilitate multi-threading framework */
1255 	size_t cpus = -1;
1256 #endif
1257 
1258 
1259 	/* for nice %b handling in strfime() */
1260 	setlocale(LC_TIME, "C");
1261 
1262 	if (NULL == (srv = server_init())) {
1263 		fprintf(stderr, "did this really happen?\n");
1264 		return EXIT_FAILURE;
1265 	}
1266 
1267 	/* init structs done */
1268 #ifdef HAVE_GETUID
1269 	i_am_root = (getuid() == 0);
1270 #else
1271 	i_am_root = 0;
1272 #endif
1273 
1274 	srv->srvconf.port = 0;
1275 	srv->srvconf.dont_daemonize = 0;
1276 
1277 	while(-1 != (o = getopt(argc, argv, "f:m:n:hvVDpt"))) {
1278 		switch(o) {
1279 		case 'f':
1280 			if (srv->config_storage) {
1281 				log_error_write(srv, __FILE__, __LINE__, "s",
1282 						"Can only read one config file. Use the include command to use multiple config files.");
1283 
1284 				server_free(srv);
1285 				return EXIT_FAILURE;
1286 			}
1287 #ifdef MULTI_THREADED
1288 			/* store the path to conf file for populating other srv structs as well */
1289 			conf_file = strdup(optarg);
1290 			if (NULL == conf_file) {
1291 				fprintf(stderr, "Can't duplicate conf_file string\n");
1292 				return EXIT_FAILURE;
1293 			}
1294 #endif
1295 			if (config_read(srv, optarg)) {
1296 				server_free(srv);
1297 				return EXIT_FAILURE;
1298 			}
1299 			break;
1300 		case 'm':
1301 			buffer_copy_string(srv->srvconf.modules_dir, optarg);
1302 			break;
1303 		case 'n':
1304 #ifdef MULTI_THREADED
1305 			cpus = get_num_cpus(optarg);
1306 #else
1307 			fprintf(stderr, "-n option only works with MTCP/MULTI_THREADED support!\n");
1308 			exit(EXIT_FAILURE);
1309 #endif
1310 			break;
1311 		case 'p': print_config = 1; break;
1312 		case 't': test_config = 1; break;
1313 		case 'D':
1314 			srv->srvconf.dont_daemonize = 1; break;
1315 		case 'v': show_version(); return EXIT_SUCCESS;
1316 		case 'V': show_features(); return EXIT_SUCCESS;
1317 		case 'h': show_help(); return EXIT_SUCCESS;
1318 		default:
1319 			show_help();
1320 			server_free(srv);
1321 
1322 			return EXIT_FAILURE;
1323 		}
1324 	}
1325 
1326 	if (!srv->config_storage) {
1327 		log_error_write(srv, __FILE__, __LINE__, "s",
1328 				"No configuration available. Try using -f option.");
1329 
1330 		server_free(srv);
1331 		return EXIT_FAILURE;
1332 	}
1333 
1334 	if (print_config) {
1335 		data_unset *dc = srv->config_context->data[0];
1336 		if (dc) {
1337 			dc->print(dc, 0);
1338 			fprintf(stdout, "\n");
1339 		} else {
1340 			/* shouldn't happend */
1341 			fprintf(stderr, "global config not found\n");
1342 		}
1343 	}
1344 
1345 	if (test_config) {
1346 		printf("Syntax OK\n");
1347 	}
1348 
1349 	if (test_config || print_config) {
1350 		server_free(srv);
1351 		return EXIT_SUCCESS;
1352 	}
1353 
1354 	/* close stdin and stdout, as they are not needed */
1355 	openDevNull(STDIN_FILENO);
1356 	openDevNull(STDOUT_FILENO);
1357 
1358 	if (0 != config_set_defaults(srv)) {
1359 		log_error_write(srv, __FILE__, __LINE__, "s",
1360 				"setting default values failed");
1361 		server_free(srv);
1362 		return EXIT_FAILURE;
1363 	}
1364 
1365 	/* UID handling */
1366 #ifdef HAVE_GETUID
1367 	if (!i_am_root && issetugid()) {
1368 		/* we are setuid-root */
1369 
1370 		log_error_write(srv, __FILE__, __LINE__, "s",
1371 				"Are you nuts ? Don't apply a SUID bit to this binary");
1372 
1373 		server_free(srv);
1374 		return EXIT_FAILURE;
1375 	}
1376 #endif
1377 
1378 	/* check document-root */
1379 	if (srv->config_storage[0]->document_root->used <= 1) {
1380 		log_error_write(srv, __FILE__, __LINE__, "s",
1381 				"document-root is not set\n");
1382 
1383 		server_free(srv);
1384 
1385 		return EXIT_FAILURE;
1386 	}
1387 
1388 	if (plugins_load(srv)) {
1389 		log_error_write(srv, __FILE__, __LINE__, "s",
1390 				"loading plugins finally failed");
1391 
1392 		plugins_free(srv);
1393 		server_free(srv);
1394 
1395 		return EXIT_FAILURE;
1396 	}
1397 
1398 	/* open pid file BEFORE chroot */
1399 	if (srv->srvconf.pid_file->used) {
1400 		if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
1401 			struct stat st;
1402 			if (errno != EEXIST) {
1403 				log_error_write(srv, __FILE__, __LINE__, "sbs",
1404 					"opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
1405 				return EXIT_FAILURE;
1406 			}
1407 
1408 			if (0 != stat(srv->srvconf.pid_file->ptr, &st)) {
1409 				log_error_write(srv, __FILE__, __LINE__, "sbs",
1410 						"stating existing pid-file failed:", srv->srvconf.pid_file, strerror(errno));
1411 			}
1412 
1413 			if (!S_ISREG(st.st_mode)) {
1414 				log_error_write(srv, __FILE__, __LINE__, "sb",
1415 						"pid-file exists and isn't regular file:", srv->srvconf.pid_file);
1416 				return EXIT_FAILURE;
1417 			}
1418 
1419 			if (-1 == (pid_fd = open(srv->srvconf.pid_file->ptr, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) {
1420 				log_error_write(srv, __FILE__, __LINE__, "sbs",
1421 						"opening pid-file failed:", srv->srvconf.pid_file, strerror(errno));
1422 				return EXIT_FAILURE;
1423 			}
1424 		}
1425 	}
1426 
1427 	if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1428 		/* select limits itself
1429 		 *
1430 		 * as it is a hard limit and will lead to a segfault we add some safety
1431 		 * */
1432 		srv->max_fds = FD_SETSIZE - 200;
1433 	} else {
1434 		srv->max_fds = 4096;
1435 	}
1436 
1437 	if (i_am_root) {
1438 		int use_rlimit = 1;
1439 
1440 #ifdef HAVE_VALGRIND_VALGRIND_H
1441 		if (RUNNING_ON_VALGRIND) use_rlimit = 0;
1442 #endif
1443 
1444 #ifdef HAVE_GETRLIMIT
1445 		if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
1446 			log_error_write(srv, __FILE__, __LINE__,
1447 					"ss", "couldn't get 'max filedescriptors'",
1448 					strerror(errno));
1449 			return EXIT_FAILURE;
1450 		}
1451 
1452 		if (use_rlimit && srv->srvconf.max_fds) {
1453 			/* set rlimits */
1454 
1455 			rlim.rlim_cur = srv->srvconf.max_fds;
1456 			rlim.rlim_max = srv->srvconf.max_fds;
1457 
1458 			if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
1459 				log_error_write(srv, __FILE__, __LINE__,
1460 						"ss", "couldn't set 'max filedescriptors'",
1461 						strerror(errno));
1462 				return EXIT_FAILURE;
1463 			}
1464 		}
1465 
1466 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1467 			srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
1468 		} else {
1469 			srv->max_fds = rlim.rlim_cur;
1470 		}
1471 
1472 		/* set core file rlimit, if enable_cores is set */
1473 		if (use_rlimit && srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
1474 			rlim.rlim_cur = rlim.rlim_max;
1475 			setrlimit(RLIMIT_CORE, &rlim);
1476 		}
1477 #endif
1478 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1479 			/* don't raise the limit above FD_SET_SIZE */
1480 			if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
1481 				log_error_write(srv, __FILE__, __LINE__, "sd",
1482 						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
1483 						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
1484 				return EXIT_FAILURE;
1485 			}
1486 		}
1487 
1488 
1489 #ifdef HAVE_PWD_H
1490 		/* set user and group */
1491 		if (srv->srvconf.username->used) {
1492 			if (NULL == (pwd = getpwnam(srv->srvconf.username->ptr))) {
1493 				log_error_write(srv, __FILE__, __LINE__, "sb",
1494 						"can't find username", srv->srvconf.username);
1495 				return EXIT_FAILURE;
1496 			}
1497 
1498 			if (pwd->pw_uid == 0) {
1499 				log_error_write(srv, __FILE__, __LINE__, "s",
1500 						"I will not set uid to 0\n");
1501 				return EXIT_FAILURE;
1502 			}
1503 		}
1504 
1505 		if (srv->srvconf.groupname->used) {
1506 			if (NULL == (grp = getgrnam(srv->srvconf.groupname->ptr))) {
1507 				log_error_write(srv, __FILE__, __LINE__, "sb",
1508 					"can't find groupname", srv->srvconf.groupname);
1509 				return EXIT_FAILURE;
1510 			}
1511 			if (grp->gr_gid == 0) {
1512 				log_error_write(srv, __FILE__, __LINE__, "s",
1513 						"I will not set gid to 0\n");
1514 				return EXIT_FAILURE;
1515 			}
1516 		}
1517 #endif
1518 	} else {
1519 
1520 #ifdef HAVE_GETRLIMIT
1521 		if (0 != getrlimit(RLIMIT_NOFILE, &rlim)) {
1522 			log_error_write(srv, __FILE__, __LINE__,
1523 					"ss", "couldn't get 'max filedescriptors'",
1524 					strerror(errno));
1525 			return EXIT_FAILURE;
1526 		}
1527 
1528 		/**
1529 		 * we are not root can can't increase the fd-limit, but we can reduce it
1530 		 */
1531 		if (srv->srvconf.max_fds && srv->srvconf.max_fds < (int)rlim.rlim_cur) {
1532 			/* set rlimits */
1533 
1534 			rlim.rlim_cur = srv->srvconf.max_fds;
1535 
1536 			if (0 != setrlimit(RLIMIT_NOFILE, &rlim)) {
1537 				log_error_write(srv, __FILE__, __LINE__,
1538 						"ss", "couldn't set 'max filedescriptors'",
1539 						strerror(errno));
1540 				return EXIT_FAILURE;
1541 			}
1542 		}
1543 
1544 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1545 			srv->max_fds = rlim.rlim_cur < ((int)FD_SETSIZE) - 200 ? rlim.rlim_cur : FD_SETSIZE - 200;
1546 		} else {
1547 			srv->max_fds = rlim.rlim_cur;
1548 		}
1549 
1550 		/* set core file rlimit, if enable_cores is set */
1551 		if (srv->srvconf.enable_cores && getrlimit(RLIMIT_CORE, &rlim) == 0) {
1552 			rlim.rlim_cur = rlim.rlim_max;
1553 			setrlimit(RLIMIT_CORE, &rlim);
1554 		}
1555 
1556 #endif
1557 		if (srv->event_handler == FDEVENT_HANDLER_SELECT) {
1558 			/* don't raise the limit above FD_SET_SIZE */
1559 			if (srv->max_fds > ((int)FD_SETSIZE) - 200) {
1560 				log_error_write(srv, __FILE__, __LINE__, "sd",
1561 						"can't raise max filedescriptors above",  FD_SETSIZE - 200,
1562 						"if event-handler is 'select'. Use 'poll' or something else or reduce server.max-fds.");
1563 				return EXIT_FAILURE;
1564 			}
1565 		}
1566 	}
1567 #ifdef MULTI_THREADED
1568 
1569 #if defined HAVE_FORK
1570 	/* network is up, let's deamonize ourself */
1571 	if (srv->srvconf.dont_daemonize == 0) daemonize();
1572 #endif
1573 #ifdef USE_MTCP
1574 	/* set max-conns */
1575 	set_max_conns(srv, 0);
1576 #else
1577 	/* set the first_entry field */
1578 	srv->first_entry = srv;
1579 
1580 	/* set max-conns */
1581 	set_max_conns(srv, 1);
1582 #endif
1583 	/* thread-wide network initialization  */
1584 	/* first initialize srv_states */
1585 	init_server_states(&srv_states, cpus, srv, conf_file);
1586 
1587 #ifdef USE_MTCP
1588 	/**
1589 	 * it is important that core limit is set
1590 	 * before mtcp_init() is called. You can
1591 	 * not set core_limit after mtcp_init()
1592 	 */
1593 	//	mtcp_getconf(&mcfg);
1594 	//	mcfg.num_cores = cpus;
1595 	//	mtcp_setconf(&mcfg);
1596 	/* initialize the mtcp context */
1597 	if (mtcp_init("mos.conf")) {
1598 		fprintf(stderr, "Failed to initialize mtcp\n");
1599 		goto clean_up;
1600 	}
1601 
1602 	mtcp_getconf(&mcfg);
1603 	mcfg.max_concurrency = mcfg.max_num_buffers = srv_states[0]->max_conns;
1604 	mcfg.num_cores = cpus;
1605 	mtcp_setconf(&mcfg);
1606 
1607 	/* register SIGINT signal handler */
1608 	mtcp_register_signal(SIGINT, signal_handler);
1609 #endif
1610 	/* now spawn the threads and initialize the underlying networking layer */
1611 	for (i = 0; i < cpus; i++) {
1612 		if (mcfg.cpu_mask & (1L << i)) {
1613 			srv_states[i]->cpu = i;
1614 #if 0
1615 			start_server((void *)srv_states[i]);
1616 #endif
1617 			if (pthread_create(&srv_states[i]->running_thread, NULL,
1618 					   start_server, (void *)srv_states[i])) {
1619 				goto clean_up;
1620 			}
1621 		}
1622 	}
1623 
1624 	/*
1625 	 * ~~~ MTCP UPDATE ~~~
1626 	 * From this point onwards, the per-core `engine' running_thread does not execute
1627 	 * the following code.
1628 	 * The main thread, however, executes the remaining system-wide initialization logic
1629 	 * before it sleeps indefintely... (well... not quite... it waits till the threads
1630 	 * commit suicide)
1631 	 * ~~~ !MTCP UPDATE! ~~~
1632 	 */
1633 #else
1634 	/* we need root-perms for port < 1024 */
1635 	if (0 != network_init(srv)) {
1636 		plugins_free(srv);
1637 		server_free(srv);
1638 
1639 		return EXIT_FAILURE;
1640 	}
1641 #endif /* !MULTI_THREADED */
1642 
1643 	if (i_am_root) {
1644 #ifdef HAVE_PWD_H
1645 		/*
1646 		 * Change group before chroot, when we have access
1647 		 * to /etc/group
1648 		 * */
1649 		if (NULL != grp) {
1650 			setgid(grp->gr_gid);
1651 			setgroups(0, NULL);
1652 			if (srv->srvconf.username->used) {
1653 				initgroups(srv->srvconf.username->ptr, grp->gr_gid);
1654 			}
1655 		}
1656 #endif
1657 #ifdef HAVE_CHROOT
1658 		if (srv->srvconf.changeroot->used) {
1659 			tzset();
1660 
1661 			if (-1 == chroot(srv->srvconf.changeroot->ptr)) {
1662 				log_error_write(srv, __FILE__, __LINE__, "ss", "chroot failed: ", strerror(errno));
1663 				return EXIT_FAILURE;
1664 			}
1665 			if (-1 == chdir("/")) {
1666 				log_error_write(srv, __FILE__, __LINE__, "ss", "chdir failed: ", strerror(errno));
1667 				return EXIT_FAILURE;
1668 			}
1669 		}
1670 #endif
1671 #ifdef HAVE_PWD_H
1672 		/* drop root privs */
1673 		if (NULL != pwd) {
1674 			setuid(pwd->pw_uid);
1675 		}
1676 #endif
1677 #if defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_DUMPABLE)
1678 		/**
1679 		 * on IRIX 6.5.30 they have prctl() but no DUMPABLE
1680 		 */
1681 		if (srv->srvconf.enable_cores) {
1682 			prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
1683 		}
1684 #endif
1685 	}
1686 
1687 #ifndef MULTI_THREADED
1688 	/* set max-conns */
1689 	set_max_conns(srv, 1);
1690 	load_plugins(srv);
1691 #endif
1692 
1693 #ifdef HAVE_FORK
1694 #ifndef MULTI_THREADED
1695 	/* network is up, let's deamonize ourself */
1696 	if (srv->srvconf.dont_daemonize == 0) daemonize();
1697 #endif
1698 #endif
1699 
1700 	srv->gid = getgid();
1701 	srv->uid = getuid();
1702 
1703 	/* write pid file */
1704 	if (pid_fd != -1) {
1705 		buffer_copy_long(srv->tmp_buf, getpid());
1706 		buffer_append_string_len(srv->tmp_buf, CONST_STR_LEN("\n"));
1707 		write(pid_fd, srv->tmp_buf->ptr, srv->tmp_buf->used - 1);
1708 		close(pid_fd);
1709 		pid_fd = -1;
1710 	}
1711 
1712 #ifndef MULTI_THREADED
1713 	/* Close stderr ASAP in the child process to make sure that nothing
1714 	 * is being written to that fd which may not be valid anymore. */
1715 	if (-1 == log_error_open(srv)) {
1716 		log_error_write(srv, __FILE__, __LINE__, "s", "Opening errorlog failed. Going down.");
1717 
1718 		plugins_free(srv);
1719 		network_close(srv);
1720 		server_free(srv);
1721 		return EXIT_FAILURE;
1722 	}
1723 
1724 	if (HANDLER_GO_ON != plugins_call_set_defaults(srv)) {
1725 		log_error_write(srv, __FILE__, __LINE__, "s", "Configuration of plugins failed. Going down.");
1726 
1727 		plugins_free(srv);
1728 		network_close(srv);
1729 		server_free(srv);
1730 
1731 		return EXIT_FAILURE;
1732 	}
1733 #endif
1734 	/* dump unused config-keys */
1735 	for (i = 0; i < srv->config_context->used; i++) {
1736 		array *config = ((data_config *)srv->config_context->data[i])->value;
1737 		size_t j;
1738 
1739 		for (j = 0; config && j < config->used; j++) {
1740 			data_unset *du = config->data[j];
1741 
1742 			/* all var.* is known as user defined variable */
1743 			if (strncmp(du->key->ptr, "var.", sizeof("var.") - 1) == 0) {
1744 				continue;
1745 			}
1746 
1747 			if (NULL == array_get_element(srv->config_touched, du->key->ptr)) {
1748 				log_error_write(srv, __FILE__, __LINE__, "sbs",
1749 						"WARNING: unknown config-key:",
1750 						du->key,
1751 						"(ignored)");
1752 			}
1753 		}
1754 	}
1755 
1756 	if (srv->config_unsupported) {
1757 		log_error_write(srv, __FILE__, __LINE__, "s",
1758 				"Configuration contains unsupported keys. Going down.");
1759 	}
1760 
1761 	if (srv->config_deprecated) {
1762 		log_error_write(srv, __FILE__, __LINE__, "s",
1763 				"Configuration contains deprecated keys. Going down.");
1764 	}
1765 
1766 	if (srv->config_unsupported || srv->config_deprecated) {
1767 		plugins_free(srv);
1768 		network_close(srv);
1769 		server_free(srv);
1770 
1771 		return EXIT_FAILURE;
1772 	}
1773 
1774 #ifdef HAVE_SIGACTION
1775 	memset(&act, 0, sizeof(act));
1776 	act.sa_handler = SIG_IGN;
1777 	sigaction(SIGPIPE, &act, NULL);
1778 	sigaction(SIGUSR1, &act, NULL);
1779 # if defined(SA_SIGINFO)
1780 	act.sa_sigaction = sigaction_handler;
1781 	sigemptyset(&act.sa_mask);
1782 	act.sa_flags = SA_SIGINFO;
1783 # else
1784 	act.sa_handler = signal_handler;
1785 	sigemptyset(&act.sa_mask);
1786 	act.sa_flags = 0;
1787 # endif
1788 #ifndef USE_MTCP
1789 	sigaction(SIGINT,  &act, NULL);
1790 #endif
1791 	sigaction(SIGTERM, &act, NULL);
1792 	sigaction(SIGHUP,  &act, NULL);
1793 	sigaction(SIGALRM, &act, NULL);
1794 	sigaction(SIGCHLD, &act, NULL);
1795 
1796 #elif defined(HAVE_SIGNAL)
1797 	Control is not coming here
1798 	/* ignore the SIGPIPE from sendfile() */
1799 	signal(SIGPIPE, SIG_IGN);
1800 	signal(SIGUSR1, SIG_IGN);
1801 	signal(SIGALRM, signal_handler);
1802 	signal(SIGTERM, signal_handler);
1803 	signal(SIGHUP,  signal_handler);
1804 	signal(SIGCHLD,  signal_handler);
1805 	signal(SIGINT,  signal_handler);
1806 #endif
1807 
1808 #ifdef USE_ALARM
1809 	signal(SIGALRM, signal_handler);
1810 
1811 	/* setup periodic timer (1 second) */
1812 	if (setitimer(ITIMER_REAL, &interval, NULL)) {
1813 		log_error_write(srv, __FILE__, __LINE__, "s", "setting timer failed");
1814 		return EXIT_FAILURE;
1815 	}
1816 
1817 	getitimer(ITIMER_REAL, &interval);
1818 #endif
1819 
1820 #ifdef HAVE_FORK
1821 	/* MTCP/MULTI_THREADED UPDATE: num_childs is always zero here. Ignoring this entire code snippet */
1822 	/* start watcher and workers */
1823 	num_childs = srv->srvconf.max_worker;
1824 	if (num_childs > 0) {
1825 		int child = 0;
1826 		while (!child && !srv_shutdown && !graceful_shutdown) {
1827 			if (num_childs > 0) {
1828 				switch (fork()) {
1829 				case -1:
1830 					return EXIT_FAILURE;
1831 				case 0:
1832 					child = 1;
1833 					break;
1834 				default:
1835 					num_childs--;
1836 					break;
1837 				}
1838 			} else {
1839 				int status;
1840 
1841 				if (-1 != wait(&status)) {
1842 					/**
1843 					 * one of our workers went away
1844 					 */
1845 					num_childs++;
1846 				} else {
1847 					switch (errno) {
1848 					case EINTR:
1849 						/**
1850 						 * if we receive a SIGHUP we have to close our logs ourself as we don't
1851 						 * have the mainloop who can help us here
1852 						 */
1853 						if (handle_sig_hup) {
1854 							handle_sig_hup = 0;
1855 
1856 							log_error_cycle(srv);
1857 
1858 							/**
1859 							 * forward to all procs in the process-group
1860 							 *
1861 							 * we also send it ourself
1862 							 */
1863 							if (!forwarded_sig_hup) {
1864 								forwarded_sig_hup = 1;
1865 								kill(0, SIGHUP);
1866 							}
1867 						}
1868 						break;
1869 					default:
1870 						break;
1871 					}
1872 				}
1873 			}
1874 		}
1875 
1876 		/**
1877 		 * for the parent this is the exit-point
1878 		 */
1879 		if (!child) {
1880 			/**
1881 			 * kill all children too
1882 			 */
1883 			if (graceful_shutdown) {
1884 				kill(0, SIGINT);
1885 			} else if (srv_shutdown) {
1886 				kill(0, SIGTERM);
1887 			}
1888 
1889 			log_error_close(srv);
1890 			network_close(srv);
1891 			connections_free(srv);
1892 			plugins_free(srv);
1893 			server_free(srv);
1894 			return EXIT_SUCCESS;
1895 		}
1896 	}
1897 #endif /* !HAVE_FORK */
1898 
1899 #ifndef MULTI_THREADED
1900 	initialize_fd_framework(srv);
1901 
1902 	/* libev backend overwrites our SIGCHLD handler and calls waitpid on SIGCHLD; we want our own SIGCHLD handling. */
1903 #ifdef HAVE_SIGACTION
1904 	sigaction(SIGCHLD, &act, NULL);
1905 #elif defined(HAVE_SIGNAL)
1906 	signal(SIGCHLD,  signal_handler);
1907 #endif
1908 
1909 	/* This part of code is only executed in the single-process, single-threaded version (non-mtcp/non-multithreaded) */
1910 	/* Under USE_MTCP settings, each individual `running_thread' executes the `main-loop' */
1911 	/* main-loop */
1912 	while (!srv_shutdown) {
1913 		int n;
1914 		size_t ndx;
1915 		time_t min_ts;
1916 
1917 		if (handle_sig_hup) {
1918 			handler_t r;
1919 
1920 			/* reset notification */
1921 			handle_sig_hup = 0;
1922 
1923 
1924 			/* cycle logfiles */
1925 
1926 			switch(r = plugins_call_handle_sighup(srv)) {
1927 			case HANDLER_GO_ON:
1928 				break;
1929 			default:
1930 				log_error_write(srv, __FILE__, __LINE__, "sd", "sighup-handler return with an error", r);
1931 				break;
1932 			}
1933 
1934 			if (-1 == log_error_cycle(srv)) {
1935 				log_error_write(srv, __FILE__, __LINE__, "s", "cycling errorlog failed, dying");
1936 
1937 				return EXIT_FAILURE;
1938 			} else {
1939 #ifdef HAVE_SIGACTION
1940 				log_error_write(srv, __FILE__, __LINE__, "sdsd",
1941 					"logfiles cycled UID =",
1942 					last_sighup_info.si_uid,
1943 					"PID =",
1944 					last_sighup_info.si_pid);
1945 #else
1946 				log_error_write(srv, __FILE__, __LINE__, "s",
1947 					"logfiles cycled");
1948 #endif
1949 			}
1950 		}
1951 
1952 		if (handle_sig_alarm) {
1953 			/* a new second */
1954 
1955 #ifdef USE_ALARM
1956 			/* reset notification */
1957 			handle_sig_alarm = 0;
1958 #endif
1959 
1960 			/* get current time */
1961 			min_ts = time(NULL);
1962 
1963 			if (min_ts != srv->cur_ts) {
1964 				int cs = 0;
1965 				connections *conns = srv->conns;
1966 				handler_t r;
1967 
1968 				switch(r = plugins_call_handle_trigger(srv)) {
1969 				case HANDLER_GO_ON:
1970 					break;
1971 				case HANDLER_ERROR:
1972 					log_error_write(srv, __FILE__, __LINE__, "s", "one of the triggers failed");
1973 					break;
1974 				default:
1975 					log_error_write(srv, __FILE__, __LINE__, "d", r);
1976 					break;
1977 				}
1978 
1979 				/* trigger waitpid */
1980 				srv->cur_ts = min_ts;
1981 
1982 				/* cleanup stat-cache */
1983 				stat_cache_trigger_cleanup(srv);
1984 				/**
1985 				 * check all connections for timeouts
1986 				 *
1987 				 */
1988 				for (ndx = 0; ndx < conns->used; ndx++) {
1989 					int changed = 0;
1990 					connection *con;
1991 					int t_diff;
1992 
1993 					con = conns->ptr[ndx];
1994 
1995 					if (con->state == CON_STATE_READ ||
1996 					    con->state == CON_STATE_READ_POST) {
1997 						if (con->request_count == 1) {
1998 							if (srv->cur_ts - con->read_idle_ts > con->conf.max_read_idle) {
1999 								/* time - out */
2000 #if 0
2001 								log_error_write(srv, __FILE__, __LINE__, "sd",
2002 										"connection closed - read-timeout:", con->fd);
2003 #endif
2004 								connection_set_state(srv, con, CON_STATE_ERROR);
2005 								changed = 1;
2006 							}
2007 						} else {
2008 							if (srv->cur_ts - con->read_idle_ts > con->keep_alive_idle) {
2009 								/* time - out */
2010 #if 0
2011 								log_error_write(srv, __FILE__, __LINE__, "sd",
2012 										"connection closed - read-timeout:", con->fd);
2013 #endif
2014 								connection_set_state(srv, con, CON_STATE_ERROR);
2015 								changed = 1;
2016 							}
2017 						}
2018 					}
2019 
2020 					if ((con->state == CON_STATE_WRITE) &&
2021 					    (con->write_request_ts != 0)) {
2022 #if 0
2023 						if (srv->cur_ts - con->write_request_ts > 60) {
2024 							log_error_write(srv, __FILE__, __LINE__, "sdd",
2025 									"connection closed - pre-write-request-timeout:", con->fd, srv->cur_ts - con->write_request_ts);
2026 						}
2027 #endif
2028 
2029 						if (srv->cur_ts - con->write_request_ts > con->conf.max_write_idle) {
2030 							/* time - out */
2031 							if (con->conf.log_timeouts) {
2032 								log_error_write(srv, __FILE__, __LINE__, "sbsosds",
2033 									"NOTE: a request for",
2034 									con->request.uri,
2035 									"timed out after writing",
2036 									con->bytes_written,
2037 									"bytes. We waited",
2038 									(int)con->conf.max_write_idle,
2039 									"seconds. If this a problem increase server.max-write-idle");
2040 							}
2041 							connection_set_state(srv, con, CON_STATE_ERROR);
2042 							changed = 1;
2043 						}
2044 					}
2045 
2046 					if (con->state == CON_STATE_CLOSE && (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT)) {
2047 						changed = 1;
2048 					}
2049 
2050 					/* we don't like div by zero */
2051 					if (0 == (t_diff = srv->cur_ts - con->connection_start)) t_diff = 1;
2052 
2053 					if (con->traffic_limit_reached &&
2054 					    (con->conf.kbytes_per_second == 0 ||
2055 					     ((con->bytes_written / t_diff) < con->conf.kbytes_per_second * 1024))) {
2056 						/* enable connection again */
2057 						con->traffic_limit_reached = 0;
2058 
2059 						changed = 1;
2060 					}
2061 
2062 					if (changed) {
2063 						connection_state_machine(srv, con);
2064 					}
2065 					con->bytes_written_cur_second = 0;
2066 					*(con->conf.global_bytes_per_second_cnt_ptr) = 0;
2067 
2068 #if 0
2069 					if (cs == 0) {
2070 						fprintf(stderr, "connection-state: ");
2071 						cs = 1;
2072 					}
2073 
2074 					fprintf(stderr, "c[%d,%d]: %s ",
2075 						con->fd,
2076 						con->fcgi.fd,
2077 						connection_get_state(con->state));
2078 #endif
2079 				}
2080 
2081 				if (cs == 1) fprintf(stderr, "\n");
2082 			}
2083 		}
2084 
2085 		if (srv->sockets_disabled) {
2086 			/* our server sockets are disabled, why ? */
2087 
2088 			if ((srv->cur_fds + srv->want_fds < srv->max_fds * 8 / 10) && /* we have enough unused fds */
2089 			    (srv->conns->used <= srv->max_conns * 9 / 10) &&
2090 			    (0 == graceful_shutdown)) {
2091 				for (i = 0; i < srv->srv_sockets.used; i++) {
2092 					server_socket *srv_socket = srv->srv_sockets.ptr[i];
2093 					fdevent_event_set(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd, FDEVENT_IN);
2094 				}
2095 
2096 				log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets enabled again");
2097 
2098 				srv->sockets_disabled = 0;
2099 			}
2100 		} else {
2101 			if ((srv->cur_fds + srv->want_fds > srv->max_fds * 9 / 10) || /* out of fds */
2102 			    (srv->conns->used >= srv->max_conns) || /* out of connections */
2103 			    (graceful_shutdown)) { /* graceful_shutdown */
2104 
2105 				/* disable server-fds */
2106 
2107 				for (i = 0; i < srv->srv_sockets.used; i++) {
2108 					server_socket *srv_socket = srv->srv_sockets.ptr[i];
2109 					fdevent_event_del(srv->ev, &(srv_socket->fde_ndx), srv_socket->fd);
2110 
2111 					if (graceful_shutdown) {
2112 						/* we don't want this socket anymore,
2113 						 *
2114 						 * closing it right away will make it possible for
2115 						 * the next lighttpd to take over (graceful restart)
2116 						 *  */
2117 
2118 						fdevent_unregister(srv->ev, srv_socket->fd);
2119 						close(srv_socket->fd);
2120 						srv_socket->fd = -1;
2121 
2122 						/* network_close() will cleanup after us */
2123 
2124 						if (srv->srvconf.pid_file->used &&
2125 						    srv->srvconf.changeroot->used == 0) {
2126 							if (0 != unlink(srv->srvconf.pid_file->ptr)) {
2127 								if (errno != EACCES && errno != EPERM) {
2128 									log_error_write(srv, __FILE__, __LINE__, "sbds",
2129 											"unlink failed for:",
2130 											srv->srvconf.pid_file,
2131 											errno,
2132 											strerror(errno));
2133 								}
2134 							}
2135 						}
2136 					}
2137 				}
2138 
2139 				if (graceful_shutdown) {
2140 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] graceful shutdown started");
2141 				} else if (srv->conns->used >= srv->max_conns) {
2142 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, connection limit reached");
2143 				} else {
2144 					log_error_write(srv, __FILE__, __LINE__, "s", "[note] sockets disabled, out-of-fds");
2145 				}
2146 
2147 				srv->sockets_disabled = 1;
2148 			}
2149 		}
2150 
2151 		if (graceful_shutdown && srv->conns->used == 0) {
2152 			/* we are in graceful shutdown phase and all connections are closed
2153 			 * we are ready to terminate without harming anyone */
2154 			srv_shutdown = 1;
2155 		}
2156 
2157 		/* we still have some fds to share */
2158 		if (srv->want_fds) {
2159 			/* check the fdwaitqueue for waiting fds */
2160 			int free_fds = srv->max_fds - srv->cur_fds - 16;
2161 			connection *con;
2162 
2163 			for (; free_fds > 0 && NULL != (con = fdwaitqueue_unshift(srv, srv->fdwaitqueue)); free_fds--) {
2164 				connection_state_machine(srv, con);
2165 
2166 				srv->want_fds--;
2167 			}
2168 		}
2169 
2170 		if ((n = fdevent_poll(srv->ev, 1000)) > 0) {
2171 			/* n is the number of events */
2172 			int revents;
2173 			int fd_ndx;
2174 #if 0
2175 			if (n > 0) {
2176 				log_error_write(srv, __FILE__, __LINE__, "sd",
2177 						"polls:", n);
2178 			}
2179 #endif
2180 			fd_ndx = -1;
2181 			do {
2182 				fdevent_handler handler;
2183 				void *context;
2184 				handler_t r;
2185 				int fd;
2186 
2187 				fd_ndx  = fdevent_event_next_fdndx (srv->ev, fd_ndx);
2188 				if (-1 == fd_ndx) break; /* not all fdevent handlers know how many fds got an event */
2189 
2190 				revents = fdevent_event_get_revent (srv->ev, fd_ndx);
2191 				fd      = fdevent_event_get_fd     (srv->ev, fd_ndx);
2192 				handler = fdevent_get_handler(srv->ev, fd);
2193 				context = fdevent_get_context(srv->ev, fd);
2194 
2195 				/* connection_handle_fdevent needs a joblist_append */
2196 #if 0
2197 				log_error_write(srv, __FILE__, __LINE__, "sdd",
2198 						"event for", fd, revents);
2199 #endif
2200 				switch (r = (*handler)(srv, context, revents)) {
2201 				case HANDLER_FINISHED:
2202 				case HANDLER_GO_ON:
2203 				case HANDLER_WAIT_FOR_EVENT:
2204 				case HANDLER_WAIT_FOR_FD:
2205 					break;
2206 				case HANDLER_ERROR:
2207 					/* should never happen */
2208 					SEGFAULT();
2209 					break;
2210 				default:
2211 					log_error_write(srv, __FILE__, __LINE__, "d", r);
2212 					break;
2213 				}
2214 			} while (--n > 0);
2215 		} else if (n < 0 && errno != EINTR) {
2216 			log_error_write(srv, __FILE__, __LINE__, "ss",
2217 					"fdevent_poll failed:",
2218 					strerror(errno));
2219 		}
2220 
2221 		for (ndx = 0; ndx < srv->joblist->used; ndx++) {
2222 			connection *con = srv->joblist->ptr[ndx];
2223 			handler_t r;
2224 
2225 			connection_state_machine(srv, con);
2226 
2227 			switch(r = plugins_call_handle_joblist(srv, con)) {
2228 			case HANDLER_FINISHED:
2229 			case HANDLER_GO_ON:
2230 				break;
2231 			default:
2232 				log_error_write(srv, __FILE__, __LINE__, "d", r);
2233 				break;
2234 			}
2235 
2236 			con->in_joblist = 0;
2237 		}
2238 
2239 		srv->joblist->used = 0;
2240 	} /* end of `while (!srv_shutdown)` */
2241 
2242 #if 0
2243 	if (srv->srvconf.pid_file->used &&
2244 	    srv->srvconf.changeroot->used == 0 &&
2245 	    0 == graceful_shutdown) {
2246 		if (0 != unlink(srv->srvconf.pid_file->ptr)) {
2247 			if (errno != EACCES && errno != EPERM) {
2248 				log_error_write(srv, __FILE__, __LINE__, "sbds",
2249 						"unlink failed for:",
2250 						srv->srvconf.pid_file,
2251 						errno,
2252 						strerror(errno));
2253 			}
2254 		}
2255 	}
2256 #endif
2257 #ifdef HAVE_SIGACTION
2258 	log_error_write(srv, __FILE__, __LINE__, "sdsd",
2259 			"server stopped by UID =",
2260 			last_sigterm_info.si_uid,
2261 			"PID =",
2262 			last_sigterm_info.si_pid);
2263 #else
2264 	log_error_write(srv, __FILE__, __LINE__, "s",
2265 			"server stopped");
2266 #endif
2267 #endif /* !MULTI_THREADED */
2268 
2269 #ifdef MULTI_THREADED
2270 	/* main thread waits... */
2271 	for (i = 0; i < cpus; i++) {
2272 		if (mcfg.cpu_mask & (1L << i))
2273 			pthread_join(srv_states[i]->running_thread, NULL);
2274 	}
2275  clean_up:
2276 #ifdef USE_MTCP
2277 	/* destroy mtcp context */
2278 	mtcp_destroy();
2279 #endif
2280 	for (i = 0; i < cpus; i++) {
2281 		srv = srv_states[i];
2282 #endif /* MULTI_THREADED */
2283 		/* clean-up */
2284 		log_error_close(srv);
2285 		network_close(srv);
2286 		connections_free(srv);
2287 		plugins_free(srv);
2288 		server_free(srv);
2289 #ifdef MULTI_THREADED
2290 	}
2291 	free(conf_file);
2292 	free(srv_states);
2293 #endif /* !MULTI_THREADED */
2294 	return EXIT_SUCCESS;
2295 }
2296 /*----------------------------------------------------------------------------*/
2297