From 9b178ba84defc24e32168f903ee47f99a355f004 Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Sun, 29 Aug 2010 17:13:15 +0200 Subject: [PATCH 1/2] daemon: add helper function setup_named_sock() Add setup_named_sock() as helper function for socksetup to make it easier to create more than one listen sockets. named_sock_setup can be called more than one time and add the new sockets to the supplied socklist_p. Signed-off-by: Alexander Sulfrian Signed-off-by: Junio C Hamano --- daemon.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/daemon.c b/daemon.c index e22a2b7fa5..deda4cf0a2 100644 --- a/daemon.c +++ b/daemon.c @@ -736,9 +736,9 @@ static int set_reuse_addr(int sockfd) #ifndef NO_IPV6 -static int socksetup(char *listen_addr, int listen_port, int **socklist_p) +static int setup_named_sock(char *listen_addr, int listen_port, int **socklist_p, int socknum) { - int socknum = 0, *socklist = NULL; + int *socklist = *socklist_p; int maxfd = -1; char pbuf[NI_MAXSERV]; struct addrinfo hints, *ai0, *ai; @@ -810,8 +810,9 @@ 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 setup_named_sock(char *listen_addr, int listen_port, int **socklist_p, int socknum) { + int *socklist = *socklist_p; struct sockaddr_in sin; int sockfd; long flags; @@ -823,41 +824,53 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p) if (listen_addr) { /* Well, host better be an IP address here. */ if (inet_pton(AF_INET, listen_addr, &sin.sin_addr.s_addr) <= 0) - return 0; + return socknum; } else { sin.sin_addr.s_addr = htonl(INADDR_ANY); } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) - return 0; + return socknum; if (set_reuse_addr(sockfd)) { close(sockfd); - return 0; + return socknum; } if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) { close(sockfd); - return 0; + return socknum; } if (listen(sockfd, 5) < 0) { close(sockfd); - return 0; + return socknum; } flags = fcntl(sockfd, F_GETFD, 0); if (flags >= 0) fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC); - *socklist_p = xmalloc(sizeof(int)); - **socklist_p = sockfd; - return 1; + socklist = xrealloc(socklist, sizeof(int) * (socknum + 1)); + socklist[socknum++] = sockfd; + + *socklist_p = socklist; + return socknum; } #endif +static int socksetup(char *listen_addr, int listen_port, int **socklist_p) +{ + int socknum = 0, *socklist = NULL; + + socknum = setup_named_sock(listen_addr, listen_port, &socklist, socknum); + + *socklist_p = socklist; + return socknum; +} + static int service_loop(int socknum, int *socklist) { struct pollfd *pfd; From 1656b65a8b2aea2a072853b9e835ef98c1a6942d Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Sun, 29 Aug 2010 17:13:16 +0200 Subject: [PATCH 2/2] daemon: allow more than one host address given via --listen When the host has more than one interfaces, daemon can listen to all of them by not giving any --listen option, or listen to only one. Teach it to accept more than one --listen options. Remove the hostname information form the die, if no socket could be created. It would only trigger when no interface out of either all interface or the ones specified on the command line with --listen options, can be listened to and so the user does know which "host" was asked. Signed-off-by: Alexander Sulfrian Signed-off-by: Junio C Hamano --- Documentation/git-daemon.txt | 1 + daemon.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index 01c9f8eb9e..685aa58cec 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -85,6 +85,7 @@ OPTIONS be either an IPv4 address or an IPv6 address if supported. If IPv6 is not supported, then --listen=hostname is also not supported and --listen must be given an IPv4 address. + Can be given more than once. Incompatible with '--inetd' option. --port=n:: diff --git a/daemon.c b/daemon.c index deda4cf0a2..bd7574e8dc 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 @@ -861,11 +862,20 @@ static int setup_named_sock(char *listen_addr, int listen_port, int **socklist_p #endif -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; - socknum = setup_named_sock(listen_addr, listen_port, &socklist, socknum); + if (!listen_addr->nr) + socknum = setup_named_sock(NULL, listen_port, &socklist, + socknum); + else { + int i; + for (i = 0; i < listen_addr->nr; i++) + socknum = setup_named_sock(listen_addr->items[i].string, + listen_port, &socklist, + socknum); + } *socklist_p = socklist; return socknum; @@ -959,14 +969,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) || @@ -979,7 +989,7 @@ 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; + struct string_list listen_addr = STRING_LIST_INIT_NODUP; int inetd_mode = 0; const char *pid_file = NULL, *user_name = NULL, *group_name = NULL; int detach = 0; @@ -987,6 +997,7 @@ int main(int argc, char **argv) struct group *group; gid_t gid = 0; int i; + int return_value; git_extract_argv0_path(argv[0]); @@ -994,7 +1005,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=")) { @@ -1119,7 +1130,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; @@ -1174,5 +1185,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; }