xref: /openbsd-src/usr.sbin/httpd/server.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: server.c,v 1.6 2014/07/16 10:25:28 reyk Exp $	*/
2 
3 /*
4  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/time.h>
22 #include <sys/stat.h>
23 #include <sys/socket.h>
24 #include <sys/un.h>
25 #include <sys/tree.h>
26 #include <sys/hash.h>
27 
28 #include <net/if.h>
29 #include <netinet/in_systm.h>
30 #include <netinet/in.h>
31 #include <netinet/ip.h>
32 #include <netinet/tcp.h>
33 #include <arpa/inet.h>
34 
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <stdio.h>
41 #include <err.h>
42 #include <pwd.h>
43 #include <event.h>
44 #include <fnmatch.h>
45 
46 #include <openssl/dh.h>
47 #include <openssl/ssl.h>
48 
49 #include "httpd.h"
50 
51 int		 server_dispatch_parent(int, struct privsep_proc *,
52 		    struct imsg *);
53 void		 server_shutdown(void);
54 
55 void		 server_init(struct privsep *, struct privsep_proc *p, void *);
56 void		 server_launch(void);
57 int		 server_socket(struct sockaddr_storage *, in_port_t,
58 		    struct server *, int, int);
59 int		 server_socket_listen(struct sockaddr_storage *, in_port_t,
60 		    struct server *);
61 
62 void		 server_accept(int, short, void *);
63 void		 server_input(struct client *);
64 
65 extern void	 bufferevent_read_pressure_cb(struct evbuffer *, size_t,
66 		    size_t, void *);
67 
68 volatile int server_clients;
69 volatile int server_inflight = 0;
70 u_int32_t server_cltid;
71 
72 static struct httpd		*env = NULL;
73 int				 proc_id;
74 
75 static struct privsep_proc procs[] = {
76 	{ "parent",	PROC_PARENT,	server_dispatch_parent }
77 };
78 
79 pid_t
80 server(struct privsep *ps, struct privsep_proc *p)
81 {
82 	pid_t	 pid;
83 	env = ps->ps_env;
84 	pid = proc_run(ps, p, procs, nitems(procs), server_init, NULL);
85 	server_http(env);
86 	return (pid);
87 }
88 
89 void
90 server_shutdown(void)
91 {
92 	config_purge(env, CONFIG_ALL);
93 	usleep(200);	/* XXX server needs to shutdown last */
94 }
95 
96 int
97 server_privinit(struct server *srv)
98 {
99 	log_debug("%s: adding server %s", __func__, srv->srv_conf.name);
100 
101 	if ((srv->srv_s = server_socket_listen(&srv->srv_conf.ss,
102 	    srv->srv_conf.port, srv)) == -1)
103 		return (-1);
104 
105 	return (0);
106 }
107 
108 void
109 server_init(struct privsep *ps, struct privsep_proc *p, void *arg)
110 {
111 	server_http(ps->ps_env);
112 
113 	if (config_init(ps->ps_env) == -1)
114 		fatal("failed to initialize configuration");
115 
116 	/* Set to current prefork id */
117 	proc_id = p->p_instance;
118 
119 	/* We use a custom shutdown callback */
120 	p->p_shutdown = server_shutdown;
121 
122 	/* Unlimited file descriptors (use system limits) */
123 	socket_rlimit(-1);
124 
125 #if 0
126 	/* Schedule statistics timer */
127 	evtimer_set(&env->sc_statev, server_statistics, NULL);
128 	memcpy(&tv, &env->sc_statinterval, sizeof(tv));
129 	evtimer_add(&env->sc_statev, &tv);
130 #endif
131 }
132 
133 void
134 server_launch(void)
135 {
136 	struct server		*srv;
137 
138 	TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
139 		server_http_init(srv);
140 
141 		log_debug("%s: running server %s", __func__,
142 		    srv->srv_conf.name);
143 
144 		event_set(&srv->srv_ev, srv->srv_s, EV_READ,
145 		    server_accept, srv);
146 		event_add(&srv->srv_ev, NULL);
147 		evtimer_set(&srv->srv_evt, server_accept, srv);
148 	}
149 }
150 
151 int
152 server_socket_af(struct sockaddr_storage *ss, in_port_t port)
153 {
154 	switch (ss->ss_family) {
155 	case AF_INET:
156 		((struct sockaddr_in *)ss)->sin_port = port;
157 		((struct sockaddr_in *)ss)->sin_len =
158 		    sizeof(struct sockaddr_in);
159 		break;
160 	case AF_INET6:
161 		((struct sockaddr_in6 *)ss)->sin6_port = port;
162 		((struct sockaddr_in6 *)ss)->sin6_len =
163 		    sizeof(struct sockaddr_in6);
164 		break;
165 	default:
166 		return (-1);
167 	}
168 
169 	return (0);
170 }
171 
172 in_port_t
173 server_socket_getport(struct sockaddr_storage *ss)
174 {
175 	switch (ss->ss_family) {
176 	case AF_INET:
177 		return (((struct sockaddr_in *)ss)->sin_port);
178 	case AF_INET6:
179 		return (((struct sockaddr_in6 *)ss)->sin6_port);
180 	default:
181 		return (0);
182 	}
183 
184 	/* NOTREACHED */
185 	return (0);
186 }
187 
188 int
189 server_socket(struct sockaddr_storage *ss, in_port_t port,
190     struct server *srv, int fd, int reuseport)
191 {
192 	struct linger	lng;
193 	int		s = -1, val;
194 
195 	if (server_socket_af(ss, port) == -1)
196 		goto bad;
197 
198 	s = fd == -1 ? socket(ss->ss_family, SOCK_STREAM, IPPROTO_TCP) : fd;
199 	if (s == -1)
200 		goto bad;
201 
202 	/*
203 	 * Socket options
204 	 */
205 	memset(&lng, 0, sizeof(lng));
206 	if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
207 		goto bad;
208 	if (reuseport) {
209 		val = 1;
210 		if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val,
211 			sizeof(int)) == -1)
212 			goto bad;
213 	}
214 	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1)
215 		goto bad;
216 	if (srv->srv_tcpflags & TCPFLAG_BUFSIZ) {
217 		val = srv->srv_tcpbufsiz;
218 		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
219 		    &val, sizeof(val)) == -1)
220 			goto bad;
221 		val = srv->srv_tcpbufsiz;
222 		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
223 		    &val, sizeof(val)) == -1)
224 			goto bad;
225 	}
226 
227 	/*
228 	 * IP options
229 	 */
230 	if (srv->srv_tcpflags & TCPFLAG_IPTTL) {
231 		val = (int)srv->srv_tcpipttl;
232 		if (setsockopt(s, IPPROTO_IP, IP_TTL,
233 		    &val, sizeof(val)) == -1)
234 			goto bad;
235 	}
236 	if (srv->srv_tcpflags & TCPFLAG_IPMINTTL) {
237 		val = (int)srv->srv_tcpipminttl;
238 		if (setsockopt(s, IPPROTO_IP, IP_MINTTL,
239 		    &val, sizeof(val)) == -1)
240 			goto bad;
241 	}
242 
243 	/*
244 	 * TCP options
245 	 */
246 	if (srv->srv_tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) {
247 		if (srv->srv_tcpflags & TCPFLAG_NNODELAY)
248 			val = 0;
249 		else
250 			val = 1;
251 		if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
252 		    &val, sizeof(val)) == -1)
253 			goto bad;
254 	}
255 	if (srv->srv_tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) {
256 		if (srv->srv_tcpflags & TCPFLAG_NSACK)
257 			val = 0;
258 		else
259 			val = 1;
260 		if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE,
261 		    &val, sizeof(val)) == -1)
262 			goto bad;
263 	}
264 
265 	return (s);
266 
267  bad:
268 	if (s != -1)
269 		close(s);
270 	return (-1);
271 }
272 
273 int
274 server_socket_listen(struct sockaddr_storage *ss, in_port_t port,
275     struct server *srv)
276 {
277 	int s;
278 
279 	if ((s = server_socket(ss, port, srv, -1, 1)) == -1)
280 		return (-1);
281 
282 	if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1)
283 		goto bad;
284 	if (listen(s, srv->srv_tcpbacklog) == -1)
285 		goto bad;
286 
287 	return (s);
288 
289  bad:
290 	close(s);
291 	return (-1);
292 }
293 
294 void
295 server_input(struct client *clt)
296 {
297 	struct server	*srv = clt->clt_server;
298 	evbuffercb	 inrd = server_read;
299 	evbuffercb	 inwr = server_write;
300 
301 	if (server_httpdesc_init(clt) == -1) {
302 		server_close(clt,
303 		    "failed to allocate http descriptor");
304 		return;
305 	}
306 
307 	clt->clt_toread = TOREAD_HTTP_HEADER;
308 	inrd = server_read_http;
309 
310 	/*
311 	 * Client <-> Server
312 	 */
313 	clt->clt_bev = bufferevent_new(clt->clt_s, inrd, inwr,
314 	    server_error, clt);
315 	if (clt->clt_bev == NULL) {
316 		server_close(clt, "failed to allocate input buffer event");
317 		return;
318 	}
319 
320 	bufferevent_settimeout(clt->clt_bev,
321 	    srv->srv_conf.timeout.tv_sec, srv->srv_conf.timeout.tv_sec);
322 	bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE);
323 }
324 
325 void
326 server_write(struct bufferevent *bev, void *arg)
327 {
328 	struct client		*clt = arg;
329 	struct evbuffer		*dst = EVBUFFER_OUTPUT(bev);
330 
331 	if (EVBUFFER_LENGTH(dst) == 0 &&
332 	    clt->clt_toread == TOREAD_HTTP_NONE)
333 		goto done;
334 
335 	getmonotime(&clt->clt_tv_last);
336 
337 	if (clt->clt_done)
338 		goto done;
339 	return;
340  done:
341 	server_close(clt, "done");
342 	return;
343 }
344 
345 void
346 server_dump(struct client *clt, const void *buf, size_t len)
347 {
348 	if (!len)
349 		return;
350 
351 	/*
352 	 * This function will dump the specified message directly
353 	 * to the underlying client, without waiting for success
354 	 * of non-blocking events etc. This is useful to print an
355 	 * error message before gracefully closing the client.
356 	 */
357 #if 0
358 	if (cre->ssl != NULL)
359 		(void)SSL_write(cre->ssl, buf, len);
360 	else
361 #endif
362 		(void)write(clt->clt_s, buf, len);
363 }
364 
365 void
366 server_read(struct bufferevent *bev, void *arg)
367 {
368 	struct client		*clt = arg;
369 	struct evbuffer		*src = EVBUFFER_INPUT(bev);
370 
371 	getmonotime(&clt->clt_tv_last);
372 
373 	if (!EVBUFFER_LENGTH(src))
374 		return;
375 	if (server_bufferevent_write_buffer(clt, src) == -1)
376 		goto fail;
377 	if (clt->clt_done)
378 		goto done;
379 	bufferevent_enable(bev, EV_READ);
380 	return;
381  done:
382 	server_close(clt, "done");
383 	return;
384  fail:
385 	server_close(clt, strerror(errno));
386 }
387 
388 void
389 server_error(struct bufferevent *bev, short error, void *arg)
390 {
391 	struct client		*clt = arg;
392 
393 	if (error & EVBUFFER_TIMEOUT) {
394 		server_close(clt, "buffer event timeout");
395 		return;
396 	}
397 	if (error & EVBUFFER_ERROR && errno == EFBIG) {
398 		bufferevent_enable(bev, EV_READ);
399 		return;
400 	}
401 	if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) {
402 		bufferevent_disable(bev, EV_READ|EV_WRITE);
403 
404 		clt->clt_done = 1;
405 		server_close(clt, "done");
406 		return;
407 	}
408 	server_close(clt, "buffer event error");
409 	return;
410 }
411 
412 void
413 server_accept(int fd, short event, void *arg)
414 {
415 	struct server		*srv = arg;
416 	struct client		*clt = NULL;
417 	socklen_t		 slen;
418 	struct sockaddr_storage	 ss;
419 	int			 s = -1;
420 
421 	event_add(&srv->srv_ev, NULL);
422 	if ((event & EV_TIMEOUT))
423 		return;
424 
425 	slen = sizeof(ss);
426 	if ((s = accept_reserve(fd, (struct sockaddr *)&ss,
427 	    &slen, FD_RESERVE, &server_inflight)) == -1) {
428 		/*
429 		 * Pause accept if we are out of file descriptors, or
430 		 * libevent will haunt us here too.
431 		 */
432 		if (errno == ENFILE || errno == EMFILE) {
433 			struct timeval evtpause = { 1, 0 };
434 
435 			event_del(&srv->srv_ev);
436 			evtimer_add(&srv->srv_evt, &evtpause);
437 			log_debug("%s: deferring connections", __func__);
438 		}
439 		return;
440 	}
441 	if (server_clients >= SERVER_MAX_CLIENTS)
442 		goto err;
443 
444 	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1)
445 		goto err;
446 
447 	if ((clt = calloc(1, sizeof(*clt))) == NULL)
448 		goto err;
449 
450 	clt->clt_s = s;
451 	clt->clt_fd = -1;
452 	clt->clt_toread = TOREAD_UNLIMITED;
453 	clt->clt_server = srv;
454 	clt->clt_id = ++server_cltid;
455 	clt->clt_serverid = srv->srv_conf.id;
456 	clt->clt_pid = getpid();
457 	clt->clt_inflight = 1;
458 	switch (ss.ss_family) {
459 	case AF_INET:
460 		clt->clt_port = ((struct sockaddr_in *)&ss)->sin_port;
461 		break;
462 	case AF_INET6:
463 		clt->clt_port = ((struct sockaddr_in6 *)&ss)->sin6_port;
464 		break;
465 	}
466 	memcpy(&clt->clt_ss, &ss, sizeof(clt->clt_ss));
467 
468 	getmonotime(&clt->clt_tv_start);
469 	memcpy(&clt->clt_tv_last, &clt->clt_tv_start, sizeof(clt->clt_tv_last));
470 
471 	server_clients++;
472 	SPLAY_INSERT(client_tree, &srv->srv_clients, clt);
473 
474 	/* Increment the per-relay client counter */
475 	//srv->srv_stats[proc_id].last++;
476 
477 	/* Pre-allocate output buffer */
478 	clt->clt_output = evbuffer_new();
479 	if (clt->clt_output == NULL) {
480 		server_close(clt, "failed to allocate output buffer");
481 		return;
482 	}
483 
484 	/* Pre-allocate log buffer */
485 	clt->clt_log = evbuffer_new();
486 	if (clt->clt_log == NULL) {
487 		server_close(clt, "failed to allocate log buffer");
488 		return;
489 	}
490 
491 	server_input(clt);
492 	return;
493 
494  err:
495 	if (s != -1) {
496 		close(s);
497 		if (clt != NULL)
498 			free(clt);
499 		/*
500 		 * the client struct was not completly set up, but still
501 		 * counted as an inflight client. account for this.
502 		 */
503 		server_inflight_dec(clt, __func__);
504 	}
505 }
506 
507 void
508 server_inflight_dec(struct client *clt, const char *why)
509 {
510 	if (clt != NULL) {
511 		/* the flight already left inflight mode. */
512 		if (clt->clt_inflight == 0)
513 			return;
514 		clt->clt_inflight = 0;
515 	}
516 
517 	/* the file was never opened, thus this was an inflight client. */
518 	server_inflight--;
519 	log_debug("%s: inflight decremented, now %d, %s",
520 	    __func__, server_inflight, why);
521 }
522 
523 void
524 server_close(struct client *clt, const char *msg)
525 {
526 	char		 ibuf[128], obuf[128], *ptr = NULL;
527 	struct server	*srv = clt->clt_server;
528 
529 	SPLAY_REMOVE(client_tree, &srv->srv_clients, clt);
530 
531 	event_del(&clt->clt_ev);
532 	if (clt->clt_bev != NULL)
533 		bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE);
534 	if (clt->clt_file != NULL)
535 		bufferevent_disable(clt->clt_file, EV_READ|EV_WRITE);
536 
537 	if ((env->sc_opts & HTTPD_OPT_LOGUPDATE) && msg != NULL) {
538 		memset(&ibuf, 0, sizeof(ibuf));
539 		memset(&obuf, 0, sizeof(obuf));
540 		(void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf));
541 		(void)print_host(&srv->srv_conf.ss, obuf, sizeof(obuf));
542 		if (EVBUFFER_LENGTH(clt->clt_log) &&
543 		    evbuffer_add_printf(clt->clt_log, "\r\n") != -1)
544 			ptr = evbuffer_readline(clt->clt_log);
545 		log_info("server %s, "
546 		    "client %d (%d active), %s -> %s:%d, "
547 		    "%s%s%s", srv->srv_conf.name, clt->clt_id, server_clients,
548 		    ibuf, obuf, ntohs(clt->clt_port), msg,
549 		    ptr == NULL ? "" : ",", ptr == NULL ? "" : ptr);
550 		if (ptr != NULL)
551 			free(ptr);
552 	}
553 
554 	if (clt->clt_bev != NULL)
555 		bufferevent_free(clt->clt_bev);
556 	else if (clt->clt_output != NULL)
557 		evbuffer_free(clt->clt_output);
558 
559 	if (clt->clt_file != NULL)
560 		bufferevent_free(clt->clt_file);
561 	if (clt->clt_fd != -1)
562 		close(clt->clt_fd);
563 	if (clt->clt_s != -1)
564 		close(clt->clt_s);
565 
566 	server_inflight_dec(clt, __func__);
567 
568 	if (clt->clt_log != NULL)
569 		evbuffer_free(clt->clt_log);
570 
571 	free(clt);
572 	server_clients--;
573 }
574 
575 int
576 server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
577 {
578 	switch (imsg->hdr.type) {
579 	case IMSG_CFG_MEDIA:
580 		config_getmedia(env, imsg);
581 		break;
582 	case IMSG_CFG_SERVER:
583 		config_getserver(env, imsg);
584 		break;
585 	case IMSG_CFG_DONE:
586 		config_getcfg(env, imsg);
587 		break;
588 	case IMSG_CTL_START:
589 		server_launch();
590 		break;
591 	case IMSG_CTL_RESET:
592 		config_getreset(env, imsg);
593 		break;
594 	default:
595 		return (-1);
596 	}
597 
598 	return (0);
599 }
600 
601 int
602 server_bufferevent_add(struct event *ev, int timeout)
603 {
604 	struct timeval tv, *ptv = NULL;
605 
606 	if (timeout) {
607 		timerclear(&tv);
608 		tv.tv_sec = timeout;
609 		ptv = &tv;
610 	}
611 
612 	return (event_add(ev, ptv));
613 }
614 
615 int
616 server_bufferevent_print(struct client *clt, const char *str)
617 {
618 	if (clt->clt_bev == NULL)
619 		return (evbuffer_add(clt->clt_output, str, strlen(str)));
620 	return (bufferevent_write(clt->clt_bev, str, strlen(str)));
621 }
622 
623 int
624 server_bufferevent_write_buffer(struct client *clt, struct evbuffer *buf)
625 {
626 	if (clt->clt_bev == NULL)
627 		return (evbuffer_add_buffer(clt->clt_output, buf));
628 	return (bufferevent_write_buffer(clt->clt_bev, buf));
629 }
630 
631 int
632 server_bufferevent_write_chunk(struct client *clt,
633     struct evbuffer *buf, size_t size)
634 {
635 	int ret;
636 	ret = server_bufferevent_write(clt, buf->buffer, size);
637 	if (ret != -1)
638 		evbuffer_drain(buf, size);
639 	return (ret);
640 }
641 
642 int
643 server_bufferevent_write(struct client *clt, void *data, size_t size)
644 {
645 	if (clt->clt_bev == NULL)
646 		return (evbuffer_add(clt->clt_output, data, size));
647 	return (bufferevent_write(clt->clt_bev, data, size));
648 }
649 
650 int
651 server_client_cmp(struct client *a, struct client *b)
652 {
653 	return ((int)a->clt_id - b->clt_id);
654 }
655 
656 SPLAY_GENERATE(client_tree, client, clt_nodes, server_client_cmp);
657