git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Alexander Sulfrian <alexander@sulfrian.net>
To: gitster@pobox.com, git@vger.kernel.org
Cc: Alexander Sulfrian <alexander@sulfrian.net>
Subject: [PATCH] added possibility to supply more than one --listen argument to git-daemon
Date: Mon, 23 Aug 2010 18:54:35 +0200	[thread overview]
Message-ID: <1282582475-3545-2-git-send-email-alexander@sulfrian.net> (raw)
In-Reply-To: <1282582475-3545-1-git-send-email-alexander@sulfrian.net>

--listen arguments are gathered in a string_list
serve and socksetup get listen_addr as string_list
socketsetup creates a listen socket for each host in that string_list

Signed-off-by: Alexander Sulfrian <alexander@sulfrian.net>
---
 daemon.c |  183 ++++++++++++++++++++++++++++++++++++--------------------------
 1 files changed, 107 insertions(+), 76 deletions(-)

diff --git a/daemon.c b/daemon.c
index e22a2b7..f4492fe 100644
--- a/daemon.c
+++ b/daemon.c
@@ -3,6 +3,7 @@
 #include "exec_cmd.h"
 #include "run-command.h"
 #include "strbuf.h"
+#include "string-list.h"
 
 #include <syslog.h>
 
@@ -736,7 +737,7 @@ static int set_reuse_addr(int sockfd)
 
 #ifndef NO_IPV6
 
-static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
+static int socksetup(struct string_list *listen_addr, int listen_port, int **socklist_p)
 {
 	int socknum = 0, *socklist = NULL;
 	int maxfd = -1;
@@ -744,6 +745,7 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 	struct addrinfo hints, *ai0, *ai;
 	int gai;
 	long flags;
+	int i;
 
 	sprintf(pbuf, "%d", listen_port);
 	memset(&hints, 0, sizeof(hints));
@@ -752,57 +754,69 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 	hints.ai_protocol = IPPROTO_TCP;
 	hints.ai_flags = AI_PASSIVE;
 
-	gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
-	if (gai)
-		die("getaddrinfo() failed: %s", gai_strerror(gai));
+	i = 0;
+	do {
+		if (listen_addr->nr > 0) {
+			gai = getaddrinfo(listen_addr->items[i].string, pbuf,
+					  &hints, &ai0);
+		}
+		else {
+			gai = getaddrinfo(NULL, pbuf, &hints, &ai0);
+		}
 
-	for (ai = ai0; ai; ai = ai->ai_next) {
-		int sockfd;
+		if (gai)
+			die("getaddrinfo() failed: %s", gai_strerror(gai));
 
-		sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-		if (sockfd < 0)
-			continue;
-		if (sockfd >= FD_SETSIZE) {
-			logerror("Socket descriptor too large");
-			close(sockfd);
-			continue;
-		}
+		for (ai = ai0; ai; ai = ai->ai_next) {
+			int sockfd;
+
+			sockfd = socket(ai->ai_family, ai->ai_socktype,
+					ai->ai_protocol);
+			if (sockfd < 0)
+				continue;
+			if (sockfd >= FD_SETSIZE) {
+				logerror("Socket descriptor too large");
+				close(sockfd);
+				continue;
+			}
 
 #ifdef IPV6_V6ONLY
-		if (ai->ai_family == AF_INET6) {
-			int on = 1;
-			setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
-				   &on, sizeof(on));
-			/* Note: error is not fatal */
-		}
+			if (ai->ai_family == AF_INET6) {
+				int on = 1;
+				setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
+					   &on, sizeof(on));
+				/* Note: error is not fatal */
+			}
 #endif
 
-		if (set_reuse_addr(sockfd)) {
-			close(sockfd);
-			continue;
-		}
+			if (set_reuse_addr(sockfd)) {
+				close(sockfd);
+				continue;
+			}
 
-		if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
-			close(sockfd);
-			continue;	/* not fatal */
-		}
-		if (listen(sockfd, 5) < 0) {
-			close(sockfd);
-			continue;	/* not fatal */
-		}
+			if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
+				close(sockfd);
+				continue;	/* not fatal */
+			}
+			if (listen(sockfd, 5) < 0) {
+				close(sockfd);
+				continue;	/* not fatal */
+			}
 
-		flags = fcntl(sockfd, F_GETFD, 0);
-		if (flags >= 0)
-			fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
+			flags = fcntl(sockfd, F_GETFD, 0);
+			if (flags >= 0)
+				fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 
-		socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
-		socklist[socknum++] = sockfd;
+			socklist = xrealloc(socklist,
+					    sizeof(int) * (socknum + 1));
+			socklist[socknum++] = sockfd;
 
-		if (maxfd < sockfd)
-			maxfd = sockfd;
-	}
+			if (maxfd < sockfd)
+				maxfd = sockfd;
+		}
 
-	freeaddrinfo(ai0);
+		freeaddrinfo(ai0);
+	} while  (++i < listen_addr->nr);
 
 	*socklist_p = socklist;
 	return socknum;
@@ -810,50 +824,60 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 
 #else /* NO_IPV6 */
 
-static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
+static int socksetup(struct string_list *listen_addr, int listen_port, int **socklist_p)
 {
+	int socknum = 0, *socklist = NULL;
 	struct sockaddr_in sin;
 	int sockfd;
 	long flags;
+	int i;
 
 	memset(&sin, 0, sizeof sin);
 	sin.sin_family = AF_INET;
 	sin.sin_port = htons(listen_port);
 
-	if (listen_addr) {
-		/* Well, host better be an IP address here. */
-		if (inet_pton(AF_INET, listen_addr, &sin.sin_addr.s_addr) <= 0)
+	i = 0;
+	do {
+		if (listen_addr->nr > 0) {
+			/* Well, host better be an IP address here. */
+			if (inet_pton(AF_INET, listen_addr->items[i].string,
+				      &sin.sin_addr.s_addr) <= 0)
+				return 0;
+		}
+		else {
+			sin.sin_addr.s_addr = htonl(INADDR_ANY);
+		}
+
+		sockfd = socket(AF_INET, SOCK_STREAM, 0);
+		if (sockfd < 0)
 			return 0;
-	} else {
-		sin.sin_addr.s_addr = htonl(INADDR_ANY);
-	}
 
-	sockfd = socket(AF_INET, SOCK_STREAM, 0);
-	if (sockfd < 0)
-		return 0;
+		if (set_reuse_addr(sockfd)) {
+			close(sockfd);
+			return 0;
+		}
 
-	if (set_reuse_addr(sockfd)) {
-		close(sockfd);
-		return 0;
-	}
+		if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
+			close(sockfd);
+			return 0;
+		}
 
-	if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
-		close(sockfd);
-		return 0;
-	}
+		if (listen(sockfd, 5) < 0) {
+			close(sockfd);
+			return 0;
+		}
 
-	if (listen(sockfd, 5) < 0) {
-		close(sockfd);
-		return 0;
-	}
+		flags = fcntl(sockfd, F_GETFD, 0);
+		if (flags >= 0)
+			fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 
-	flags = fcntl(sockfd, F_GETFD, 0);
-	if (flags >= 0)
-		fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
+		socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
+		socklist[socknum++] = sockfd;
 
-	*socklist_p = xmalloc(sizeof(int));
-	**socklist_p = sockfd;
-	return 1;
+	} while (++i < listen_addr->nr);
+
+	*socklist_p = socklist;
+	return socknum;
 }
 
 #endif
@@ -946,14 +970,14 @@ static void store_pid(const char *path)
 		die_errno("failed to write pid file '%s'", path);
 }
 
-static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
+static int serve(struct string_list *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
 {
 	int socknum, *socklist;
 
 	socknum = socksetup(listen_addr, listen_port, &socklist);
 	if (socknum == 0)
-		die("unable to allocate any listen sockets on host %s port %u",
-		    listen_addr, listen_port);
+		die("unable to allocate any listen sockets on port %u",
+		    listen_port);
 
 	if (pass && gid &&
 	    (initgroups(pass->pw_name, gid) || setgid (gid) ||
@@ -966,14 +990,17 @@ static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t
 int main(int argc, char **argv)
 {
 	int listen_port = 0;
-	char *listen_addr = NULL;
 	int inetd_mode = 0;
+	struct string_list listen_addr;
 	const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
 	int detach = 0;
 	struct passwd *pass = NULL;
 	struct group *group;
 	gid_t gid = 0;
 	int i;
+	int return_value;
+
+	memset(&listen_addr, 0, sizeof(struct string_list));
 
 	git_extract_argv0_path(argv[0]);
 
@@ -981,7 +1008,7 @@ int main(int argc, char **argv)
 		char *arg = argv[i];
 
 		if (!prefixcmp(arg, "--listen=")) {
-			listen_addr = xstrdup_tolower(arg + 9);
+			string_list_append(&listen_addr, xstrdup_tolower(arg + 9));
 			continue;
 		}
 		if (!prefixcmp(arg, "--port=")) {
@@ -1106,7 +1133,7 @@ int main(int argc, char **argv)
 	if (inetd_mode && (group_name || user_name))
 		die("--user and --group are incompatible with --inetd");
 
-	if (inetd_mode && (listen_port || listen_addr))
+	if (inetd_mode && (listen_port || (listen_addr.nr > 0)))
 		die("--listen= and --port= are incompatible with --inetd");
 	else if (listen_port == 0)
 		listen_port = DEFAULT_GIT_PORT;
@@ -1161,5 +1188,9 @@ int main(int argc, char **argv)
 	if (pid_file)
 		store_pid(pid_file);
 
-	return serve(listen_addr, listen_port, pass, gid);
+	return_value = serve(&listen_addr, listen_port, pass, gid);
+
+	string_list_clear(&listen_addr, 0);
+
+	return return_value;
 }
-- 
1.7.1

  reply	other threads:[~2010-08-23 16:55 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-23 16:54 added possibility to supply more than one --listen argument to git-daemon Alexander Sulfrian
2010-08-23 16:54 ` Alexander Sulfrian [this message]
2010-08-23 19:56   ` [PATCH] " Junio C Hamano
2010-08-29 15:07     ` daemon: allow more than one host addresses given via --listen Alexander Sulfrian
2010-08-29 15:13       ` Alexander Sulfrian
2010-08-29 15:13       ` [PATCHv3 1/2] daemon: add helper function named_sock_setup Alexander Sulfrian
2010-08-29 15:13       ` [PATCHv3 2/2] daemon: allow more than one host address given via --listen Alexander Sulfrian
2010-08-30  7:28         ` Junio C Hamano
2010-08-30 11:30           ` Alexander Sulfrian
2010-08-30 11:30           ` [PATCHv4 1/2] daemon: add helper function named_sock_setup Alexander Sulfrian
2010-08-30 12:12             ` Erik Faye-Lund
2010-08-30 12:46               ` AlexanderS
2010-08-30 12:58                 ` Erik Faye-Lund
2010-08-30 11:30           ` [PATCHv4 2/2] daemon: allow more than one host address given via --listen Alexander Sulfrian
2010-08-29 15:07     ` [PATCHv2 1/2] daemon: add helper function named_sock_setup Alexander Sulfrian
2010-08-29 15:07     ` [PATCHv2 2/2] daemon: allow more than one host address given via --listen Alexander Sulfrian
2010-08-29 15:11       ` Erik Faye-Lund
2010-08-29 15:17         ` AlexanderS

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1282582475-3545-2-git-send-email-alexander@sulfrian.net \
    --to=alexander@sulfrian.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).