From: Tracey Emery Subject: Re: gotwebd.conf multi-listen To: gameoftrees@openbsd.org Date: Mon, 29 Aug 2022 11:47:01 -0600 On Mon, Aug 29, 2022 at 08:34:09AM +0200, Stefan Sperling wrote: > Allow multiple "listen on" statements per server in gotwebd.conf. > > ok? ok > > diff 9dc531b939237dddb6dfb8b7e28cafe6572dae16 df5647108032d971e41b894d003557038209f6fe > commit - 9dc531b939237dddb6dfb8b7e28cafe6572dae16 > commit + df5647108032d971e41b894d003557038209f6fe > blob - 4a98f544d07275e73edfe3df1b42a22bc24af9c0 > blob + 5d7373f2b4dc57c21636901682103257c86d3646 > --- gotwebd/gotwebd.h > +++ gotwebd/gotwebd.h > @@ -278,8 +278,6 @@ struct server { > char unix_socket_name[PATH_MAX]; > > int fcgi_socket; > - char fcgi_socket_bind[GOTWEBD_MAXTEXT]; > - in_port_t fcgi_socket_port; > }; > TAILQ_HEAD(serverlist, server); > > @@ -338,8 +336,6 @@ struct gotwebd { > char unix_socket_name[PATH_MAX]; > > int fcgi_socket; > - char fcgi_socket_bind[GOTWEBD_MAXTEXT]; > - in_port_t fcgi_socket_port; > }; > > struct querystring { > blob - d061ce939fdc0aeb984fb2f8da84a80463c6b189 > blob + e5dbb389e17efbf6b7055d59bb2268ebbc47807c > --- gotwebd/parse.y > +++ gotwebd/parse.y > @@ -93,14 +93,17 @@ static struct server *conf_new_server(const char *); > int getservice(const char *); > int n; > > -int get_addrs(const char *, struct addresslist *, in_port_t); > +int get_addrs(const char *, struct server *, in_port_t); > +int addr_dup_check(struct addresslist *, struct address *, > + const char *, const char *); > +int add_addr(struct server *, struct address *); > struct address *host_v4(const char *); > struct address *host_v6(const char *); > -int host_dns(const char *, struct addresslist *, > +int host_dns(const char *, struct server *, > int, in_port_t, const char *, int); > -int host_if(const char *, struct addresslist *, > +int host_if(const char *, struct server *, > int, in_port_t, const char *, int); > -int host(const char *, struct addresslist *, > +int host(const char *, struct server *, > int, in_port_t, const char *, int); > int is_if_in_group(const char *, const char *); > > @@ -222,14 +225,6 @@ server : SERVER STRING { > } > > new_srv = conf_new_server($2); > - if (new_srv->fcgi_socket) > - if (get_addrs(new_srv->fcgi_socket_bind, > - &new_srv->al, > - new_srv->fcgi_socket_port) == -1) { > - yyerror("could not get tcp iface " > - "addrs"); > - YYERROR; > - } > log_debug("adding server %s", $2); > free($2); > } > @@ -248,14 +243,6 @@ server : SERVER STRING { > log_debug("adding server %s", $2); > free($2); > } '{' optnl serveropts2 '}' { > - if (new_srv->fcgi_socket) { > - if (get_addrs(new_srv->fcgi_socket_bind, > - &new_srv->al, new_srv->fcgi_socket_port) > - == -1) { > - yyerror("could not get tcp iface addr"); > - YYERROR; > - } > - } > } > ; > > @@ -329,16 +316,10 @@ serveropts1 : REPOS_PATH STRING { > free($2); > } > | LISTEN ON STRING fcgiport { > - n = strlcpy(new_srv->fcgi_socket_bind, $3, > - sizeof(new_srv->fcgi_socket_bind)); > - if (n >= sizeof(new_srv->fcgi_socket_bind)) { > - yyerror("%s: fcgi_socket_bind truncated", > - __func__); > - free($3); > + if (get_addrs($3, new_srv, $4) == -1) { > + yyerror("could not get addrs"); > YYERROR; > } > - free($3); > - new_srv->fcgi_socket_port = $4; > } > | MAX_REPOS NUMBER { > if ($2 > 0) > @@ -837,7 +818,6 @@ struct server * > conf_new_server(const char *name) > { > struct server *srv = NULL; > - int val; > > srv = calloc(1, sizeof(*srv)); > if (srv == NULL) > @@ -878,10 +858,6 @@ conf_new_server(const char *name) > if (n >= sizeof(srv->custom_css)) > fatalx("%s: strlcpy", __func__); > > - val = getservice(D_FCGI_PORT); > - srv->fcgi_socket_port = gotwebd->fcgi_socket_port ? > - gotwebd->fcgi_socket_port: val; > - > srv->show_site_owner = D_SHOWSOWNER; > srv->show_repo_owner = D_SHOWROWNER; > srv->show_repo_age = D_SHOWAGE; > @@ -1053,7 +1029,7 @@ host_v6(const char *s) > } > > int > -host_dns(const char *s, struct addresslist *al, int max, > +host_dns(const char *s, struct server *new_srv, int max, > in_port_t port, const char *ifname, int ipproto) > { > struct addrinfo hints, *res0, *res; > @@ -1062,7 +1038,7 @@ host_dns(const char *s, struct addresslist *al, int ma > struct sockaddr_in6 *sin6; > struct address *h; > > - if ((cnt = host_if(s, al, max, port, ifname, ipproto)) != 0) > + if ((cnt = host_if(s, new_srv, max, port, ifname, ipproto)) != 0) > return (cnt); > > memset(&hints, 0, sizeof(hints)); > @@ -1114,7 +1090,8 @@ host_dns(const char *s, struct addresslist *al, int ma > got_sockaddr_inet6_init(sin6, &ra->sin6_addr, 0); > } > > - TAILQ_INSERT_HEAD(al, h, entry); > + if (add_addr(new_srv, h)) > + return -1; > cnt++; > } > if (cnt == max && res) { > @@ -1126,7 +1103,7 @@ host_dns(const char *s, struct addresslist *al, int ma > } > > int > -host_if(const char *s, struct addresslist *al, int max, > +host_if(const char *s, struct server *new_srv, int max, > in_port_t port, const char *ifname, int ipproto) > { > struct ifaddrs *ifap, *p; > @@ -1181,7 +1158,8 @@ host_if(const char *s, struct addresslist *al, int max > ra->sin6_scope_id); > } > > - TAILQ_INSERT_HEAD(al, h, entry); > + if (add_addr(new_srv, h)) > + return -1; > cnt++; > } > if (af == AF_INET) { > @@ -1199,7 +1177,7 @@ host_if(const char *s, struct addresslist *al, int max > } > > int > -host(const char *s, struct addresslist *al, int max, > +host(const char *s, struct server *new_srv, int max, > in_port_t port, const char *ifname, int ipproto) > { > struct address *h; > @@ -1225,11 +1203,12 @@ host(const char *s, struct addresslist *al, int max, > if (ipproto != -1) > h->ipproto = ipproto; > > - TAILQ_INSERT_HEAD(al, h, entry); > + if (add_addr(new_srv, h)) > + return -1; > return (1); > } > > - return (host_dns(s, al, max, port, ifname, ipproto)); > + return (host_dns(s, new_srv, max, port, ifname, ipproto)); > } > > int > @@ -1277,20 +1256,21 @@ end: > } > > int > -get_addrs(const char *addr, struct addresslist *al, in_port_t port) > +get_addrs(const char *addr, struct server *new_srv, in_port_t port) > { > if (strcmp("", addr) == 0) { > - if (host("127.0.0.1", al, 1, port, "127.0.0.1", -1) <= 0) { > + if (host("127.0.0.1", new_srv, 1, port, "127.0.0.1", > + -1) <= 0) { > yyerror("invalid listen ip: %s", > "127.0.0.1"); > return (-1); > } > - if (host("::1", al, 1, port, "::1", -1) <= 0) { > + if (host("::1", new_srv, 1, port, "::1", -1) <= 0) { > yyerror("invalid listen ip: %s", "::1"); > return (-1); > } > } else { > - if (host(addr, al, GOTWEBD_MAXIFACE, port, addr, > + if (host(addr, new_srv, GOTWEBD_MAXIFACE, port, addr, > -1) <= 0) { > yyerror("invalid listen ip: %s", addr); > return (-1); > @@ -1298,3 +1278,77 @@ get_addrs(const char *addr, struct addresslist *al, in > } > return (0); > } > + > +int > +addr_dup_check(struct addresslist *al, struct address *h, const char *new_srv, > + const char *other_srv) > +{ > + struct address *a; > + void *ia; > + char buf[INET6_ADDRSTRLEN]; > + const char *addrstr; > + > + TAILQ_FOREACH(a, al, entry) { > + if (memcmp(&a->ss, &h->ss, sizeof(h->ss)) != 0 || > + a->port != h->port) > + continue; > + > + switch (h->ss.ss_family) { > + case AF_INET: > + ia = &((struct sockaddr_in *)(&h->ss))->sin_addr; > + break; > + case AF_INET6: > + ia = &((struct sockaddr_in6 *)(&h->ss))->sin6_addr; > + break; > + default: > + yyerror("unknown address family: %d", h->ss.ss_family); > + return -1; > + } > + addrstr = inet_ntop(h->ss.ss_family, ia, buf, sizeof(buf)); > + if (addrstr) { > + if (other_srv) { > + yyerror("server %s: duplicate fcgi listen " > + "address %s:%d, already used by server %s", > + new_srv, addrstr, h->port, other_srv); > + } else { > + log_warnx("server: %s: duplicate fcgi listen " > + "address %s:%d", new_srv, addrstr, h->port); > + } > + } else { > + if (other_srv) { > + yyerror("server: %s: duplicate fcgi listen " > + "address, already used by server %s", > + new_srv, other_srv); > + } else { > + log_warnx("server %s: duplicate fcgi listen " > + "address", new_srv); > + } > + } > + > + return -1; > + } > + > + return 0; > +} > + > +int > +add_addr(struct server *new_srv, struct address *h) > +{ > + struct server *srv; > + > + /* Address cannot be shared between different servers. */ > + TAILQ_FOREACH(srv, &gotwebd->servers, entry) { > + if (srv == new_srv) > + continue; > + if (addr_dup_check(&srv->al, h, new_srv->name, srv->name)) > + return -1; > + } > + > + /* Tolerate duplicate address lines within the scope of a server. */ > + if (addr_dup_check(&new_srv->al, h, NULL, NULL) == 0) > + TAILQ_INSERT_TAIL(&new_srv->al, h, entry); > + else > + free(h); > + > + return 0; > +} > blob - 85254db81ad6128ffb6d3c8d8a362e337415a8ab > blob + 7e510af9c4ae6f2609874519758443d006c1afc3 > --- gotwebd/sockets.c > +++ gotwebd/sockets.c > @@ -208,7 +208,7 @@ sockets_conf_new_socket_fcgi(struct gotwebd *env, stru > sock->fd = -1; > sock->conf.af_type = a->ss.ss_family; > > - sock->conf.fcgi_socket_port = srv->fcgi_socket_port; > + sock->conf.fcgi_socket_port = a->port; > > n = snprintf(sock->conf.name, GOTWEBD_MAXTEXT, "%s_parent", > srv->name); > -- Tracey Emery