1193326Sed/*	$OpenBSD: server.c,v 1.129 2023/11/08 19:19:10 millert Exp $	*/
2193326Sed
3193326Sed/*
4193326Sed * Copyright (c) 2006 - 2015 Reyk Floeter <reyk@openbsd.org>
5193326Sed *
6193326Sed * Permission to use, copy, modify, and distribute this software for any
7193326Sed * purpose with or without fee is hereby granted, provided that the above
8193326Sed * copyright notice and this permission notice appear in all copies.
9193326Sed *
10193326Sed * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11193326Sed * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12193326Sed * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13193326Sed * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14193326Sed * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15193326Sed * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16205219Srdivacky * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17193326Sed */
18193326Sed
19193326Sed#include <sys/types.h>
20198092Srdivacky#include <sys/queue.h>
21193326Sed#include <sys/time.h>
22193326Sed#include <sys/stat.h>
23205219Srdivacky#include <sys/socket.h>
24205219Srdivacky#include <sys/uio.h>
25205219Srdivacky#include <sys/tree.h>
26193326Sed
27193326Sed#include <netinet/in.h>
28193326Sed#include <netinet/tcp.h>
29193326Sed#include <arpa/inet.h>
30193326Sed
31193326Sed#include <stdio.h>
32193326Sed#include <stdlib.h>
33193326Sed#include <stdarg.h>
34193326Sed#include <limits.h>
35205408Srdivacky#include <errno.h>
36193326Sed#include <fcntl.h>
37193326Sed#include <string.h>
38193326Sed#include <syslog.h>
39193326Sed#include <unistd.h>
40193326Sed#include <event.h>
41193326Sed#include <imsg.h>
42205408Srdivacky#include <tls.h>
43193326Sed#include <vis.h>
44193326Sed
45193326Sed#include "httpd.h"
46193326Sed
47193326Sed#define MINIMUM(a, b)	(((a) < (b)) ? (a) : (b))
48200583Srdivacky
49193326Sedint		 server_dispatch_parent(int, struct privsep_proc *,
50205408Srdivacky		    struct imsg *);
51205408Srdivackyint		 server_dispatch_logger(int, struct privsep_proc *,
52193326Sed		    struct imsg *);
53193326Sedvoid		 server_shutdown(void);
54200583Srdivacky
55205408Srdivackyvoid		 server_init(struct privsep *, struct privsep_proc *p, void *);
56200583Srdivackyvoid		 server_launch(void);
57205408Srdivackyint		 server_socket(struct sockaddr_storage *, in_port_t,
58205408Srdivacky		    struct server_config *, int, int);
59205408Srdivackyint		 server_socket_listen(struct sockaddr_storage *, in_port_t,
60200583Srdivacky		    struct server_config *);
61200583Srdivackystruct server	*server_byid(uint32_t);
62205219Srdivacky
63205219Srdivackyint		 server_tls_init(struct server *);
64205219Srdivackyvoid		 server_tls_readcb(int, short, void *);
65205219Srdivackyvoid		 server_tls_writecb(int, short, void *);
66205219Srdivackyvoid		 server_tls_handshake(int, short, void *);
67193326Sed
68205408Srdivackyvoid		 server_accept(int, short, void *);
69205219Srdivackyvoid		 server_input(struct client *);
70205219Srdivackyvoid		 server_inflight_dec(struct client *, const char *);
71205408Srdivacky
72205408Srdivackyextern void	 bufferevent_read_pressure_cb(struct evbuffer *, size_t,
73205408Srdivacky		    size_t, void *);
74205408Srdivacky
75200583Srdivackyvolatile int server_clients;
76200583Srdivackyvolatile int server_inflight = 0;
77200583Srdivackyuint32_t server_cltid;
78200583Srdivacky
79200583Srdivackystatic struct privsep_proc procs[] = {
80200583Srdivacky	{ "parent",	PROC_PARENT,	server_dispatch_parent },
81200583Srdivacky	{ "logger",	PROC_LOGGER,	server_dispatch_logger }
82200583Srdivacky};
83200583Srdivacky
84200583Srdivackyvoid
85205408Srdivackyserver(struct privsep *ps, struct privsep_proc *p)
86200583Srdivacky{
87205408Srdivacky	proc_run(ps, p, procs, nitems(procs), server_init, NULL);
88205408Srdivacky	server_http();
89205408Srdivacky}
90200583Srdivacky
91200583Srdivackyvoid
92206084Srdivackyserver_shutdown(void)
93206084Srdivacky{
94206084Srdivacky	config_purge(httpd_env, CONFIG_ALL);
95206084Srdivacky	usleep(200);	/* XXX server needs to shutdown last */
96206084Srdivacky}
97206084Srdivacky
98206084Srdivackyint
99206084Srdivackyserver_privinit(struct server *srv)
100205408Srdivacky{
101205408Srdivacky	struct server	*s;
102206084Srdivacky
103205408Srdivacky	if (srv->srv_conf.flags & SRVFLAG_LOCATION)
104205408Srdivacky		return (0);
105205408Srdivacky
106206084Srdivacky	log_debug("%s: adding server %s", __func__, srv->srv_conf.name);
107206084Srdivacky
108206084Srdivacky	/*
109206084Srdivacky	 * There's no need to open a new socket if a server with the
110206084Srdivacky	 * same address already exists.
111206084Srdivacky	 */
112205408Srdivacky	TAILQ_FOREACH(s, httpd_env->sc_servers, srv_entry) {
113198092Srdivacky		if (s != srv && s->srv_s != -1 &&
114198092Srdivacky		    s->srv_conf.port == srv->srv_conf.port &&
115205219Srdivacky		    sockaddr_cmp((struct sockaddr *)&s->srv_conf.ss,
116205408Srdivacky		    (struct sockaddr *)&srv->srv_conf.ss,
117205408Srdivacky		    s->srv_conf.prefixlen) == 0)
118205408Srdivacky			return (0);
119205408Srdivacky	}
120198092Srdivacky
121198092Srdivacky	/* Open listening socket in the privileged process */
122193326Sed	if ((srv->srv_s = server_socket_listen(&srv->srv_conf.ss,
123193326Sed	    srv->srv_conf.port, &srv->srv_conf)) == -1)
124193326Sed		return (-1);
125198092Srdivacky
126193326Sed	return (0);
127193326Sed}
128193326Sed
129198092Srdivackyint
130193326Sedserver_tls_cmp(struct server *s1, struct server *s2)
131193326Sed{
132193326Sed	struct server_config	*sc1, *sc2;
133193326Sed
134193326Sed	sc1 = &s1->srv_conf;
135193326Sed	sc2 = &s2->srv_conf;
136193326Sed
137193326Sed	if (sc1->tls_flags != sc2->tls_flags)
138193326Sed		return (-1);
139193326Sed	if (sc1->tls_protocols != sc2->tls_protocols)
140193326Sed		return (-1);
141193326Sed	if (sc1->tls_ticket_lifetime != sc2->tls_ticket_lifetime)
142198092Srdivacky		return (-1);
143193326Sed	if (strcmp(sc1->tls_ciphers, sc2->tls_ciphers) != 0)
144193326Sed		return (-1);
145198092Srdivacky	if (strcmp(sc1->tls_dhe_params, sc2->tls_dhe_params) != 0)
146193326Sed		return (-1);
147193326Sed	if (strcmp(sc1->tls_ecdhe_curves, sc2->tls_ecdhe_curves) != 0)
148198092Srdivacky		return (-1);
149193326Sed
150193326Sed	return (0);
151193326Sed}
152193326Sed
153193326Sedint
154198092Srdivackyserver_tls_load_keypair(struct server *srv)
155193326Sed{
156193326Sed	if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0)
157193326Sed		return (0);
158193326Sed
159193326Sed	if ((srv->srv_conf.tls_cert = tls_load_file(srv->srv_conf.tls_cert_file,
160198092Srdivacky	    &srv->srv_conf.tls_cert_len, NULL)) == NULL)
161193326Sed		return (-1);
162193326Sed	log_debug("%s: using certificate %s", __func__,
163193326Sed	    srv->srv_conf.tls_cert_file);
164193326Sed
165193326Sed	/* XXX allow to specify password for encrypted key */
166193326Sed	if ((srv->srv_conf.tls_key = tls_load_file(srv->srv_conf.tls_key_file,
167193326Sed	    &srv->srv_conf.tls_key_len, NULL)) == NULL)
168193326Sed		return (-1);
169193326Sed	log_debug("%s: using private key %s", __func__,
170193326Sed	    srv->srv_conf.tls_key_file);
171193326Sed
172193326Sed	return (0);
173193326Sed}
174193326Sed
175198092Srdivackyint
176193326Sedserver_tls_load_ocsp(struct server *srv)
177198092Srdivacky{
178193326Sed	if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0)
179193326Sed		return (0);
180193326Sed
181193326Sed	if (srv->srv_conf.tls_ocsp_staple_file == NULL)
182193326Sed		return (0);
183193326Sed
184193326Sed	if ((srv->srv_conf.tls_ocsp_staple = tls_load_file(
185193326Sed	    srv->srv_conf.tls_ocsp_staple_file,
186193326Sed	    &srv->srv_conf.tls_ocsp_staple_len, NULL)) == NULL) {
187193326Sed		log_warnx("%s: Failed to load ocsp staple from %s", __func__,
188193326Sed		    srv->srv_conf.tls_ocsp_staple_file);
189198092Srdivacky		return (-1);
190193326Sed	}
191193326Sed
192193326Sed	if (srv->srv_conf.tls_ocsp_staple_len == 0) {
193193326Sed		log_warnx("%s: ignoring 0 length ocsp staple from %s", __func__,
194193326Sed		    srv->srv_conf.tls_ocsp_staple_file);
195193326Sed		return (0);
196198092Srdivacky	}
197193326Sed
198193326Sed	log_debug("%s: using ocsp staple from %s", __func__,
199193326Sed	    srv->srv_conf.tls_ocsp_staple_file);
200193326Sed
201193326Sed	return (0);
202193326Sed}
203193326Sed
204198092Srdivackyint
205193326Sedserver_tls_load_ca(struct server *srv)
206193326Sed{
207193326Sed	if ((srv->srv_conf.tls_flags & TLSFLAG_CA) == 0 ||
208193326Sed	    srv->srv_conf.tls_ca_file == NULL)
209193326Sed		return (0);
210193326Sed
211193326Sed	if ((srv->srv_conf.tls_ca = tls_load_file(
212193326Sed	    srv->srv_conf.tls_ca_file,
213193326Sed	    &srv->srv_conf.tls_ca_len, NULL)) == NULL)
214193326Sed		return (-1);
215193326Sed	log_debug("%s: using ca cert(s) from %s", __func__,
216193326Sed	    srv->srv_conf.tls_ca_file);
217193326Sed
218193326Sed	return (0);
219193326Sed}
220193326Sed
221193326Sedint
222193326Sedserver_tls_load_crl(struct server *srv)
223198092Srdivacky{
224193326Sed	if ((srv->srv_conf.tls_flags & TLSFLAG_CA) == 0 ||
225193326Sed	    srv->srv_conf.tls_crl_file == NULL)
226193326Sed		return (0);
227193326Sed
228193326Sed	if ((srv->srv_conf.tls_crl = tls_load_file(
229198092Srdivacky	    srv->srv_conf.tls_crl_file,
230193326Sed	    &srv->srv_conf.tls_crl_len, NULL)) == NULL)
231193326Sed		return (-1);
232193326Sed	log_debug("%s: using crl(s) from %s", __func__,
233193326Sed	    srv->srv_conf.tls_crl_file);
234193326Sed
235193326Sed	return (0);
236193326Sed}
237193326Sed
238193326Sedint
239193326Sedserver_tls_init(struct server *srv)
240193326Sed{
241193326Sed	struct server_config *srv_conf;
242193326Sed
243198092Srdivacky	if ((srv->srv_conf.flags & SRVFLAG_TLS) == 0)
244193326Sed		return (0);
245193326Sed
246193326Sed	log_debug("%s: setting up tls for %s", __func__, srv->srv_conf.name);
247193326Sed
248198092Srdivacky	if ((srv->srv_tls_config = tls_config_new()) == NULL) {
249193326Sed		log_warnx("%s: failed to get tls config", __func__);
250193326Sed		return (-1);
251193326Sed	}
252193326Sed	if ((srv->srv_tls_ctx = tls_server()) == NULL) {
253193326Sed		log_warnx("%s: failed to get tls server", __func__);
254193326Sed		return (-1);
255193326Sed	}
256193326Sed
257193326Sed	if (tls_config_set_protocols(srv->srv_tls_config,
258193326Sed	    srv->srv_conf.tls_protocols) != 0) {
259193326Sed		log_warnx("%s: failed to set tls protocols: %s",
260193326Sed		    __func__, tls_config_error(srv->srv_tls_config));
261193326Sed		return (-1);
262193326Sed	}
263193326Sed	if (tls_config_set_ciphers(srv->srv_tls_config,
264193326Sed	    srv->srv_conf.tls_ciphers) != 0) {
265193326Sed		log_warnx("%s: failed to set tls ciphers: %s",
266198092Srdivacky		    __func__, tls_config_error(srv->srv_tls_config));
267193326Sed		return (-1);
268193326Sed	}
269198092Srdivacky	if (tls_config_set_dheparams(srv->srv_tls_config,
270193326Sed	    srv->srv_conf.tls_dhe_params) != 0) {
271193326Sed		log_warnx("%s: failed to set tls dhe params: %s",
272198092Srdivacky		    __func__, tls_config_error(srv->srv_tls_config));
273193326Sed		return (-1);
274193326Sed	}
275198092Srdivacky	if (tls_config_set_ecdhecurves(srv->srv_tls_config,
276193326Sed	    srv->srv_conf.tls_ecdhe_curves) != 0) {
277193326Sed		log_warnx("%s: failed to set tls ecdhe curves: %s",
278193326Sed		    __func__, tls_config_error(srv->srv_tls_config));
279193326Sed		return (-1);
280193326Sed	}
281193326Sed
282193326Sed	if (tls_config_set_keypair_ocsp_mem(srv->srv_tls_config,
283198092Srdivacky	    srv->srv_conf.tls_cert, srv->srv_conf.tls_cert_len,
284193326Sed	    srv->srv_conf.tls_key, srv->srv_conf.tls_key_len,
285193326Sed	    srv->srv_conf.tls_ocsp_staple,
286193326Sed	    srv->srv_conf.tls_ocsp_staple_len) != 0) {
287193326Sed		log_warnx("%s: failed to set tls certificate/key: %s",
288193326Sed		    __func__, tls_config_error(srv->srv_tls_config));
289198092Srdivacky		return (-1);
290193326Sed	}
291193326Sed
292193326Sed	if (srv->srv_conf.tls_ca != NULL) {
293193326Sed		if (tls_config_set_ca_mem(srv->srv_tls_config,
294193326Sed		    srv->srv_conf.tls_ca, srv->srv_conf.tls_ca_len) != 0) {
295193326Sed			log_warnx("%s: failed to add ca cert(s)", __func__);
296193326Sed			return (-1);
297193326Sed		}
298193326Sed		if (tls_config_set_crl_mem(srv->srv_tls_config,
299193326Sed		    srv->srv_conf.tls_crl, srv->srv_conf.tls_crl_len) != 0) {
300193326Sed			log_warnx("%s: failed to add crl(s)", __func__);
301193326Sed			return (-1);
302193326Sed		}
303193326Sed		if (srv->srv_conf.tls_flags & TLSFLAG_OPTIONAL)
304193326Sed			tls_config_verify_client_optional(srv->srv_tls_config);
305193326Sed		else
306198092Srdivacky			tls_config_verify_client(srv->srv_tls_config);
307193326Sed	}
308193326Sed
309193326Sed	TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) {
310193326Sed		if (srv_conf->tls_cert == NULL || srv_conf->tls_key == NULL)
311193326Sed			continue;
312193326Sed		log_debug("%s: adding keypair for server %s", __func__,
313193326Sed		    srv->srv_conf.name);
314193326Sed		if (tls_config_add_keypair_ocsp_mem(srv->srv_tls_config,
315193326Sed		    srv_conf->tls_cert, srv_conf->tls_cert_len,
316193326Sed		    srv_conf->tls_key, srv_conf->tls_key_len,
317193326Sed		    srv_conf->tls_ocsp_staple,
318193326Sed		    srv_conf->tls_ocsp_staple_len) != 0) {
319193326Sed			log_warnx("%s: failed to add tls keypair", __func__);
320193326Sed			return (-1);
321193326Sed		}
322193326Sed	}
323193326Sed
324193326Sed	/* set common session ID among all processes */
325193326Sed	if (tls_config_set_session_id(srv->srv_tls_config,
326193326Sed	    httpd_env->sc_tls_sid, sizeof(httpd_env->sc_tls_sid)) == -1) {
327198092Srdivacky		log_warnx("%s: could not set the TLS session ID: %s",
328193326Sed		    __func__, tls_config_error(srv->srv_tls_config));
329193326Sed		return (-1);
330198092Srdivacky	}
331193326Sed
332193326Sed	/* ticket support */
333193326Sed	if (srv->srv_conf.tls_ticket_lifetime) {
334193326Sed		if (tls_config_set_session_lifetime(srv->srv_tls_config,
335193326Sed		    srv->srv_conf.tls_ticket_lifetime) == -1) {
336193326Sed			log_warnx("%s: could not set the TLS session lifetime: "
337193326Sed			    "%s", __func__,
338193326Sed			    tls_config_error(srv->srv_tls_config));
339193326Sed			return (-1);
340193326Sed		}
341198092Srdivacky		tls_config_add_ticket_key(srv->srv_tls_config,
342193326Sed		    srv->srv_conf.tls_ticket_key.tt_keyrev,
343193326Sed		    srv->srv_conf.tls_ticket_key.tt_key,
344193326Sed		    sizeof(srv->srv_conf.tls_ticket_key.tt_key));
345198092Srdivacky		explicit_bzero(&srv->srv_conf.tls_ticket_key,
346193326Sed		    sizeof(srv->srv_conf.tls_ticket_key));
347193326Sed	}
348193326Sed
349193326Sed	if (tls_configure(srv->srv_tls_ctx, srv->srv_tls_config) != 0) {
350193326Sed		log_warnx("%s: failed to configure tls - %s", __func__,
351193326Sed		    tls_error(srv->srv_tls_ctx));
352193326Sed		return (-1);
353193326Sed	}
354193326Sed
355193326Sed	/* We're now done with the public/private key & ca/crl... */
356193326Sed	tls_config_clear_keys(srv->srv_tls_config);
357193326Sed	freezero(srv->srv_conf.tls_cert, srv->srv_conf.tls_cert_len);
358193326Sed	freezero(srv->srv_conf.tls_key, srv->srv_conf.tls_key_len);
359193326Sed	free(srv->srv_conf.tls_ca);
360193326Sed	free(srv->srv_conf.tls_crl);
361193326Sed	srv->srv_conf.tls_ca = NULL;
362193326Sed	srv->srv_conf.tls_cert = NULL;
363193326Sed	srv->srv_conf.tls_crl = NULL;
364193326Sed	srv->srv_conf.tls_key = NULL;
365193326Sed	srv->srv_conf.tls_ca_len = 0;
366193326Sed	srv->srv_conf.tls_cert_len = 0;
367193326Sed	srv->srv_conf.tls_crl_len = 0;
368193326Sed	srv->srv_conf.tls_key_len = 0;
369193326Sed
370193326Sed	return (0);
371193326Sed}
372193326Sed
373193326Sedvoid
374193326Sedserver_generate_ticket_key(struct server_config *srv_conf)
375193326Sed{
376193326Sed	struct server_tls_ticket *key = &srv_conf->tls_ticket_key;
377193326Sed
378193326Sed	key->tt_id = srv_conf->id;
379193326Sed	key->tt_keyrev = arc4random();
380193326Sed	arc4random_buf(key->tt_key, sizeof(key->tt_key));
381193326Sed}
382193326Sed
383193326Sedvoid
384193326Sedserver_init(struct privsep *ps, struct privsep_proc *p, void *arg)
385193326Sed{
386193326Sed	server_http();
387193326Sed
388193326Sed	if (config_init(ps->ps_env) == -1)
389193326Sed		fatal("failed to initialize configuration");
390193326Sed
391193326Sed	/* We use a custom shutdown callback */
392193326Sed	p->p_shutdown = server_shutdown;
393193326Sed
394193326Sed	/* Unlimited file descriptors (use system limits) */
395193326Sed	socket_rlimit(-1);
396193326Sed
397193326Sed	if (pledge("stdio rpath inet unix recvfd", NULL) == -1)
398193326Sed		fatal("pledge");
399193326Sed
400193326Sed#if 0
401193326Sed	/* Schedule statistics timer */
402193326Sed	evtimer_set(&ps->ps_env->sc_statev, server_statistics, NULL);
403193326Sed	memcpy(&tv, &ps->ps_env->sc_statinterval, sizeof(tv));
404193326Sed	evtimer_add(&ps->ps_env->sc_statev, &tv);
405193326Sed#endif
406193326Sed}
407193326Sed
408193326Sedvoid
409193326Sedserver_launch(void)
410193326Sed{
411193326Sed	struct server		*srv;
412193326Sed
413193326Sed	TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
414193326Sed		log_debug("%s: configuring server %s", __func__,
415198092Srdivacky		    srv->srv_conf.name);
416193326Sed
417198092Srdivacky		server_tls_init(srv);
418193326Sed		server_http_init(srv);
419193326Sed
420198092Srdivacky		log_debug("%s: running server %s", __func__,
421193326Sed		    srv->srv_conf.name);
422193326Sed
423194613Sed		event_set(&srv->srv_ev, srv->srv_s, EV_READ,
424205408Srdivacky		    server_accept, srv);
425193326Sed		event_add(&srv->srv_ev, NULL);
426193326Sed		evtimer_set(&srv->srv_evt, server_accept, srv);
427198092Srdivacky	}
428193326Sed}
429193326Sed
430193326Sedvoid
431193326Sedserver_purge(struct server *srv)
432193326Sed{
433198092Srdivacky	struct client		*clt;
434193326Sed	struct server_config	*srv_conf;
435193326Sed
436194711Sed	/* shutdown and remove server */
437194711Sed	if (event_initialized(&srv->srv_ev))
438193326Sed		event_del(&srv->srv_ev);
439193326Sed	if (evtimer_initialized(&srv->srv_evt))
440193326Sed		evtimer_del(&srv->srv_evt);
441193326Sed
442193326Sed	if (srv->srv_s != -1)
443193326Sed		close(srv->srv_s);
444193326Sed	TAILQ_REMOVE(httpd_env->sc_servers, srv, srv_entry);
445193326Sed
446193326Sed	/* cleanup sessions */
447193326Sed	while ((clt =
448193326Sed	    SPLAY_ROOT(&srv->srv_clients)) != NULL)
449193326Sed		server_close(clt, NULL);
450193326Sed
451193326Sed	/* cleanup hosts */
452193326Sed	while ((srv_conf =
453198092Srdivacky	    TAILQ_FIRST(&srv->srv_hosts)) != NULL) {
454193326Sed		TAILQ_REMOVE(&srv->srv_hosts, srv_conf, entry);
455198092Srdivacky
456193326Sed		/* It might point to our own "default" entry */
457193326Sed		if (srv_conf != &srv->srv_conf) {
458193326Sed			serverconfig_free(srv_conf);
459193326Sed			free(srv_conf);
460193326Sed		}
461193326Sed	}
462193326Sed
463193326Sed	tls_config_free(srv->srv_tls_config);
464193326Sed	tls_free(srv->srv_tls_ctx);
465193326Sed
466193326Sed	free(srv);
467193326Sed}
468200583Srdivacky
469205219Srdivackyvoid
470205219Srdivackyserverconfig_free(struct server_config *srv_conf)
471200583Srdivacky{
472205219Srdivacky	struct fastcgi_param	*param, *tparam;
473205219Srdivacky
474200583Srdivacky	free(srv_conf->return_uri);
475200583Srdivacky	free(srv_conf->tls_ca_file);
476200583Srdivacky	free(srv_conf->tls_ca);
477200583Srdivacky	free(srv_conf->tls_cert_file);
478200583Srdivacky	free(srv_conf->tls_crl_file);
479200583Srdivacky	free(srv_conf->tls_crl);
480200583Srdivacky	free(srv_conf->tls_key_file);
481200583Srdivacky	free(srv_conf->tls_ocsp_staple_file);
482200583Srdivacky	free(srv_conf->tls_ocsp_staple);
483200583Srdivacky	freezero(srv_conf->tls_cert, srv_conf->tls_cert_len);
484200583Srdivacky	freezero(srv_conf->tls_key, srv_conf->tls_key_len);
485200583Srdivacky
486205219Srdivacky	TAILQ_FOREACH_SAFE(param, &srv_conf->fcgiparams, entry, tparam)
487205408Srdivacky		free(param);
488205408Srdivacky}
489205219Srdivacky
490205408Srdivackyvoid
491205408Srdivackyserverconfig_reset(struct server_config *srv_conf)
492205408Srdivacky{
493205408Srdivacky	srv_conf->auth = NULL;
494205219Srdivacky	srv_conf->return_uri = NULL;
495205219Srdivacky	srv_conf->tls_ca = NULL;
496193326Sed	srv_conf->tls_ca_file = NULL;
497193326Sed	srv_conf->tls_cert = NULL;
498193326Sed	srv_conf->tls_cert_file = NULL;
499193326Sed	srv_conf->tls_crl = NULL;
500193326Sed	srv_conf->tls_crl_file = NULL;
501193326Sed	srv_conf->tls_key = NULL;
502193326Sed	srv_conf->tls_key_file = NULL;
503193326Sed	srv_conf->tls_ocsp_staple = NULL;
504193326Sed	srv_conf->tls_ocsp_staple_file = NULL;
505193326Sed	TAILQ_INIT(&srv_conf->fcgiparams);
506193326Sed}
507193326Sed
508193326Sedstruct server *
509198092Srdivackyserver_byaddr(struct sockaddr *addr, in_port_t port)
510193326Sed{
511193326Sed	struct server	*srv;
512193326Sed
513193326Sed	TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
514193326Sed		if (port == srv->srv_conf.port &&
515193326Sed		    sockaddr_cmp((struct sockaddr *)&srv->srv_conf.ss,
516193326Sed		    addr, srv->srv_conf.prefixlen) == 0)
517193326Sed			return (srv);
518198092Srdivacky	}
519193326Sed
520193326Sed	return (NULL);
521193326Sed}
522198092Srdivacky
523193326Sedstruct server_config *
524193326Sedserverconfig_byid(uint32_t id)
525193326Sed{
526193326Sed	struct server		*srv;
527193326Sed	struct server_config	*srv_conf;
528193326Sed
529193326Sed	TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
530193326Sed		if (srv->srv_conf.id == id)
531193326Sed			return (&srv->srv_conf);
532193326Sed		TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) {
533193326Sed			if (srv_conf->id == id)
534193326Sed				return (srv_conf);
535193326Sed		}
536193326Sed	}
537193326Sed
538193326Sed	return (NULL);
539193326Sed}
540193326Sed
541193326Sedstruct server *
542193326Sedserver_byid(uint32_t id)
543193326Sed{
544193326Sed	struct server	*srv;
545193326Sed
546193326Sed	TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
547193326Sed		if (srv->srv_conf.id == id)
548193326Sed			return (srv);
549193326Sed	}
550193326Sed	return (NULL);
551193326Sed}
552193326Sed
553193326Sedint
554193326Sedserver_foreach(int (*srv_cb)(struct server *,
555193326Sed    struct server_config *, void *), void *arg)
556193326Sed{
557198092Srdivacky	struct server		*srv;
558193326Sed	struct server_config	*srv_conf;
559193326Sed
560193326Sed	TAILQ_FOREACH(srv, httpd_env->sc_servers, srv_entry) {
561193326Sed		if ((srv_cb)(srv, &srv->srv_conf, arg) == -1)
562193326Sed			return (-1);
563193326Sed		TAILQ_FOREACH(srv_conf, &srv->srv_hosts, entry) {
564193326Sed			if ((srv_cb)(srv, srv_conf, arg) == -1)
565193326Sed				return (-1);
566193326Sed		}
567193326Sed	}
568193326Sed
569198092Srdivacky	return (0);
570193326Sed}
571198092Srdivacky
572193326Sedstruct server *
573193326Sedserver_match(struct server *s2, int match_name)
574193326Sed{
575193326Sed	struct server	*s1;
576193326Sed
577193326Sed	/* Attempt to find matching server. */
578198092Srdivacky	TAILQ_FOREACH(s1, httpd_env->sc_servers, srv_entry) {
579193326Sed		if ((s1->srv_conf.flags & SRVFLAG_LOCATION) != 0)
580193326Sed			continue;
581193326Sed		if (match_name) {
582193326Sed			if (strcmp(s1->srv_conf.name, s2->srv_conf.name) != 0)
583193326Sed				continue;
584193326Sed		}
585193326Sed		if (s1->srv_conf.port != s2->srv_conf.port)
586193326Sed			continue;
587193326Sed		if (sockaddr_cmp(
588193326Sed		    (struct sockaddr *)&s1->srv_conf.ss,
589193326Sed		    (struct sockaddr *)&s2->srv_conf.ss,
590193326Sed		    s1->srv_conf.prefixlen) != 0)
591193326Sed			continue;
592193326Sed
593193326Sed		return (s1);
594193326Sed	}
595193326Sed
596198092Srdivacky	return (NULL);
597193326Sed}
598193326Sed
599193326Sedint
600193326Sedserver_socket_af(struct sockaddr_storage *ss, in_port_t port)
601193326Sed{
602193326Sed	switch (ss->ss_family) {
603193326Sed	case AF_INET:
604193326Sed		((struct sockaddr_in *)ss)->sin_port = port;
605203955Srdivacky		((struct sockaddr_in *)ss)->sin_len =
606203955Srdivacky		    sizeof(struct sockaddr_in);
607203955Srdivacky		break;
608203955Srdivacky	case AF_INET6:
609203955Srdivacky		((struct sockaddr_in6 *)ss)->sin6_port = port;
610203955Srdivacky		((struct sockaddr_in6 *)ss)->sin6_len =
611203955Srdivacky		    sizeof(struct sockaddr_in6);
612193326Sed		break;
613193326Sed	default:
614193326Sed		return (-1);
615193326Sed	}
616193326Sed
617193326Sed	return (0);
618193326Sed}
619193326Sed
620193326Sedin_port_t
621193326Sedserver_socket_getport(struct sockaddr_storage *ss)
622193326Sed{
623193326Sed	switch (ss->ss_family) {
624193326Sed	case AF_INET:
625193326Sed		return (((struct sockaddr_in *)ss)->sin_port);
626193326Sed	case AF_INET6:
627193326Sed		return (((struct sockaddr_in6 *)ss)->sin6_port);
628193326Sed	default:
629193326Sed		return (0);
630193326Sed	}
631193326Sed
632193326Sed	/* NOTREACHED */
633193326Sed	return (0);
634193326Sed}
635193326Sed
636193326Sedint
637198092Srdivackyserver_socket(struct sockaddr_storage *ss, in_port_t port,
638193326Sed    struct server_config *srv_conf, int fd, int reuseport)
639193326Sed{
640193326Sed	struct linger	lng;
641193326Sed	int		s = -1, val;
642198092Srdivacky
643193326Sed	if (server_socket_af(ss, port) == -1)
644193326Sed		goto bad;
645193326Sed
646193326Sed	s = fd == -1 ? socket(ss->ss_family, SOCK_STREAM | SOCK_NONBLOCK,
647193326Sed	    IPPROTO_TCP) : fd;
648193326Sed	if (s == -1)
649193326Sed		goto bad;
650193326Sed
651193326Sed	/*
652193326Sed	 * Socket options
653193326Sed	 */
654193326Sed	memset(&lng, 0, sizeof(lng));
655198092Srdivacky	if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
656193326Sed		goto bad;
657193326Sed	if (reuseport) {
658193326Sed		val = 1;
659193326Sed		if (setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val,
660198092Srdivacky		    sizeof(int)) == -1)
661193326Sed			goto bad;
662193326Sed	}
663193326Sed	if (srv_conf->tcpflags & TCPFLAG_BUFSIZ) {
664193326Sed		val = srv_conf->tcpbufsiz;
665193326Sed		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF,
666193326Sed		    &val, sizeof(val)) == -1)
667193326Sed			goto bad;
668193326Sed		val = srv_conf->tcpbufsiz;
669193326Sed		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF,
670193326Sed		    &val, sizeof(val)) == -1)
671193326Sed			goto bad;
672193326Sed	}
673193326Sed
674193326Sed	/*
675193326Sed	 * IP options
676193326Sed	 */
677193326Sed	if (srv_conf->tcpflags & TCPFLAG_IPTTL) {
678193326Sed		val = (int)srv_conf->tcpipttl;
679193326Sed		switch (ss->ss_family) {
680193326Sed		case AF_INET:
681193326Sed			if (setsockopt(s, IPPROTO_IP, IP_TTL,
682193326Sed			    &val, sizeof(val)) == -1)
683193326Sed				goto bad;
684193326Sed			break;
685193326Sed		case AF_INET6:
686193326Sed			if (setsockopt(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS,
687193326Sed			    &val, sizeof(val)) == -1)
688193326Sed				goto bad;
689193326Sed			break;
690198092Srdivacky		}
691193326Sed	}
692193326Sed	if (srv_conf->tcpflags & TCPFLAG_IPMINTTL) {
693198092Srdivacky		val = (int)srv_conf->tcpipminttl;
694193326Sed		switch (ss->ss_family) {
695193326Sed		case AF_INET:
696193326Sed			if (setsockopt(s, IPPROTO_IP, IP_MINTTL,
697193326Sed			    &val, sizeof(val)) == -1)
698193326Sed				goto bad;
699193326Sed			break;
700193326Sed		case AF_INET6:
701193326Sed			if (setsockopt(s, IPPROTO_IPV6, IPV6_MINHOPCOUNT,
702193326Sed			    &val, sizeof(val)) == -1)
703193326Sed				goto bad;
704193326Sed			break;
705193326Sed		}
706193326Sed	}
707193326Sed
708193326Sed	/*
709193326Sed	 * TCP options
710193326Sed	 */
711205219Srdivacky	if (srv_conf->tcpflags & (TCPFLAG_NODELAY|TCPFLAG_NNODELAY)) {
712205219Srdivacky		if (srv_conf->tcpflags & TCPFLAG_NNODELAY)
713193326Sed			val = 0;
714193326Sed		else
715193326Sed			val = 1;
716198092Srdivacky		if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY,
717193326Sed		    &val, sizeof(val)) == -1)
718205219Srdivacky			goto bad;
719205219Srdivacky	}
720205219Srdivacky	if (srv_conf->tcpflags & (TCPFLAG_SACK|TCPFLAG_NSACK)) {
721205219Srdivacky		if (srv_conf->tcpflags & TCPFLAG_NSACK)
722205219Srdivacky			val = 0;
723205219Srdivacky		else
724205219Srdivacky			val = 1;
725193326Sed		if (setsockopt(s, IPPROTO_TCP, TCP_SACK_ENABLE,
726193326Sed		    &val, sizeof(val)) == -1)
727193326Sed			goto bad;
728193326Sed	}
729193326Sed
730205219Srdivacky	return (s);
731205219Srdivacky
732205219Srdivacky bad:
733205219Srdivacky	if (s != -1)
734205219Srdivacky		close(s);
735205219Srdivacky	return (-1);
736198092Srdivacky}
737205219Srdivacky
738205219Srdivackyint
739205219Srdivackyserver_socket_listen(struct sockaddr_storage *ss, in_port_t port,
740193326Sed    struct server_config *srv_conf)
741193326Sed{
742193326Sed	int s;
743193326Sed
744193326Sed	if ((s = server_socket(ss, port, srv_conf, -1, 1)) == -1)
745193326Sed		return (-1);
746205219Srdivacky
747205219Srdivacky	if (bind(s, (struct sockaddr *)ss, ss->ss_len) == -1)
748193326Sed		goto bad;
749193326Sed	if (listen(s, srv_conf->tcpbacklog) == -1)
750205219Srdivacky		goto bad;
751193326Sed
752193326Sed	return (s);
753205219Srdivacky
754205219Srdivacky bad:
755193326Sed	close(s);
756193326Sed	return (-1);
757205219Srdivacky}
758193326Sed
759193326Sedint
760205219Srdivackyserver_socket_connect(struct sockaddr_storage *ss, in_port_t port,
761205219Srdivacky    struct server_config *srv_conf)
762205219Srdivacky{
763205219Srdivacky	int	s;
764205219Srdivacky
765205219Srdivacky	if ((s = server_socket(ss, port, srv_conf, -1, 0)) == -1)
766193326Sed		return (-1);
767205219Srdivacky
768205219Srdivacky	if (connect(s, (struct sockaddr *)ss, ss->ss_len) == -1) {
769205219Srdivacky		if (errno != EINPROGRESS)
770198092Srdivacky			goto bad;
771193326Sed	}
772193326Sed
773193326Sed	return (s);
774198092Srdivacky
775193326Sed bad:
776193326Sed	close(s);
777198092Srdivacky	return (-1);
778193326Sed}
779193326Sed
780193326Sedvoid
781193326Sedserver_tls_readcb(int fd, short event, void *arg)
782193326Sed{
783193326Sed	struct bufferevent	*bufev = arg;
784193326Sed	struct client		*clt = bufev->cbarg;
785193326Sed	char			 rbuf[IBUF_READ_SIZE];
786193326Sed	int			 what = EVBUFFER_READ;
787193326Sed	int			 howmuch = IBUF_READ_SIZE;
788193326Sed	ssize_t			 ret;
789193326Sed	size_t			 len;
790198092Srdivacky
791193326Sed	if (event == EV_TIMEOUT) {
792193326Sed		what |= EVBUFFER_TIMEOUT;
793193326Sed		goto err;
794193326Sed	}
795193326Sed
796193326Sed	if (bufev->wm_read.high != 0)
797193326Sed		howmuch = MINIMUM(sizeof(rbuf), bufev->wm_read.high);
798193326Sed
799193326Sed	ret = tls_read(clt->clt_tls_ctx, rbuf, howmuch);
800193326Sed	if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) {
801193326Sed		goto retry;
802193326Sed	} else if (ret == -1) {
803193326Sed		what |= EVBUFFER_ERROR;
804198092Srdivacky		goto err;
805193326Sed	}
806193326Sed	len = ret;
807193326Sed
808193326Sed	if (len == 0) {
809193326Sed		what |= EVBUFFER_EOF;
810193326Sed		goto err;
811193326Sed	}
812193326Sed
813193326Sed	if (evbuffer_add(bufev->input, rbuf, len) == -1) {
814193326Sed		what |= EVBUFFER_ERROR;
815205219Srdivacky		goto err;
816205219Srdivacky	}
817193326Sed
818193326Sed	server_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
819193326Sed
820193326Sed	len = EVBUFFER_LENGTH(bufev->input);
821193326Sed	if (bufev->wm_read.low != 0 && len < bufev->wm_read.low)
822193326Sed		return;
823198092Srdivacky	if (bufev->wm_read.high != 0 && len > bufev->wm_read.high) {
824193326Sed		struct evbuffer *buf = bufev->input;
825193326Sed		event_del(&bufev->ev_read);
826205219Srdivacky		evbuffer_setcb(buf, bufferevent_read_pressure_cb, bufev);
827205219Srdivacky		return;
828205219Srdivacky	}
829205219Srdivacky
830205219Srdivacky	if (bufev->readcb != NULL)
831205219Srdivacky		(*bufev->readcb)(bufev, bufev->cbarg);
832205219Srdivacky	return;
833205219Srdivacky
834205219Srdivacky retry:
835193326Sed	server_bufferevent_add(&bufev->ev_read, bufev->timeout_read);
836193326Sed	return;
837193326Sed
838193326Sed err:
839193326Sed	(*bufev->errorcb)(bufev, what, bufev->cbarg);
840193326Sed}
841198092Srdivacky
842193326Sedvoid
843193326Sedserver_tls_writecb(int fd, short event, void *arg)
844193326Sed{
845198092Srdivacky	struct bufferevent	*bufev = arg;
846193326Sed	struct client		*clt = bufev->cbarg;
847193326Sed	ssize_t			 ret;
848193326Sed	short			 what = EVBUFFER_WRITE;
849193326Sed	size_t			 len;
850193326Sed
851193326Sed	if (event == EV_TIMEOUT) {
852193326Sed		what |= EVBUFFER_TIMEOUT;
853193326Sed		goto err;
854193326Sed	}
855193326Sed
856193326Sed	if (EVBUFFER_LENGTH(bufev->output)) {
857193326Sed		ret = tls_write(clt->clt_tls_ctx,
858193326Sed		    EVBUFFER_DATA(bufev->output),
859193326Sed		    EVBUFFER_LENGTH(bufev->output));
860193326Sed		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT) {
861198092Srdivacky			goto retry;
862193326Sed		} else if (ret == -1) {
863193326Sed			what |= EVBUFFER_ERROR;
864193326Sed			goto err;
865193326Sed		}
866193326Sed		len = ret;
867193326Sed		evbuffer_drain(bufev->output, len);
868193326Sed	}
869193326Sed
870193326Sed	if (EVBUFFER_LENGTH(bufev->output) != 0)
871193326Sed		server_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
872193326Sed
873193326Sed	if (bufev->writecb != NULL &&
874193326Sed	    EVBUFFER_LENGTH(bufev->output) <= bufev->wm_write.low)
875193326Sed		(*bufev->writecb)(bufev, bufev->cbarg);
876193326Sed	return;
877193326Sed
878193326Sed retry:
879193326Sed	server_bufferevent_add(&bufev->ev_write, bufev->timeout_write);
880193326Sed	return;
881193326Sed
882193326Sed err:
883198092Srdivacky	(*bufev->errorcb)(bufev, what, bufev->cbarg);
884193326Sed}
885193326Sed
886193326Sedvoid
887193326Sedserver_input(struct client *clt)
888193326Sed{
889193326Sed	struct server_config	*srv_conf = clt->clt_srv_conf;
890198092Srdivacky	evbuffercb		 inrd = server_read;
891193326Sed	evbuffercb		 inwr = server_write;
892193326Sed	socklen_t		 slen;
893198092Srdivacky
894193326Sed	if (server_httpdesc_init(clt) == -1) {
895193326Sed		server_close(clt, "failed to allocate http descriptor");
896193326Sed		return;
897193326Sed	}
898193326Sed
899193326Sed	clt->clt_toread = TOREAD_HTTP_HEADER;
900193326Sed	inrd = server_read_http;
901193326Sed
902198092Srdivacky	slen = sizeof(clt->clt_sndbufsiz);
903193326Sed	if (getsockopt(clt->clt_s, SOL_SOCKET, SO_SNDBUF,
904193326Sed	    &clt->clt_sndbufsiz, &slen) == -1) {
905193326Sed		server_close(clt, "failed to get send buffer size");
906193326Sed		return;
907193326Sed	}
908198092Srdivacky
909193326Sed	/*
910193326Sed	 * Client <-> Server
911193326Sed	 */
912198092Srdivacky	clt->clt_bev = bufferevent_new(clt->clt_s, inrd, inwr,
913193326Sed	    server_error, clt);
914193326Sed	if (clt->clt_bev == NULL) {
915193326Sed		server_close(clt, "failed to allocate input buffer event");
916193326Sed		return;
917193326Sed	}
918193326Sed
919193326Sed	if (srv_conf->flags & SRVFLAG_TLS) {
920205219Srdivacky		event_set(&clt->clt_bev->ev_read, clt->clt_s, EV_READ,
921205219Srdivacky		    server_tls_readcb, clt->clt_bev);
922193326Sed		event_set(&clt->clt_bev->ev_write, clt->clt_s, EV_WRITE,
923193326Sed		    server_tls_writecb, clt->clt_bev);
924193326Sed	}
925193326Sed
926205219Srdivacky	/* Adjust write watermark to the socket buffer output size */
927205219Srdivacky	bufferevent_setwatermark(clt->clt_bev, EV_WRITE,
928193326Sed	    SERVER_MIN_PREFETCHED * clt->clt_sndbufsiz, 0);
929193326Sed	/* Read at most amount of data that fits in one fcgi record. */
930193326Sed	bufferevent_setwatermark(clt->clt_bev, EV_READ, 0, FCGI_CONTENT_SIZE);
931193326Sed
932193326Sed	bufferevent_settimeout(clt->clt_bev,
933193326Sed	    srv_conf->requesttimeout.tv_sec, srv_conf->requesttimeout.tv_sec);
934198092Srdivacky	bufferevent_enable(clt->clt_bev, EV_READ|EV_WRITE);
935193326Sed}
936193326Sed
937193326Sedvoid
938193326Sedserver_write(struct bufferevent *bev, void *arg)
939193326Sed{
940193326Sed	struct client		*clt = arg;
941198092Srdivacky	struct evbuffer		*dst = EVBUFFER_OUTPUT(bev);
942193326Sed
943193326Sed	if (EVBUFFER_LENGTH(dst) == 0 &&
944193326Sed	    clt->clt_toread == TOREAD_HTTP_NONE)
945193326Sed		goto done;
946193326Sed
947193326Sed	getmonotime(&clt->clt_tv_last);
948193326Sed
949193326Sed	if (clt->clt_done)
950193326Sed		goto done;
951198092Srdivacky
952193326Sed	if (clt->clt_srvbev && clt->clt_srvbev_throttled) {
953193326Sed		bufferevent_enable(clt->clt_srvbev, EV_READ);
954193326Sed		clt->clt_srvbev_throttled = 0;
955193326Sed	}
956198092Srdivacky
957193326Sed	return;
958193326Sed done:
959193326Sed	(*bev->errorcb)(bev, EVBUFFER_WRITE, bev->cbarg);
960193326Sed	return;
961193326Sed}
962193326Sed
963193326Sedvoid
964193326Sedserver_dump(struct client *clt, const void *buf, size_t len)
965193326Sed{
966193326Sed	if (!len)
967205219Srdivacky		return;
968205219Srdivacky
969193326Sed	/*
970198092Srdivacky	 * This function will dump the specified message directly
971205219Srdivacky	 * to the underlying client, without waiting for success
972193326Sed	 * of non-blocking events etc. This is useful to print an
973193326Sed	 * error message before gracefully closing the client.
974193326Sed	 */
975193326Sed	if (clt->clt_tls_ctx != NULL)
976193326Sed		(void)tls_write(clt->clt_tls_ctx, buf, len);
977193326Sed	else
978193326Sed		(void)write(clt->clt_s, buf, len);
979193326Sed}
980193326Sed
981193326Sedvoid
982193326Sedserver_read(struct bufferevent *bev, void *arg)
983193326Sed{
984198092Srdivacky	struct client		*clt = arg;
985193326Sed	struct evbuffer		*src = EVBUFFER_INPUT(bev);
986193326Sed
987198092Srdivacky	getmonotime(&clt->clt_tv_last);
988193326Sed
989193326Sed	if (!EVBUFFER_LENGTH(src))
990198092Srdivacky		return;
991193326Sed	if (server_bufferevent_write_buffer(clt, src) == -1)
992193326Sed		goto fail;
993193326Sed	if (clt->clt_done)
994198092Srdivacky		goto done;
995205219Srdivacky
996193326Sed	if (EVBUFFER_LENGTH(EVBUFFER_OUTPUT(clt->clt_bev)) > (size_t)
997193326Sed	    SERVER_MAX_PREFETCH * clt->clt_sndbufsiz) {
998193326Sed		bufferevent_disable(clt->clt_srvbev, EV_READ);
999198092Srdivacky		clt->clt_srvbev_throttled = 1;
1000193326Sed	}
1001193326Sed
1002193326Sed	return;
1003193326Sed done:
1004193326Sed	(*bev->errorcb)(bev, EVBUFFER_READ, bev->cbarg);
1005193326Sed	return;
1006193326Sed fail:
1007193326Sed	server_close(clt, strerror(errno));
1008193326Sed}
1009193326Sed
1010193326Sedvoid
1011193326Sedserver_error(struct bufferevent *bev, short error, void *arg)
1012193326Sed{
1013193326Sed	struct client		*clt = arg;
1014193326Sed	struct evbuffer		*dst;
1015193326Sed
1016193326Sed	if (error & EVBUFFER_TIMEOUT) {
1017198092Srdivacky		if (!clt->clt_headersdone && clt->clt_line > 0)
1018193326Sed			server_abort_http(clt, 408, "timeout");
1019198092Srdivacky		else
1020193326Sed			server_close(clt, "timeout");
1021193326Sed		return;
1022193326Sed	}
1023193326Sed	if (error & EVBUFFER_ERROR) {
1024193326Sed		if (errno == EFBIG) {
1025193326Sed			bufferevent_enable(bev, EV_READ);
1026193326Sed			return;
1027193326Sed		}
1028193326Sed		server_close(clt, "buffer event error");
1029193326Sed		return;
1030193326Sed	}
1031193326Sed	if (error & EVBUFFER_EOF) {
1032193326Sed		server_close(clt, "closed");
1033193326Sed		return;
1034193326Sed	}
1035194613Sed	if (error & (EVBUFFER_READ|EVBUFFER_WRITE)) {
1036194613Sed		bufferevent_disable(bev, EV_READ|EV_WRITE);
1037194613Sed
1038194613Sed		clt->clt_done = 1;
1039194613Sed
1040194613Sed		dst = EVBUFFER_OUTPUT(clt->clt_bev);
1041194613Sed		if (EVBUFFER_LENGTH(dst)) {
1042194613Sed			/* Finish writing all data first */
1043193326Sed			bufferevent_enable(clt->clt_bev, EV_WRITE);
1044194613Sed			return;
1045194613Sed		}
1046194613Sed
1047194613Sed		server_close(clt, "done");
1048198092Srdivacky		return;
1049194613Sed	}
1050194613Sed	server_close(clt, "unknown event error");
1051205219Srdivacky	return;
1052205219Srdivacky}
1053205219Srdivacky
1054205219Srdivackyvoid
1055205219Srdivackyserver_accept(int fd, short event, void *arg)
1056205219Srdivacky{
1057194613Sed	struct server		*srv = arg;
1058200583Srdivacky	struct client		*clt = NULL;
1059200583Srdivacky	socklen_t		 slen;
1060200583Srdivacky	struct sockaddr_storage	 ss;
1061200583Srdivacky	int			 s = -1;
1062200583Srdivacky
1063200583Srdivacky	event_add(&srv->srv_ev, NULL);
1064200583Srdivacky	if ((event & EV_TIMEOUT))
1065200583Srdivacky		return;
1066200583Srdivacky
1067200583Srdivacky	slen = sizeof(ss);
1068200583Srdivacky	if ((s = accept_reserve(fd, (struct sockaddr *)&ss,
1069200583Srdivacky	    &slen, FD_RESERVE, &server_inflight)) == -1) {
1070200583Srdivacky		/*
1071200583Srdivacky		 * Pause accept if we are out of file descriptors, or
1072200583Srdivacky		 * libevent will haunt us here too.
1073200583Srdivacky		 */
1074200583Srdivacky		if (errno == ENFILE || errno == EMFILE) {
1075200583Srdivacky			struct timeval evtpause = { 1, 0 };
1076200583Srdivacky
1077200583Srdivacky			event_del(&srv->srv_ev);
1078200583Srdivacky			evtimer_add(&srv->srv_evt, &evtpause);
1079200583Srdivacky			log_debug("%s: deferring connections", __func__);
1080200583Srdivacky		}
1081200583Srdivacky		return;
1082200583Srdivacky	}
1083200583Srdivacky	if (server_clients >= SERVER_MAX_CLIENTS)
1084204643Srdivacky		goto err;
1085205219Srdivacky
1086204643Srdivacky	if ((clt = calloc(1, sizeof(*clt))) == NULL)
1087204643Srdivacky		goto err;
1088204643Srdivacky
1089204643Srdivacky	/* Pre-allocate log buffer */
1090204643Srdivacky	clt->clt_log = evbuffer_new();
1091204643Srdivacky	if (clt->clt_log == NULL)
1092205219Srdivacky		goto err;
1093205219Srdivacky
1094204643Srdivacky	clt->clt_s = s;
1095204643Srdivacky	clt->clt_fd = -1;
1096204643Srdivacky	clt->clt_toread = TOREAD_UNLIMITED;
1097204643Srdivacky	clt->clt_srv = srv;
1098204643Srdivacky	clt->clt_srv_conf = &srv->srv_conf;
1099204643Srdivacky	clt->clt_id = ++server_cltid;
1100204643Srdivacky	clt->clt_srv_id = srv->srv_conf.id;
1101204643Srdivacky	clt->clt_pid = getpid();
1102200583Srdivacky	clt->clt_inflight = 1;
1103194613Sed
1104194613Sed	/* get local address */
1105195099Sed	slen = sizeof(clt->clt_srv_ss);
1106195099Sed	if (getsockname(s, (struct sockaddr *)&clt->clt_srv_ss,
1107195099Sed	    &slen) == -1) {
1108195099Sed		server_close(clt, "listen address lookup failed");
1109195099Sed		return;
1110195099Sed	}
1111195099Sed
1112195099Sed	/* get client address */
1113198092Srdivacky	memcpy(&clt->clt_ss, &ss, sizeof(clt->clt_ss));
1114195099Sed
1115195099Sed	/* get ports */
1116198092Srdivacky	switch (ss.ss_family) {
1117195099Sed	case AF_INET:
1118195099Sed		clt->clt_port = ((struct sockaddr_in *)&ss)->sin_port;
1119195099Sed		break;
1120194613Sed	case AF_INET6:
1121195099Sed		clt->clt_port = ((struct sockaddr_in6 *)&ss)->sin6_port;
1122195099Sed		break;
1123198092Srdivacky	}
1124195099Sed
1125195099Sed	getmonotime(&clt->clt_tv_start);
1126195099Sed	memcpy(&clt->clt_tv_last, &clt->clt_tv_start, sizeof(clt->clt_tv_last));
1127198092Srdivacky
1128195099Sed	server_clients++;
1129195099Sed	SPLAY_INSERT(client_tree, &srv->srv_clients, clt);
1130198092Srdivacky
1131195099Sed	/* Pre-allocate output buffer */
1132195099Sed	clt->clt_output = evbuffer_new();
1133195099Sed	if (clt->clt_output == NULL) {
1134195099Sed		server_close(clt, "failed to allocate output buffer");
1135195099Sed		return;
1136195099Sed	}
1137195099Sed
1138195099Sed	if (srv->srv_conf.flags & SRVFLAG_TLS) {
1139195099Sed		if (tls_accept_socket(srv->srv_tls_ctx, &clt->clt_tls_ctx,
1140195099Sed		    clt->clt_s) != 0) {
1141195099Sed			server_close(clt, "failed to accept tls socket");
1142195099Sed			return;
1143195099Sed		}
1144195099Sed		event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_READ,
1145195099Sed		    server_tls_handshake, &clt->clt_tv_start,
1146195099Sed		    &srv->srv_conf.timeout, clt);
1147195099Sed		return;
1148198092Srdivacky	}
1149195099Sed
1150195099Sed	server_input(clt);
1151198092Srdivacky	return;
1152195099Sed
1153198092Srdivacky err:
1154195099Sed	if (s != -1) {
1155195099Sed		close(s);
1156198092Srdivacky		free(clt);
1157195099Sed		/*
1158195099Sed		 * the client struct was not completely set up, but still
1159195099Sed		 * counted as an inflight client. account for this.
1160195099Sed		 */
1161195099Sed		server_inflight_dec(NULL, __func__);
1162195099Sed	}
1163195099Sed}
1164195099Sed
1165195099Sedvoid
1166195099Sedserver_tls_handshake(int fd, short event, void *arg)
1167195099Sed{
1168195099Sed	struct client *clt = (struct client *)arg;
1169195099Sed	struct server *srv = (struct server *)clt->clt_srv;
1170198092Srdivacky	int ret;
1171195099Sed
1172195099Sed	if (event == EV_TIMEOUT) {
1173198092Srdivacky		server_close(clt, "tls handshake timeout");
1174195099Sed		return;
1175198092Srdivacky	}
1176195099Sed
1177195099Sed	if (srv->srv_tls_ctx == NULL || clt->clt_tls_ctx == NULL)
1178195099Sed		fatalx("NULL tls context");
1179195099Sed
1180198092Srdivacky	ret = tls_handshake(clt->clt_tls_ctx);
1181200583Srdivacky	if (ret == 0) {
1182200583Srdivacky		server_input(clt);
1183200583Srdivacky	} else if (ret == TLS_WANT_POLLIN) {
1184200583Srdivacky		event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_READ,
1185200583Srdivacky		    server_tls_handshake, &clt->clt_tv_start,
1186198092Srdivacky		    &srv->srv_conf.timeout, clt);
1187200583Srdivacky	} else if (ret == TLS_WANT_POLLOUT) {
1188200583Srdivacky		event_again(&clt->clt_ev, clt->clt_s, EV_TIMEOUT|EV_WRITE,
1189200583Srdivacky		    server_tls_handshake, &clt->clt_tv_start,
1190200583Srdivacky		    &srv->srv_conf.timeout, clt);
1191200583Srdivacky	} else {
1192198092Srdivacky		log_debug("%s: tls handshake failed - %s", __func__,
1193200583Srdivacky		    tls_error(clt->clt_tls_ctx));
1194200583Srdivacky		server_close(clt, "tls handshake failed");
1195195099Sed	}
1196195099Sed}
1197193326Sed
1198193326Sedvoid
1199193326Sedserver_inflight_dec(struct client *clt, const char *why)
1200198092Srdivacky{
1201198092Srdivacky	if (clt != NULL) {
1202198092Srdivacky		/* the flight already left inflight mode. */
1203198092Srdivacky		if (clt->clt_inflight == 0)
1204198092Srdivacky			return;
1205198092Srdivacky		clt->clt_inflight = 0;
1206193326Sed	}
1207193326Sed
1208193326Sed	/* the file was never opened, thus this was an inflight client. */
1209193326Sed	server_inflight--;
1210193326Sed	DPRINTF("%s: inflight decremented, now %d, %s",
1211193326Sed	    __func__, server_inflight, why);
1212198092Srdivacky}
1213198092Srdivacky
1214198092Srdivackyvoid
1215198092Srdivackyserver_sendlog(struct server_config *srv_conf, int cmd, const char *emsg, ...)
1216198092Srdivacky{
1217193326Sed	va_list		 ap;
1218193326Sed	char		*msg;
1219193326Sed	int		 ret;
1220	struct iovec	 iov[2];
1221
1222	if (srv_conf->flags & SRVFLAG_SYSLOG) {
1223		va_start(ap, emsg);
1224		if (cmd == IMSG_LOG_ACCESS)
1225			vlog(LOG_INFO, emsg, ap);
1226		else
1227			vlog(LOG_DEBUG, emsg, ap);
1228		va_end(ap);
1229		return;
1230	}
1231
1232	va_start(ap, emsg);
1233	ret = vasprintf(&msg, emsg, ap);
1234	va_end(ap);
1235	if (ret == -1) {
1236		log_warn("%s: vasprintf", __func__);
1237		return;
1238	}
1239
1240	iov[0].iov_base = &srv_conf->id;
1241	iov[0].iov_len = sizeof(srv_conf->id);
1242	iov[1].iov_base = msg;
1243	iov[1].iov_len = ret + 1;
1244
1245	if (proc_composev(httpd_env->sc_ps, PROC_LOGGER, cmd, iov, 2) != 0) {
1246		log_warn("%s: failed to compose imsg", __func__);
1247		free(msg);
1248		return;
1249	}
1250	free(msg);
1251}
1252
1253void
1254server_log(struct client *clt, const char *msg)
1255{
1256	char			 ibuf[HOST_NAME_MAX+1], obuf[HOST_NAME_MAX+1];
1257	struct server_config	*srv_conf = clt->clt_srv_conf;
1258	char			*ptr = NULL, *vmsg = NULL;
1259	int			 debug_cmd = -1;
1260
1261	switch (srv_conf->logformat) {
1262	case LOG_FORMAT_CONNECTION:
1263		debug_cmd = IMSG_LOG_ACCESS;
1264		break;
1265	default:
1266		if (log_getverbose() > 1)
1267			debug_cmd = IMSG_LOG_ERROR;
1268		if (EVBUFFER_LENGTH(clt->clt_log)) {
1269			while ((ptr =
1270			    evbuffer_readline(clt->clt_log)) != NULL) {
1271				server_sendlog(srv_conf,
1272				    IMSG_LOG_ACCESS, "%s", ptr);
1273				free(ptr);
1274			}
1275		}
1276		break;
1277	}
1278
1279	if (debug_cmd != -1 && msg != NULL) {
1280		memset(ibuf, 0, sizeof(ibuf));
1281		memset(obuf, 0, sizeof(obuf));
1282		(void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf));
1283		(void)server_http_host(&clt->clt_srv_ss, obuf, sizeof(obuf));
1284		if (EVBUFFER_LENGTH(clt->clt_log) &&
1285		    evbuffer_add_printf(clt->clt_log, "\n") != -1)
1286			ptr = evbuffer_readline(clt->clt_log);
1287		(void)stravis(&vmsg, msg, HTTPD_LOGVIS);
1288		server_sendlog(srv_conf, debug_cmd, "server %s, "
1289		    "client %d (%d active), %s:%u -> %s, "
1290		    "%s%s%s", srv_conf->name, clt->clt_id, server_clients,
1291		    ibuf, ntohs(clt->clt_port), obuf, vmsg == NULL ? "" : vmsg,
1292		    ptr == NULL ? "" : ",", ptr == NULL ? "" : ptr);
1293		free(vmsg);
1294		free(ptr);
1295	}
1296}
1297
1298void
1299server_close(struct client *clt, const char *msg)
1300{
1301	struct server		*srv = clt->clt_srv;
1302
1303	if (clt->clt_fcgi_count-- > 0) {
1304		clt->clt_fcgi_error = msg;
1305		return;
1306	}
1307
1308	SPLAY_REMOVE(client_tree, &srv->srv_clients, clt);
1309
1310	/* free the HTTP descriptors incl. headers */
1311	server_close_http(clt);
1312
1313	/* tls_close must be called before the underlying socket is closed. */
1314	if (clt->clt_tls_ctx != NULL)
1315		tls_close(clt->clt_tls_ctx); /* XXX - error handling */
1316	tls_free(clt->clt_tls_ctx);
1317
1318	event_del(&clt->clt_ev);
1319	if (clt->clt_bev != NULL)
1320		bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE);
1321	if (clt->clt_srvbev != NULL)
1322		bufferevent_disable(clt->clt_srvbev, EV_READ|EV_WRITE);
1323
1324	server_log(clt, msg);
1325
1326	if (clt->clt_bev != NULL)
1327		bufferevent_free(clt->clt_bev);
1328	if (clt->clt_output != NULL)
1329		evbuffer_free(clt->clt_output);
1330	if (clt->clt_srvevb != NULL)
1331		evbuffer_free(clt->clt_srvevb);
1332
1333	if (clt->clt_srvbev != NULL)
1334		bufferevent_free(clt->clt_srvbev);
1335
1336	if (clt->clt_fd != -1)
1337		close(clt->clt_fd);
1338	if (clt->clt_s != -1)
1339		close(clt->clt_s);
1340
1341	server_inflight_dec(clt, __func__);
1342
1343	if (clt->clt_log != NULL)
1344		evbuffer_free(clt->clt_log);
1345
1346	free(clt);
1347	server_clients--;
1348}
1349
1350int
1351server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
1352{
1353	struct server			*srv;
1354	struct server_tls_ticket	 key;
1355
1356	switch (imsg->hdr.type) {
1357	case IMSG_CFG_MEDIA:
1358		config_getmedia(httpd_env, imsg);
1359		break;
1360	case IMSG_CFG_AUTH:
1361		config_getauth(httpd_env, imsg);
1362		break;
1363	case IMSG_CFG_SERVER:
1364		config_getserver(httpd_env, imsg);
1365		break;
1366	case IMSG_CFG_TLS:
1367		config_getserver_tls(httpd_env, imsg);
1368		break;
1369	case IMSG_CFG_FCGI:
1370		config_getserver_fcgiparams(httpd_env, imsg);
1371		break;
1372	case IMSG_CFG_DONE:
1373		config_getcfg(httpd_env, imsg);
1374		break;
1375	case IMSG_CTL_START:
1376		server_launch();
1377		break;
1378	case IMSG_CTL_RESET:
1379		config_getreset(httpd_env, imsg);
1380		break;
1381	case IMSG_TLSTICKET_REKEY:
1382		IMSG_SIZE_CHECK(imsg, (&key));
1383		memcpy(&key, imsg->data, sizeof(key));
1384		/* apply to the right server */
1385		srv = server_byid(key.tt_id);
1386		if (srv) {
1387			tls_config_add_ticket_key(srv->srv_tls_config,
1388			    key.tt_keyrev, key.tt_key, sizeof(key.tt_key));
1389		}
1390		break;
1391	default:
1392		return (-1);
1393	}
1394
1395	return (0);
1396}
1397
1398int
1399server_dispatch_logger(int fd, struct privsep_proc *p, struct imsg *imsg)
1400{
1401	switch (imsg->hdr.type) {
1402	default:
1403		return (-1);
1404	}
1405
1406	return (0);
1407}
1408
1409int
1410server_bufferevent_add(struct event *ev, int timeout)
1411{
1412	struct timeval tv, *ptv = NULL;
1413
1414	if (timeout) {
1415		timerclear(&tv);
1416		tv.tv_sec = timeout;
1417		ptv = &tv;
1418	}
1419
1420	return (event_add(ev, ptv));
1421}
1422
1423int
1424server_bufferevent_printf(struct client *clt, const char *fmt, ...)
1425{
1426	int	 ret;
1427	va_list	 ap;
1428	char	*str;
1429
1430	va_start(ap, fmt);
1431	ret = vasprintf(&str, fmt, ap);
1432	va_end(ap);
1433
1434	if (ret == -1)
1435		return (ret);
1436
1437	ret = server_bufferevent_print(clt, str);
1438	free(str);
1439
1440	return (ret);
1441}
1442
1443int
1444server_bufferevent_print(struct client *clt, const char *str)
1445{
1446	if (clt->clt_bev == NULL)
1447		return (evbuffer_add(clt->clt_output, str, strlen(str)));
1448	return (bufferevent_write(clt->clt_bev, str, strlen(str)));
1449}
1450
1451int
1452server_bufferevent_write_buffer(struct client *clt, struct evbuffer *buf)
1453{
1454	if (clt->clt_bev == NULL)
1455		return (evbuffer_add_buffer(clt->clt_output, buf));
1456	return (bufferevent_write_buffer(clt->clt_bev, buf));
1457}
1458
1459int
1460server_bufferevent_write_chunk(struct client *clt,
1461    struct evbuffer *buf, size_t size)
1462{
1463	int ret;
1464	ret = server_bufferevent_write(clt, EVBUFFER_DATA(buf), size);
1465	if (ret != -1)
1466		evbuffer_drain(buf, size);
1467	return (ret);
1468}
1469
1470int
1471server_bufferevent_write(struct client *clt, void *data, size_t size)
1472{
1473	if (clt->clt_bev == NULL)
1474		return (evbuffer_add(clt->clt_output, data, size));
1475	return (bufferevent_write(clt->clt_bev, data, size));
1476}
1477
1478int
1479server_client_cmp(struct client *a, struct client *b)
1480{
1481	return ((int)a->clt_id - b->clt_id);
1482}
1483
1484SPLAY_GENERATE(client_tree, client, clt_nodes, server_client_cmp);
1485