diff options
author | Reyk Floeter <reyk@esdenera.com> | 2014-07-12 21:02:10 +0200 |
---|---|---|
committer | Reyk Floeter <reyk@esdenera.com> | 2014-07-12 21:02:10 +0200 |
commit | 75854f383606390a964f7de8760dde1666f5a8af (patch) | |
tree | 193b8e332aa6b5b9a7f673d32cb6412906d564fb | |
parent | 1f017dae0c723632bcf3737e2de8c4a9b286b0d1 (diff) | |
download | httpd-75854f383606390a964f7de8760dde1666f5a8af.tar.gz httpd-75854f383606390a964f7de8760dde1666f5a8af.zip |
- configure and run the servers
- replay bcopy/bzero with memcpy/memset
-rw-r--r-- | config.c | 85 | ||||
-rw-r--r-- | httpd.c | 17 | ||||
-rw-r--r-- | httpd.h | 6 | ||||
-rw-r--r-- | log.c | 2 | ||||
-rw-r--r-- | parse.y | 89 | ||||
-rw-r--r-- | server.c | 14 |
6 files changed, 186 insertions, 27 deletions
@@ -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); } @@ -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; @@ -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 */ @@ -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++; @@ -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) { @@ -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; |