Commit Diff


commit - eb916dafa2967bc60a8996ea7cc0a23a661ed88e
commit + 360794246d58ac20752da51536158584a51d1478
blob - ebe0bac12e5e093bd83e0efed0048485805ea07d
blob + 39545f5ca4d24bed17282d23968aa2a919a327fc
--- gotwebd/config.c
+++ gotwebd/config.c
@@ -50,6 +50,7 @@ config_init(struct gotwebd *env)
 	env->server_cnt = 0;
 	TAILQ_INIT(&env->servers);
 	TAILQ_INIT(&env->sockets);
+	TAILQ_INIT(&env->addresses);
 
 	return 0;
 }
@@ -88,9 +89,7 @@ config_getserver(struct gotwebd *env, struct imsg *ims
 	memcpy(srv, p, sizeof(*srv));
 
 	/* log server info */
-	log_debug("%s: server=%s fcgi_socket=%s unix_socket=%s", __func__,
-	    srv->name, srv->fcgi_socket ? "yes" : "no", srv->unix_socket ?
-	    "yes" : "no");
+	log_debug("%s: server=%s", __func__, srv->name);
 
 	TAILQ_INSERT_TAIL(&env->servers, srv, entry);
 
@@ -147,8 +146,8 @@ config_getsock(struct gotwebd *env, struct imsg *imsg)
 		sock->pack_fds[i] = -1;
 
 	/* log new socket info */
-	log_debug("%s: name=%s id=%d server=%s af_type=%s socket_path=%s",
-	    __func__, sock->conf.name, sock->conf.id, sock->conf.srv_name,
+	log_debug("%s: id=%d af_type=%s socket_path=%s",
+	    __func__, sock->conf.id,
 	    sock->conf.af_type == AF_UNIX ? "unix" :
 	    (sock->conf.af_type == AF_INET ? "inet" :
 	    (sock->conf.af_type == AF_INET6 ? "inet6" : "unknown")),
blob - 2c4a828f3b8cde396a60854daae3bbc690ecdfd3
blob + b5bdf32e07b935f396dc7b1a3860b7f418eef2cf
--- gotwebd/gotwebd.conf.5
+++ gotwebd/gotwebd.conf.5
@@ -62,9 +62,6 @@ will be used.
 Run the specified number of server processes.
 .Xr gotwebd 8
 runs 3 server processes by default.
-.It Ic unix_socket Ar on | off
-Controls whether the servers will listen on unix sockets by default.
-Listening on unix sockets is the default.
 .It Ic unix_socket_name Ar path
 Set the path to the default unix socket.
 Defaults to
@@ -108,8 +105,6 @@ argument may be number or a service name defined in
 May be specified multiple times to build up a list of listening sockets.
 However, a given combination of address and port may only be used by
 one server.
-.It Ic listen on socket off
-Disable use of unix socket.
 .It Ic listen on socket Ar path
 Set the path to the unix socket used by the server.
 .It Ic logo Ar path
@@ -211,7 +206,6 @@ implicit
 socket.
 .Bd -literal -offset indent
 server "localhost" {
-	listen on socket off
 	listen on 127.0.0.1 port 9000
 	listen on ::1 port 9000
 }
blob - 9adea01286908db58bde811ebffe397078853fe3
blob + 1657f8a62dd05c0eea153e252b2a93ddc1aeb1dc
--- gotwebd/gotwebd.h
+++ gotwebd/gotwebd.h
@@ -308,11 +308,6 @@ struct server {
 	int		 show_repo_description;
 	int		 show_repo_cloneurl;
 	int		 respect_exportok;
-
-	int		 unix_socket;
-	char		 unix_socket_name[PATH_MAX];
-
-	int		 fcgi_socket;
 };
 TAILQ_HEAD(serverlist, server);
 
@@ -324,9 +319,6 @@ enum client_action {
 struct socket_conf {
 	struct address	 addr;
 
-	char		 name[GOTWEBD_MAXTEXT];
-	char		 srv_name[GOTWEBD_MAXTEXT];
-
 	int		 id;
 	int		 af_type;
 	char		 unix_socket_name[PATH_MAX];
@@ -353,6 +345,7 @@ struct passwd;
 struct gotwebd {
 	struct serverlist	servers;
 	struct socketlist	sockets;
+	struct addresslist	addresses;
 
 	const char	*gotwebd_conffile;
 
@@ -372,7 +365,6 @@ struct gotwebd {
 
 	char		 httpd_chroot[PATH_MAX];
 
-	int		 unix_socket;
 	char		 unix_socket_name[PATH_MAX];
 };
 
blob - 84c27c6aef847eb203aee9d73ec6114c3af9eb15
blob + 83ff26c00de4deadcb16dcb4494799c8d0bad002
--- gotwebd/parse.y
+++ gotwebd/parse.y
@@ -26,6 +26,7 @@
 #include <sys/queue.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/un.h>
 
 #include <net/if.h>
 #include <netinet/in.h>
@@ -94,8 +95,8 @@ int				 getservice(const char *);
 int				 n;
 
 int		 get_addrs(const char *, const char *, struct server *);
-int		 addr_dup_check(struct addresslist *, struct address *,
-		    const char *, const char *);
+int		 get_unix_addr(const char *, struct server *);
+int		 addr_dup_check(struct addresslist *, struct address *);
 int		 add_addr(struct server *, struct address *);
 
 typedef struct {
@@ -112,7 +113,7 @@ typedef struct {
 %token	LOGO_URL SHOW_REPO_OWNER SHOW_REPO_AGE SHOW_REPO_DESCRIPTION
 %token	MAX_REPOS_DISPLAY REPOS_PATH MAX_COMMITS_DISPLAY ON ERROR
 %token	SHOW_SITE_OWNER SHOW_REPO_CLONEURL PORT PREFORK RESPECT_EXPORTOK
-%token	UNIX_SOCKET UNIX_SOCKET_NAME SERVER CHROOT CUSTOM_CSS SOCKET
+%token	UNIX_SOCKET_NAME SERVER CHROOT CUSTOM_CSS SOCKET
 %token	SUMMARY_COMMITS_DISPLAY SUMMARY_TAGS_DISPLAY
 
 %token	<v.string>	STRING
@@ -201,9 +202,6 @@ main		: PREFORK NUMBER {
 			}
 			free($2);
 		}
-		| UNIX_SOCKET boolean {
-			gotwebd->unix_socket = $2;
-		}
 		| UNIX_SOCKET_NAME STRING {
 			n = snprintf(gotwebd->unix_socket_name,
 			    sizeof(gotwebd->unix_socket_name), "%s%s",
@@ -328,7 +326,6 @@ serveropts1	: REPOS_PATH STRING {
 			}
 			free($3);
 			free($5);
-			new_srv->fcgi_socket = 1;
 		}
 		| LISTEN ON listen_addr PORT NUMBER {
 			char portno[32];
@@ -345,24 +342,10 @@ serveropts1	: REPOS_PATH STRING {
 				YYERROR;
 			}
 			free($3);
-			new_srv->fcgi_socket = 1;
 		}
 		| LISTEN ON SOCKET STRING {
-			if (strcasecmp($4, "off") == 0) {
-				new_srv->unix_socket = 0;
-				free($4);
-				YYACCEPT;
-			}
-
-			new_srv->unix_socket = 1;
-
-			n = snprintf(new_srv->unix_socket_name,
-			    sizeof(new_srv->unix_socket_name), "%s%s",
-			    gotwebd->httpd_chroot, $4);
-			if (n < 0 ||
-			    (size_t)n >= sizeof(new_srv->unix_socket_name)) {
-				yyerror("%s: unix_socket_name truncated",
-				    __func__);
+			if (get_unix_addr($4, new_srv) == -1) {
+				yyerror("can't listen on %s", $4);
 				free($4);
 				YYERROR;
 			}
@@ -489,7 +472,6 @@ lookup(char *s)
 		{ "socket",			SOCKET },
 		{ "summary_commits_display",	SUMMARY_COMMITS_DISPLAY },
 		{ "summary_tags_display",	SUMMARY_TAGS_DISPLAY },
-		{ "unix_socket",		UNIX_SOCKET },
 		{ "unix_socket_name",		UNIX_SOCKET_NAME },
 	};
 	const struct keywords *p;
@@ -823,12 +805,19 @@ int
 parse_config(const char *filename, struct gotwebd *env)
 {
 	struct sym *sym, *next;
+	struct server *srv;
+	int n;
 
 	if (config_init(env) == -1)
 		fatalx("failed to initialize configuration");
 
 	gotwebd = env;
 
+	n = snprintf(env->unix_socket_name, sizeof(env->unix_socket_name),
+	    "%s%s", D_HTTPD_CHROOT, D_UNIX_SOCKET);
+	if (n < 0 || (size_t)n >= sizeof(env->unix_socket_name))
+		fatalx("%s: snprintf", __func__);
+
 	file = newfile(filename, 0);
 	if (file == NULL) {
 		add_default_server();
@@ -854,13 +843,21 @@ parse_config(const char *filename, struct gotwebd *env
 		}
 	}
 
-	if (errors)
-		return (-1);
-
 	/* just add default server if no config specified */
 	if (gotwebd->server_cnt == 0)
 		add_default_server();
 
+	/* add the implicit listen on socket where missing */
+	TAILQ_FOREACH(srv, &gotwebd->servers, entry) {
+		if (!TAILQ_EMPTY(&srv->al))
+			continue;
+		if (get_unix_addr(env->unix_socket_name, srv) == -1)
+			yyerror("can't listen on %s", env->unix_socket_name);
+	}
+
+	if (errors)
+		return (-1);
+
 	/* setup our listening sockets */
 	sockets_parse_sockets(env);
 
@@ -879,11 +876,6 @@ conf_new_server(const char *name)
 	n = strlcpy(srv->name, name, sizeof(srv->name));
 	if (n >= sizeof(srv->name))
 		fatalx("%s: strlcpy", __func__);
-	n = snprintf(srv->unix_socket_name,
-	    sizeof(srv->unix_socket_name), "%s%s", D_HTTPD_CHROOT,
-	    D_UNIX_SOCKET);
-	if (n < 0 || (size_t)n >= sizeof(srv->unix_socket_name))
-		fatalx("%s: snprintf", __func__);
 	n = strlcpy(srv->repos_path, D_GOTPATH,
 	    sizeof(srv->repos_path));
 	if (n >= sizeof(srv->repos_path))
@@ -923,9 +915,6 @@ conf_new_server(const char *name)
 	srv->summary_commits_display = D_MAXSLCOMMDISP;
 	srv->summary_tags_display = D_MAXSLTAGDISP;
 
-	srv->unix_socket = 1;
-	srv->fcgi_socket = 0;
-
 	TAILQ_INIT(&srv->al);
 	TAILQ_INSERT_TAIL(&gotwebd->servers, srv, entry);
 	gotwebd->server_cnt++;
@@ -1074,13 +1063,34 @@ get_addrs(const char *hostname, const char *servname, 
 }
 
 int
-addr_dup_check(struct addresslist *al, struct address *h, const char *new_srv,
-    const char *other_srv)
+get_unix_addr(const char *path, struct server *new_srv)
 {
+	struct address *h;
+	struct sockaddr_un *sun;
+
+	if ((h = calloc(1, sizeof(*h))) == NULL)
+		fatal("%s: calloc", __func__);
+
+	h->ai_family = AF_UNIX;
+	h->ai_socktype = SOCK_STREAM;
+	h->ai_protocol = PF_UNSPEC;
+	h->slen = sizeof(*sun);
+
+	sun = (struct sockaddr_un *)&h->ss;
+	sun->sun_family = AF_UNIX;
+	if (strlcpy(sun->sun_path, path, sizeof(sun->sun_path)) >=
+	    sizeof(sun->sun_path)) {
+		log_warnx("socket path too long: %s", sun->sun_path);
+		return (-1);
+	}
+
+	return add_addr(new_srv, h);
+}
+
+int
+addr_dup_check(struct addresslist *al, struct address *h)
+{
 	struct address *a;
-	void *ia;
-	char buf[INET6_ADDRSTRLEN];
-	const char *addrstr;
 
 	TAILQ_FOREACH(a, al, entry) {
 		if (a->ai_family != h->ai_family ||
@@ -1089,39 +1099,6 @@ addr_dup_check(struct addresslist *al, struct address 
 		    a->slen != h->slen ||
 		    memcmp(&a->ss, &h->ss, a->slen) != 0)
 			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;
 	}
 
@@ -1132,20 +1109,22 @@ int
 add_addr(struct server *new_srv, struct address *h)
 {
 	struct server *srv;
+	struct address *dup;
 
-	/* 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;
+		if (addr_dup_check(&srv->al, h) == -1) {
+			free(h);
+			return 0;
+		}
 	}
 
-	/* 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);
+	if (addr_dup_check(&gotwebd->addresses, h) == 0) {
+		if ((dup = calloc(1, sizeof(*dup))) == NULL)
+			fatal("%s: calloc", __func__);
+		memcpy(dup, h, sizeof(*dup));
+		TAILQ_INSERT_TAIL(&gotwebd->addresses, dup, entry);
+	}
 
-	return 0;
+	TAILQ_INSERT_TAIL(&new_srv->al, h, entry);
+	return (0);
 }
blob - 156dad3dc6bd9624457ed102668c97c9f301eda3
blob + fd3c5d9c75c9ebd4b6883e0fefaa27c558b4d263
--- gotwebd/sockets.c
+++ gotwebd/sockets.c
@@ -78,10 +78,8 @@ static int	 sockets_create_socket(struct address *);
 static int	 sockets_accept_reserve(int, struct sockaddr *, socklen_t *,
 		    int, volatile int *);
 
-static struct socket *sockets_conf_new_socket_unix(struct gotwebd *,
-		    struct server *, int);
-static struct socket *sockets_conf_new_socket_fcgi(struct gotwebd *,
-		    struct server *, int, struct address *);
+static struct socket *sockets_conf_new_socket(struct gotwebd *,
+		    int, struct address *);
 
 int cgi_inflight = 0;
 
@@ -132,88 +130,25 @@ sockets(struct gotwebd *env, int fd)
 void
 sockets_parse_sockets(struct gotwebd *env)
 {
-	struct server *srv;
 	struct address *a;
 	struct socket *new_sock = NULL;
 	int sock_id = 1;
 
-	TAILQ_FOREACH(srv, &env->servers, entry) {
-		if (srv->unix_socket) {
-			new_sock = sockets_conf_new_socket_unix(env, srv,
-			    sock_id);
-			if (new_sock) {
-				sock_id++;
-				TAILQ_INSERT_TAIL(&env->sockets, new_sock,
-				    entry);
-			}
+	TAILQ_FOREACH(a, &env->addresses, entry) {
+		new_sock = sockets_conf_new_socket(env, sock_id, a);
+		if (new_sock) {
+			sock_id++;
+			TAILQ_INSERT_TAIL(&env->sockets,
+			    new_sock, entry);
 		}
-
-		if (srv->fcgi_socket) {
-			if (TAILQ_EMPTY(&srv->al)) {
-				fatalx("%s: server %s has no IP addresses to "
-				    "listen for FCGI connections", __func__,
-				    srv->name);
-			}
-			TAILQ_FOREACH(a, &srv->al, entry) {
-				if (a->ss.ss_family != AF_INET &&
-				    a->ss.ss_family != AF_INET6)
-					continue;
-				new_sock = sockets_conf_new_socket_fcgi(env,
-				    srv, sock_id, a);
-				if (new_sock) {
-					sock_id++;
-					TAILQ_INSERT_TAIL(&env->sockets,
-					    new_sock, entry);
-				}
-			}
-		}
 	}
 }
 
 static struct socket *
-sockets_conf_new_socket_unix(struct gotwebd *env, struct server *srv, int id)
-{
-	struct socket *sock;
-	int n;
-
-	if ((sock = calloc(1, sizeof(*sock))) == NULL)
-		fatalx("%s: calloc", __func__);
-
-	sock->conf.id = id;
-	sock->fd = -1;
-	sock->conf.af_type = AF_UNIX;
-
-	if (strlcpy(sock->conf.unix_socket_name,
-	    srv->unix_socket_name,
-	    sizeof(sock->conf.unix_socket_name)) >=
-	    sizeof(sock->conf.unix_socket_name)) {
-		free(sock);
-		fatalx("%s: strlcpy", __func__);
-	}
-
-	n = snprintf(sock->conf.name, GOTWEBD_MAXTEXT, "%s_parent",
-	    srv->name);
-	if (n < 0 || (size_t)n >= GOTWEBD_MAXTEXT) {
-		free(sock);
-		fatalx("%s: snprintf", __func__);
-	}
-
-	if (strlcpy(sock->conf.srv_name, srv->name,
-	    sizeof(sock->conf.srv_name)) >= sizeof(sock->conf.srv_name)) {
-		free(sock);
-		fatalx("%s: strlcpy", __func__);
-	}
-
-	return sock;
-}
-
-static struct socket *
-sockets_conf_new_socket_fcgi(struct gotwebd *env, struct server *srv, int id,
-    struct address *a)
+sockets_conf_new_socket(struct gotwebd *env, int id, struct address *a)
 {
 	struct socket *sock;
 	struct address *acp;
-	int n;
 
 	if ((sock = calloc(1, sizeof(*sock))) == NULL)
 		fatalx("%s: calloc", __func__);
@@ -222,20 +157,17 @@ 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 = a->port;
+	if (a->ss.ss_family == AF_UNIX) {
+		struct sockaddr_un *sun;
 
-	n = snprintf(sock->conf.name, GOTWEBD_MAXTEXT, "%s_parent",
-	    srv->name);
-	if (n < 0 || (size_t)n >= GOTWEBD_MAXTEXT) {
-		free(sock);
-		fatalx("%s: snprintf", __func__);
+		sun = (struct sockaddr_un *)&a->ss;
+		if (strlcpy(sock->conf.unix_socket_name, sun->sun_path,
+		    sizeof(sock->conf.unix_socket_name)) >=
+		    sizeof(sock->conf.unix_socket_name))
+			fatalx("unix socket path too long: %s", sun->sun_path);
 	}
 
-	if (strlcpy(sock->conf.srv_name, srv->name,
-	    sizeof(sock->conf.srv_name)) >= sizeof(sock->conf.srv_name)) {
-		free(sock);
-		fatalx("%s: strlcpy", __func__);
-	}
+	sock->conf.fcgi_socket_port = a->port;
 
 	acp = &sock->conf.addr;
 
@@ -438,9 +370,9 @@ sockets_privinit(struct gotwebd *env, struct socket *s
 	}
 
 	if (sock->conf.af_type == AF_INET || sock->conf.af_type == AF_INET6) {
-		log_debug("%s: initializing %s FCGI socket on port %d for %s",
+		log_debug("%s: initializing %s FCGI socket on port %d",
 		    __func__, sock->conf.af_type == AF_INET ? "inet" : "inet6",
-		    sock->conf.fcgi_socket_port, sock->conf.name);
+		    sock->conf.fcgi_socket_port);
 		sock->fd = sockets_create_socket(&sock->conf.addr);
 		if (sock->fd == -1) {
 			log_warnx("%s: create FCGI socket failed", __func__);
@@ -454,33 +386,15 @@ sockets_privinit(struct gotwebd *env, struct socket *s
 static int
 sockets_unix_socket_listen(struct gotwebd *env, struct socket *sock)
 {
-	struct sockaddr_un sun;
-	struct socket *tsock;
 	int u_fd = -1;
 	mode_t old_umask, mode;
 
-	TAILQ_FOREACH(tsock, &env->sockets, entry) {
-		if (strcmp(tsock->conf.unix_socket_name,
-		    sock->conf.unix_socket_name) == 0 &&
-		    tsock->fd != -1)
-			return (tsock->fd);
-	}
-
 	u_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK| SOCK_CLOEXEC, 0);
 	if (u_fd == -1) {
 		log_warn("%s: socket", __func__);
 		return -1;
 	}
 
-	sun.sun_family = AF_UNIX;
-	if (strlcpy(sun.sun_path, sock->conf.unix_socket_name,
-	    sizeof(sun.sun_path)) >= sizeof(sun.sun_path)) {
-		log_warn("%s: %s name too long", __func__,
-		    sock->conf.unix_socket_name);
-		close(u_fd);
-		return -1;
-	}
-
 	if (unlink(sock->conf.unix_socket_name) == -1) {
 		if (errno != ENOENT) {
 			log_warn("%s: unlink %s", __func__,
@@ -493,7 +407,8 @@ sockets_unix_socket_listen(struct gotwebd *env, struct
 	old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
 	mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP;
 
-	if (bind(u_fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
+	if (bind(u_fd, (struct sockaddr *)&sock->conf.addr.ss,
+	    sock->conf.addr.slen) == -1) {
 		log_warn("%s: bind: %s", __func__, sock->conf.unix_socket_name);
 		close(u_fd);
 		(void)umask(old_umask);