"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Tracey Emery <tracey@traceyemery.net>
Subject:
Re: gotwebd.conf multi-listen
To:
gameoftrees@openbsd.org
Date:
Mon, 29 Aug 2022 11:47:01 -0600

Download raw body.

Thread
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