aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReyk Floeter <reyk@esdenera.com>2014-07-12 21:02:10 +0200
committerReyk Floeter <reyk@esdenera.com>2014-07-12 21:02:10 +0200
commit75854f383606390a964f7de8760dde1666f5a8af (patch)
tree193b8e332aa6b5b9a7f673d32cb6412906d564fb
parent1f017dae0c723632bcf3737e2de8c4a9b286b0d1 (diff)
downloadhttpd-75854f383606390a964f7de8760dde1666f5a8af.tar.gz
httpd-75854f383606390a964f7de8760dde1666f5a8af.zip
- configure and run the servers
- replay bcopy/bzero with memcpy/memset
-rw-r--r--config.c85
-rw-r--r--httpd.c17
-rw-r--r--httpd.h6
-rw-r--r--log.c2
-rw-r--r--parse.y89
-rw-r--r--server.c14
6 files changed, 186 insertions, 27 deletions
diff --git a/config.c b/config.c
index bc26f7d..affe3b2 100644
--- a/config.c
+++ b/config.c
@@ -137,5 +137,90 @@ config_getcfg(struct httpd *env, struct imsg *imsg)
what = ps->ps_what[privsep_process];
+ if (privsep_process != PROC_PARENT)
+ proc_compose_imsg(env->sc_ps, PROC_PARENT, -1,
+ IMSG_CFG_DONE, -1, NULL, 0);
+
+ return (0);
+}
+
+int
+config_setserver(struct httpd *env, struct server *srv)
+{
+ struct privsep *ps = env->sc_ps;
+ struct server_config s;
+ int id;
+ int fd, n, m;
+ struct iovec iov[6];
+ size_t c;
+ u_int what;
+
+ /* opens listening sockets etc. */
+ if (server_privinit(srv) == -1)
+ return (-1);
+
+ for (id = 0; id < PROC_MAX; id++) {
+ what = ps->ps_what[id];
+
+ if ((what & CONFIG_SERVERS) == 0 || id == privsep_process)
+ continue;
+
+ DPRINTF("%s: sending server %s to %s fd %d", __func__,
+ srv->srv_conf.name, ps->ps_title[id], srv->srv_s);
+
+ memcpy(&s, &srv->srv_conf, sizeof(s));
+
+ c = 0;
+ iov[c].iov_base = &s;
+ iov[c++].iov_len = sizeof(s);
+
+ if (id == PROC_SERVER) {
+ /* XXX imsg code will close the fd after 1st call */
+ n = -1;
+ proc_range(ps, id, &n, &m);
+ for (n = 0; n < m; n++) {
+ if ((fd = dup(srv->srv_s)) == -1)
+ return (-1);
+ proc_composev_imsg(ps, id, n,
+ IMSG_CFG_SERVER, fd, iov, c);
+ }
+ } else {
+ proc_composev_imsg(ps, id, -1, IMSG_CFG_SERVER, -1,
+ iov, c);
+ }
+ }
+
+ close(srv->srv_s);
+ srv->srv_s = -1;
+
+ return (0);
+}
+
+int
+config_getserver(struct httpd *env, struct imsg *imsg)
+{
+ struct privsep *ps = env->sc_ps;
+ struct server *srv;
+ u_int8_t *p = imsg->data;
+ size_t s;
+
+ if ((srv = calloc(1, sizeof(*srv))) == NULL) {
+ close(imsg->fd);
+ return (-1);
+ }
+
+ IMSG_SIZE_CHECK(imsg, &srv->srv_conf);
+ memcpy(&srv->srv_conf, p, sizeof(srv->srv_conf));
+ s = sizeof(srv->srv_conf);
+
+ srv->srv_s = imsg->fd;
+
+ SPLAY_INIT(&srv->srv_clients);
+ TAILQ_INSERT_TAIL(env->sc_servers, srv, srv_entry);
+
+ DPRINTF("%s: %s %d received configuration \"%s\"", __func__,
+ ps->ps_title[privsep_process], ps->ps_instance,
+ srv->srv_conf.name);
+
return (0);
}
diff --git a/httpd.c b/httpd.c
index 73ab565..5f9c17d 100644
--- a/httpd.c
+++ b/httpd.c
@@ -268,11 +268,12 @@ parent_configure(struct httpd *env)
int id;
struct ctl_flags cf;
int ret = -1;
+ struct server *srv;
-#if 0
- TAILQ_FOREACH(srv, env->sc_server, entry)
- config_setserver(env, srv);
-#endif
+ TAILQ_FOREACH(srv, env->sc_servers, srv_entry) {
+ if (config_setserver(env, srv) == -1)
+ fatal("create server");
+ }
/* The servers need to reload their config. */
env->sc_reload = env->sc_prefork_server;
@@ -392,13 +393,13 @@ event_again(struct event *ev, int fd, short event,
struct timeval tv_next, tv_now, tv;
getmonotime(&tv_now);
- bcopy(end, &tv_next, sizeof(tv_next));
+ memcpy(&tv_next, end, sizeof(tv_next));
timersub(&tv_now, start, &tv_now);
timersub(&tv_next, &tv_now, &tv_next);
- bzero(&tv, sizeof(tv));
+ memset(&tv, 0, sizeof(tv));
if (timercmp(&tv_next, &tv, >))
- bcopy(&tv_next, &tv, sizeof(tv));
+ memcpy(&tv, &tv_next, sizeof(tv));
event_del(ev);
event_set(ev, fd, event, fn, arg);
@@ -431,7 +432,7 @@ canonicalize_host(const char *host, char *name, size_t len)
/* 1. remove repeated dots and convert upper case to lower case */
plen = strlen(host);
- bzero(name, len);
+ memset(name, 0, len);
for (i = j = 0; i < plen; i++) {
if (j >= (len - 1))
goto fail;
diff --git a/httpd.h b/httpd.h
index f871583..0b9f864 100644
--- a/httpd.h
+++ b/httpd.h
@@ -69,7 +69,6 @@ enum httpchunk {
#if DEBUG > 1
#define DPRINTF log_debug
-#define DEBUG_CERT 1
#else
#define DPRINTF(x...) do {} while(0)
#endif
@@ -152,6 +151,7 @@ enum imsg_type {
IMSG_CTL_NOTIFY,
IMSG_CTL_END,
IMSG_CTL_START,
+ IMSG_CFG_SERVER,
IMSG_CFG_DONE
};
@@ -259,8 +259,6 @@ struct server {
u_int8_t srv_tcpipminttl;
int srv_s;
- in_port_t src_port;
- struct sockaddr_storage srv_ss;
struct bufferevent *srv_bev;
int srv_dsts;
struct bufferevent *srv_dstbev;
@@ -391,5 +389,7 @@ void config_purge(struct httpd *, u_int);
int config_setreset(struct httpd *, u_int);
int config_getreset(struct httpd *, struct imsg *);
int config_getcfg(struct httpd *, struct imsg *);
+int config_setserver(struct httpd *, struct server *);
+int config_getserver(struct httpd *, struct imsg *);
#endif /* _HTTPD_H */
diff --git a/log.c b/log.c
index 9e1adaf..ab6f469 100644
--- a/log.c
+++ b/log.c
@@ -213,7 +213,7 @@ printb_flags(const u_int32_t v, const char *bits)
char c, *p, *r;
p = r = buf[++idx % 2];
- bzero(p, BUFSIZ);
+ memset(p, 0, BUFSIZ);
if (bits) {
bits++;
diff --git a/parse.y b/parse.y
index f6b9669..7af8a53 100644
--- a/parse.y
+++ b/parse.y
@@ -130,6 +130,7 @@ typedef struct {
%token <v.string> STRING
%token <v.number> NUMBER
%type <v.number> loglevel
+%type <v.port> port
%%
@@ -231,8 +232,71 @@ serveropts_l : serveropts_l serveroptsl nl
| serveroptsl optnl
;
-serveroptsl : LISTEN ON STRING PORT NUMBER {
+serveroptsl : LISTEN ON STRING port {
+ struct addresslist al;
+ struct address *h;
+ struct server *s;
+
+ if (srv->srv_conf.ss.ss_family != AF_UNSPEC) {
+ yyerror("listen address already specified");
+ free($3);
+ YYERROR;
+ } else
+ s = srv;
+ if ($4.op != PF_OP_EQ) {
+ yyerror("invalid port");
+ free($3);
+ YYERROR;
+ }
+
+ TAILQ_INIT(&al);
+ if (host($3, &al, 1, &$4, NULL, -1) <= 0) {
+ yyerror("invalid listen ip: %s", $3);
+ free($3);
+ YYERROR;
+ }
free($3);
+ h = TAILQ_FIRST(&al);
+ memcpy(&srv->srv_conf.ss, &h->ss,
+ sizeof(s->srv_conf.ss));
+ s->srv_conf.port = h->port.val[0];
+ host_free(&al);
+ }
+ ;
+
+port : PORT STRING {
+ char *a, *b;
+ int p[2];
+
+ p[0] = p[1] = 0;
+
+ a = $2;
+ b = strchr($2, ':');
+ if (b == NULL)
+ $$.op = PF_OP_EQ;
+ else {
+ *b++ = '\0';
+ if ((p[1] = getservice(b)) == -1) {
+ free($2);
+ YYERROR;
+ }
+ $$.op = PF_OP_RRG;
+ }
+ if ((p[0] = getservice(a)) == -1) {
+ free($2);
+ YYERROR;
+ }
+ $$.val[0] = p[0];
+ $$.val[1] = p[1];
+ free($2);
+ }
+ | PORT NUMBER {
+ if ($2 <= 0 || $2 >= (int)USHRT_MAX) {
+ yyerror("invalid port: %d", $2);
+ YYERROR;
+ }
+ $$.val[0] = htons($2);
+ $$.op = PF_OP_EQ;
}
;
@@ -784,7 +848,7 @@ host_v4(const char *s)
struct sockaddr_in *sain;
struct address *h;
- bzero(&ina, sizeof(ina));
+ memset(&ina, 0, sizeof(ina));
if (inet_pton(AF_INET, s, &ina) != 1)
return (NULL);
@@ -805,7 +869,7 @@ host_v6(const char *s)
struct sockaddr_in6 *sa_in6;
struct address *h = NULL;
- bzero(&hints, sizeof(hints));
+ memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM; /* dummy */
hints.ai_flags = AI_NUMERICHOST;
@@ -840,7 +904,7 @@ host_dns(const char *s, struct addresslist *al, int max,
if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0)
return (cnt);
- bzero(&hints, sizeof(hints));
+ memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
error = getaddrinfo(s, NULL, &hints, &res0);
@@ -860,7 +924,7 @@ host_dns(const char *s, struct addresslist *al, int max,
fatal(NULL);
if (port != NULL)
- bcopy(port, &h->port, sizeof(h->port));
+ memcpy(&h->port, port, sizeof(h->port));
if (ifname != NULL) {
if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
sizeof(h->ifname))
@@ -923,7 +987,7 @@ host_if(const char *s, struct addresslist *al, int max,
fatal("calloc");
if (port != NULL)
- bcopy(port, &h->port, sizeof(h->port));
+ memcpy(&h->port, port, sizeof(h->port));
if (ifname != NULL) {
if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
sizeof(h->ifname))
@@ -981,7 +1045,7 @@ host(const char *s, struct addresslist *al, int max,
if (h != NULL) {
if (port != NULL)
- bcopy(port, &h->port, sizeof(h->port));
+ memcpy(&h->port, port, sizeof(h->port));
if (ifname != NULL) {
if (strlcpy(h->ifname, ifname, sizeof(h->ifname)) >=
sizeof(h->ifname)) {
@@ -1001,6 +1065,17 @@ host(const char *s, struct addresslist *al, int max,
return (host_dns(s, al, max, port, ifname, ipproto));
}
+void
+host_free(struct addresslist *al)
+{
+ struct address *h;
+
+ while ((h = TAILQ_FIRST(al)) != NULL) {
+ TAILQ_REMOVE(al, h, entry);
+ free(h);
+ }
+}
+
int
getservice(char *n)
{
diff --git a/server.c b/server.c
index 65912d8..b700b2f 100644
--- a/server.c
+++ b/server.c
@@ -123,7 +123,7 @@ server_init(struct privsep *ps, struct privsep_proc *p, void *arg)
#if 0
/* Schedule statistics timer */
evtimer_set(&env->sc_statev, server_statistics, NULL);
- bcopy(&env->sc_statinterval, &tv, sizeof(tv));
+ memcpy(&tv, &env->sc_statinterval, sizeof(tv));
evtimer_add(&env->sc_statev, &tv);
#endif
}
@@ -200,7 +200,7 @@ server_socket(struct sockaddr_storage *ss, in_port_t port,
/*
* Socket options
*/
- bzero(&lng, sizeof(lng));
+ memset(&lng, 0, sizeof(lng));
if (setsockopt(s, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)) == -1)
goto bad;
if (reuseport) {
@@ -460,7 +460,7 @@ server_accept(int fd, short event, void *arg)
memcpy(&clt->clt_ss, &ss, sizeof(clt->clt_ss));
getmonotime(&clt->clt_tv_start);
- bcopy(&clt->clt_tv_start, &clt->clt_tv_last, sizeof(clt->clt_tv_last));
+ memcpy(&clt->clt_tv_last, &clt->clt_tv_start, sizeof(clt->clt_tv_last));
server_clients++;
SPLAY_INSERT(client_tree, &srv->srv_clients, clt);
@@ -513,10 +513,10 @@ server_close(struct client *clt, const char *msg)
bufferevent_disable(clt->clt_bev, EV_READ|EV_WRITE);
if ((env->sc_opts & HTTPD_OPT_LOGUPDATE) && msg != NULL) {
- bzero(&ibuf, sizeof(ibuf));
- bzero(&obuf, sizeof(obuf));
+ memset(&ibuf, 0, sizeof(ibuf));
+ memset(&obuf, 0, sizeof(obuf));
(void)print_host(&clt->clt_ss, ibuf, sizeof(ibuf));
- (void)print_host(&srv->srv_ss, obuf, sizeof(obuf));
+ (void)print_host(&srv->srv_conf.ss, obuf, sizeof(obuf));
if (EVBUFFER_LENGTH(clt->clt_log) &&
evbuffer_add_printf(clt->clt_log, "\r\n") != -1)
ptr = evbuffer_readline(clt->clt_log);
@@ -557,11 +557,9 @@ int
server_dispatch_parent(int fd, struct privsep_proc *p, struct imsg *imsg)
{
switch (imsg->hdr.type) {
-#if 0
case IMSG_CFG_SERVER:
config_getserver(env, imsg);
break;
-#endif
case IMSG_CFG_DONE:
config_getcfg(env, imsg);
break;