server.c revision 1.21
1/*	$OpenBSD: server.c,v 1.21 2014/08/01 22:24:05 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
51int		 server_dispatch_parent(int, struct privsep_proc *,
52		    struct imsg *);
53void		 server_shutdown(void);
54
55void		 server_init(struct privsep *, struct privsep_proc *p, void *);
56void		 server_launch(void);
57int		 server_socket(struct sockaddr_storage *, in_port_t,
58		    struct server_config *, int, int);
59int		 server_socket_listen(struct sockaddr_storage *, in_port_t,
60		    struct server_config *);
61
62void		 server_accept(int, short, void *);
63void		 server_input(struct client *);
64
65extern void	 bufferevent_read_pressure_cb(struct evbuffer *, size_t,
66		    size_t, void *);
67
68volatile int server_clients;
69volatile int server_inflight = 0;
70u_int32_t server_cltid;
71
72static struct httpd		*env = NULL;
73int				 proc_id;
74
75static struct privsep_proc procs[] = {
76	{ "parent",	PROC_PARENT,	server_dispatch_parent }
77};
78
79pid_t
80server(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
89void
90server_shutdown(void)
91{
92	config_purge(env, CONFIG_ALL);
93	usleep(200);	/* XXX server needs to shutdown last */
94}
95
96int
97server_privinit(struct server *srv)
98{
99	if (srv->srv_conf.flags & SRVFLAG_LOCATION)
100		return (0);
101
102	log_debug("%s: adding server %s", __func__, srv->srv_conf.name);
103
104	if ((srv->srv_s = server_socket_listen(&srv->srv_conf.ss,
105	    srv->srv_conf.port, &srv->srv_conf)) == -1)
106		return (-1);
107
108	return (0);
109}
110
111void
112server_init(struct privsep *ps, struct privsep_proc *p, void *arg)
113{
114	server_http(ps->ps_env);
115
116	if (config_init(ps->ps_env) == -1)
117		fatal("failed to initialize configuration");
118
119	/* Set to current prefork id */
120	proc_id = p->p_instance;
121
122	/* We use a custom shutdown callback */
123	p->p_shutdown = server_shutdown;
124
125	/* Unlimited file descriptors (use system limits) */
126	socket_rlimit(-1);
127
128#if 0
129	/* Schedule statistics timer */
130	evtimer_set(&env->sc_statev, server_statistics, NULL);
131	memcpy(&tv, &env->sc_statinterval, sizeof(tv));
132	evtimer_add(&env->sc_statev, &tv);
133#endif
134}
135
136void
137server_launch(void)
138{
139	struct server		*srv;
140
141	TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
142		server_http_init(srv);
143
144		log_debug("%s: running server %s", __func__,
145		    srv->srv_conf.name);
146
147		event_set(&srv->srv_ev, srv->srv_s, EV_READ,
148		    server_accept, srv);
149		event_add(&srv->srv_ev, NULL);
150		evtimer_set(&srv->srv_evt, server_accept, srv);
151	}
152}
153
154void
155server_purge(struct server *srv)
156{
157	struct client		*clt;
158	struct server_config	*srv_conf;
159
160	/* shutdown and remove server */
161	if (event_initialized(&srv->srv_ev))
162		event_del(&srv->srv_ev);
163	if (evtimer_initialized(&srv->srv_evt))
164		evtimer_del(&srv->srv_evt);
165
166	close(srv->srv_s);
167	TAILQ_REMOVE(env->sc_servers, srv, srv_entry);
168
169	/* cleanup sessions */
170	while ((clt =
171	    SPLAY_ROOT(&srv->srv_clients)) != NULL)
172		server_close(clt, NULL);
173
174	/* cleanup hosts */
175	while ((srv_conf =
176	    TAILQ_FIRST(&srv->srv_hosts)) != NULL) {
177		TAILQ_REMOVE(&srv->srv_hosts, srv_conf, entry);
178
179		/* It might point to our own "default" entry */
180		if (srv_conf != &srv->srv_conf)
181			free(srv_conf);
182	}
183
184	free(srv);
185}
186
187struct server *
188server_byaddr(struct sockaddr *addr, in_port_t port)
189{
190	struct server	*srv;
191
192	TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
193		if (port == srv->srv_conf.port &&
194		    sockaddr_cmp((struct sockaddr *)&srv->srv_conf.ss,
195		    addr, srv->srv_conf.prefixlen) == 0)
196			return (srv);
197	}
198
199	return (NULL);
200}
201
202int
203server_socket_af(struct sockaddr_storage *ss, in_port_t port)
204{
205	switch (ss->ss_family) {
206	case AF_INET:
207		((struct sockaddr_in *)ss)->sin_port = port;
208		((struct sockaddr_in *)ss)->sin_len =
209		    sizeof(struct sockaddr_in);
210		break;
211	case AF_INET6:
212		((struct sockaddr_in6 *)ss)->sin6_port = port;
213		((struct sockaddr_in6 *)ss)->sin6_len =
214		    sizeof(struct sockaddr_in6);
215		break;
216	default:
217		return (-1);
218	}
219
220	return (0);
221}
222
223in_port_t
224server_socket_getport(struct sockaddr_storage *ss)
225{
226	switch (ss->ss_family) {
227	case AF_INET:
228		return (((struct sockaddr_in *)ss)->sin_port);
229	case AF_INET6:
230		return (((struct sockaddr_in6 *)ss)->sin6_port);
231	default:
232		return (0);
233	}
234
235	/* NOTREACHED */
236	return (0);
237}
238
239int
240server_socket(struct sockaddr_storage *ss, in_port_t port,
241    struct server_config *srv_conf, int fd, int reuseport)
242{
243	struct linger	lng;
244	int		s = -1, val;
245
246	if (server_socket_af(ss, port) == -1)
247		goto bad;
248
249	s = fd == -1 ? socket(ss->ss_family, SOCK_STREAM, IPPROTO_TCP) : fd;
250	if (s == -1)
251		goto bad;
252
253	/*
254	 * Socket options
255	 */
256	memset(&lng, 0, sizeof(lng));
257	if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
258		goto bad;
259	if (reuseport) {
260		val = 1;
261		if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val,
262			sizeof(int)) == -1)
263			goto bad;
264	}
265	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1)
266		goto bad;
267	if (srv_conf->tcpflags & TCPFLAG_BUFSIZ) {
268		val = srv_conf->tcpbufsiz;
269		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
270		    &val, sizeof(val)) == -1)
271			goto bad;
272		val = srv_conf->tcpbufsiz;
273		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
274		    &val, sizeof(val)) == -1)
275			goto bad;
276	}
277
278	/*
279	 * IP options
280	 */
281	if (srv_conf->tcpflags & TCPFLAG_IPTTL) {
282		val = (int)srv_conf->tcpipttl;
283		if (setsockopt(s, IPPROTO_IP, IP_TTL,
284		    &val, sizeof(val)) == -1)
285			goto bad;
286	}
287	if (srv_conf->tcpflags & TCPFLAG_IPMINTTL) {
288		val = (int)srv_conf->tcpipminttl;
289		if (setsockopt(s, IPPROTO_IP, IP_MINTTL,
290		    &val, sizeof(val)) == -1)
291			goto bad;
292	}
293
294	/*
295	 * TCP options
296	 */
297	if (srv_conf->tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) {
298		if (srv_conf->tcpflags & TCPFLAG_NNODELAY)
299			val = 0;
300		else
301			val = 1;
302		if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
303		    &val, sizeof(val)) == -1)
304			goto bad;
305	}
306	if (srv_conf->tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) {
307		if (srv_conf->tcpflags & TCPFLAG_NSACK)
308			val = 0;
309		else
310			val = 1;
311		if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE,
312		    &val, sizeof(val)) == -1)
313			goto bad;
314	}
315
316	return (s);
317
318 bad:
319	if (s != -1)
320		close(s);
321	return (-1);
322}
323
324int
325server_socket_listen(struct sockaddr_storage *ss, in_port_t port,
326    struct server_config *srv_conf)
327{
328	int s;
329
330	if ((s = server_socket(ss, port, srv_conf, -1, 1)) == -1)
331		return (-1);
332
333	if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1)
334		goto bad;
335	if (listen(s, srv_conf->tcpbacklog) == -1)
336		goto bad;
337
338	return (s);
339
340 bad:
341	close(s);
342	return (-1);
343}
344
345void
346server_input(struct client *clt)
347{
348	struct server_config	*srv_conf = clt->clt_srv_conf;
349	evbuffercb		 inrd = server_read;
350	evbuffercb		 inwr = server_write;
351
352	if (server_httpdesc_init(clt) == -1) {
353		server_close(clt,
354		    "failed to allocate http descriptor");
355		return;
356	}
357
358	clt->clt_toread = TOREAD_HTTP_HEADER;
359	inrd = server_read_http;
360
361	/*
362	 * Client <-> Server
363	 */
364	clt->clt_bev = bufferevent_new(clt->clt_s, inrd, inwr,
365	    server_error, clt);
366	if (clt->clt_bev == NULL) {
367		server_close(clt, "failed to allocate input buffer event");
368		return;
369	}
370
371	bufferevent_settimeout(clt->clt_bev,
372	    srv_conf->timeout.tv_sec, srv_conf->timeout.tv_sec);
373	bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE);
374}
375
376void
377server_write(struct bufferevent *bev, void *arg)
378{
379	struct client		*clt = arg;
380	struct evbuffer		*dst = EVBUFFER_OUTPUT(bev);
381
382	if (EVBUFFER_LENGTH(dst) == 0 &&
383	    clt->clt_toread == TOREAD_HTTP_NONE)
384		goto done;
385
386	getmonotime(&clt->clt_tv_last);
387
388	if (clt->clt_done)
389		goto done;
390	return;
391 done:
392	server_close(clt, "done");
393	return;
394}
395
396void
397server_dump(struct client *clt, const void *buf, size_t len)
398{
399	if (!len)
400		return;
401
402	/*
403	 * This function will dump the specified message directly
404	 * to the underlying client, without waiting for success
405	 * of non-blocking events etc. This is useful to print an
406	 * error message before gracefully closing the client.
407	 */
408#if 0
409	if (cre->ssl != NULL)
410		(void)SSL_write(cre->ssl, buf, len);
411	else
412#endif
413		(void)write(clt->clt_s, buf, len);
414}
415
416void
417server_read(struct bufferevent *bev, void *arg)
418{
419	struct client		*clt = arg;
420	struct evbuffer		*src = EVBUFFER_INPUT(bev);
421
422	getmonotime(&clt->clt_tv_last);
423
424	if (!EVBUFFER_LENGTH(src))
425		return;
426	if (server_bufferevent_write_buffer(clt, src) == -1)
427		goto fail;
428	if (clt->clt_done)
429		goto done;
430	bufferevent_enable(bev, EV_READ);
431	return;
432 done:
433	server_close(clt, "done");
434	return;
435 fail:
436	server_close(clt, strerror(errno));
437}
438
439void
440server_error(struct bufferevent *bev, short error, void *arg)
441{
442	struct client		*clt = arg;
443
444	if (error & EVBUFFER_TIMEOUT) {
445		server_close(clt, "buffer event timeout");
446		return;
447	}
448	if (error & EVBUFFER_ERROR && errno == EFBIG) {
449		bufferevent_enable(bev, EV_READ);
450		return;
451	}
452	if (error & (EVBUFFER_READ|EVBUFFER_WRITE|EVBUFFER_EOF)) {
453		bufferevent_disable(bev, EV_READ|EV_WRITE);
454
455		clt->clt_done = 1;
456		server_close(clt, "done");
457		return;
458	}
459	server_close(clt, "buffer event error");
460	return;
461}
462
463void
464server_accept(int fd, short event, void *arg)
465{
466	struct server		*srv = arg;
467	struct client		*clt = NULL;
468	socklen_t		 slen;
469	struct sockaddr_storage	 ss;
470	int			 s = -1;
471
472	event_add(&srv->srv_ev, NULL);
473	if ((event & EV_TIMEOUT))
474		return;
475
476	slen = sizeof(ss);
477	if ((s = accept_reserve(fd, (struct sockaddr *)&ss,
478	    &slen, FD_RESERVE, &server_inflight)) == -1) {
479		/*
480		 * Pause accept if we are out of file descriptors, or
481		 * libevent will haunt us here too.
482		 */
483		if (errno == ENFILE || errno == EMFILE) {
484			struct timeval evtpause = { 1, 0 };
485
486			event_del(&srv->srv_ev);
487			evtimer_add(&srv->srv_evt, &evtpause);
488			log_debug("%s: deferring connections", __func__);
489		}
490		return;
491	}
492	if (server_clients >= SERVER_MAX_CLIENTS)
493		goto err;
494
495	if (fcntl(s, F_SETFL, O_NONBLOCK) == -1)
496		goto err;
497
498	if ((clt = calloc(1, sizeof(*clt))) == NULL)
499		goto err;
500
501	clt->clt_s = s;
502	clt->clt_fd = -1;
503	clt->clt_toread = TOREAD_UNLIMITED;
504	clt->clt_srv = srv;
505	clt->clt_srv_conf = &srv->srv_conf;
506	clt->clt_id = ++server_cltid;
507	clt->clt_srv_id = srv->srv_conf.id;
508	clt->clt_pid = getpid();
509	clt->clt_inflight = 1;
510
511	/* get local address */
512	slen = sizeof(clt->clt_srv_ss);
513	if (getsockname(s, (struct sockaddr *)&clt->clt_srv_ss,
514	    &slen) == -1) {
515		server_close(clt, "listen address lookup failed");
516		return;
517	}
518
519	/* get client address */
520	memcpy(&clt->clt_ss, &ss, sizeof(clt->clt_ss));
521
522	/* get ports */
523	switch (ss.ss_family) {
524	case AF_INET:
525		clt->clt_port = ((struct sockaddr_in *)&ss)->sin_port;
526		break;
527	case AF_INET6:
528		clt->clt_port = ((struct sockaddr_in6 *)&ss)->sin6_port;
529		break;
530	}
531
532	getmonotime(&clt->clt_tv_start);
533	memcpy(&clt->clt_tv_last, &clt->clt_tv_start, sizeof(clt->clt_tv_last));
534
535	server_clients++;
536	SPLAY_INSERT(client_tree, &srv->srv_clients, clt);
537
538	/* Increment the per-relay client counter */
539	//srv->srv_stats[proc_id].last++;
540
541	/* Pre-allocate output buffer */
542	clt->clt_output = evbuffer_new();
543	if (clt->clt_output == NULL) {
544		server_close(clt, "failed to allocate output buffer");
545		return;
546	}
547
548	/* Pre-allocate log buffer */
549	clt->clt_log = evbuffer_new();
550	if (clt->clt_log == NULL) {
551		server_close(clt, "failed to allocate log buffer");
552		return;
553	}
554
555	server_input(clt);
556	return;
557
558 err:
559	if (s != -1) {
560		close(s);
561		if (clt != NULL)
562			free(clt);
563		/*
564		 * the client struct was not completly set up, but still
565		 * counted as an inflight client. account for this.
566		 */
567		server_inflight_dec(clt, __func__);
568	}
569}
570
571void
572server_inflight_dec(struct client *clt, const char *why)
573{
574	if (clt != NULL) {
575		/* the flight already left inflight mode. */
576		if (clt->clt_inflight == 0)
577			return;
578		clt->clt_inflight = 0;
579	}
580
581	/* the file was never opened, thus this was an inflight client. */
582	server_inflight--;
583	DPRINTF("%s: inflight decremented, now %d, %s",
584	    __func__, server_inflight, why);
585}
586
587void
588server_log(struct client *clt)
589{
590	char		*ptr = NULL;
591
592	if (!EVBUFFER_LENGTH(clt->clt_log))
593		return;
594
595	while ((ptr = evbuffer_readline(clt->clt_log)) != NULL) {
596		log_info("%s", ptr);
597		free(ptr);
598	}
599}
600
601void
602server_close(struct client *clt, const char *msg)
603{
604	char			 ibuf[MAXHOSTNAMELEN], obuf[MAXHOSTNAMELEN];
605	struct server		*srv = clt->clt_srv;
606	struct server_config	*srv_conf = clt->clt_srv_conf;
607	extern int		 debug;
608
609	SPLAY_REMOVE(client_tree, &srv->srv_clients, clt);
610
611	/* free the HTTP descriptors incl. headers */
612	server_close_http(clt);
613
614	event_del(&clt->clt_ev);
615	if (clt->clt_bev != NULL)
616		bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE);
617	if (clt->clt_srvbev != NULL)
618		bufferevent_disable(clt->clt_srvbev, EV_READ|EV_WRITE);
619
620	server_log(clt);
621
622	if (debug && msg != NULL) {
623		memset(&ibuf, 0, sizeof(ibuf));
624		memset(&obuf, 0, sizeof(obuf));
625		(void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf));
626		(void)server_http_host(&clt->clt_srv_ss, obuf, sizeof(obuf));
627		log_debug("server %s, "
628		    "client %d (%d active), %s:%u -> %s, "
629		    "%s", srv_conf->name, clt->clt_id, server_clients,
630		    ibuf, ntohs(clt->clt_port), obuf, msg);
631	}
632
633	if (clt->clt_bev != NULL)
634		bufferevent_free(clt->clt_bev);
635	if (clt->clt_output != NULL)
636		evbuffer_free(clt->clt_output);
637	if (clt->clt_srvevb != NULL)
638		evbuffer_free(clt->clt_srvevb);
639
640	if (clt->clt_srvbev != NULL)
641		bufferevent_free(clt->clt_srvbev);
642	if (clt->clt_fd != -1)
643		close(clt->clt_fd);
644	if (clt->clt_s != -1)
645		close(clt->clt_s);
646
647	server_inflight_dec(clt, __func__);
648
649	if (clt->clt_log != NULL)
650		evbuffer_free(clt->clt_log);
651
652	free(clt);
653	server_clients--;
654}
655
656int
657server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
658{
659	switch (imsg->hdr.type) {
660	case IMSG_CFG_MEDIA:
661		config_getmedia(env, imsg);
662		break;
663	case IMSG_CFG_SERVER:
664		config_getserver(env, imsg);
665		break;
666	case IMSG_CFG_DONE:
667		config_getcfg(env, imsg);
668		break;
669	case IMSG_CTL_START:
670		server_launch();
671		break;
672	case IMSG_CTL_RESET:
673		config_getreset(env, imsg);
674		break;
675	default:
676		return (-1);
677	}
678
679	return (0);
680}
681
682int
683server_bufferevent_add(struct event *ev, int timeout)
684{
685	struct timeval tv, *ptv = NULL;
686
687	if (timeout) {
688		timerclear(&tv);
689		tv.tv_sec = timeout;
690		ptv = &tv;
691	}
692
693	return (event_add(ev, ptv));
694}
695
696int
697server_bufferevent_print(struct client *clt, const char *str)
698{
699	if (clt->clt_bev == NULL)
700		return (evbuffer_add(clt->clt_output, str, strlen(str)));
701	return (bufferevent_write(clt->clt_bev, str, strlen(str)));
702}
703
704int
705server_bufferevent_write_buffer(struct client *clt, struct evbuffer *buf)
706{
707	if (clt->clt_bev == NULL)
708		return (evbuffer_add_buffer(clt->clt_output, buf));
709	return (bufferevent_write_buffer(clt->clt_bev, buf));
710}
711
712int
713server_bufferevent_write_chunk(struct client *clt,
714    struct evbuffer *buf, size_t size)
715{
716	int ret;
717	ret = server_bufferevent_write(clt, buf->buffer, size);
718	if (ret != -1)
719		evbuffer_drain(buf, size);
720	return (ret);
721}
722
723int
724server_bufferevent_write(struct client *clt, void *data, size_t size)
725{
726	if (clt->clt_bev == NULL)
727		return (evbuffer_add(clt->clt_output, data, size));
728	return (bufferevent_write(clt->clt_bev, data, size));
729}
730
731int
732server_client_cmp(struct client *a, struct client *b)
733{
734	return ((int)a->clt_id - b->clt_id);
735}
736
737SPLAY_GENERATE(client_tree, client, clt_nodes, server_client_cmp);
738