Skip to content

Commit e6202df

Browse files
committed
Merge branch 'as/daemon-multi-listen'
* as/daemon-multi-listen: daemon: allow more than one host address given via --listen daemon: add helper function named_sock_setup
2 parents 0141215 + 3a3a29c commit e6202df

File tree

2 files changed

+54
-27
lines changed

2 files changed

+54
-27
lines changed

Documentation/git-daemon.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ OPTIONS
8585
be either an IPv4 address or an IPv6 address if supported. If IPv6
8686
is not supported, then --listen=hostname is also not supported and
8787
--listen must be given an IPv4 address.
88+
Can be given more than once.
8889
Incompatible with '--inetd' option.
8990

9091
--port=<n>::

daemon.c

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "exec_cmd.h"
44
#include "run-command.h"
55
#include "strbuf.h"
6+
#include "string-list.h"
67

78
#include <syslog.h>
89

@@ -734,11 +735,17 @@ static int set_reuse_addr(int sockfd)
734735
&on, sizeof(on));
735736
}
736737

738+
struct socketlist {
739+
int *list;
740+
size_t nr;
741+
size_t alloc;
742+
};
743+
737744
#ifndef NO_IPV6
738745

739-
static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
746+
static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist)
740747
{
741-
int socknum = 0, *socklist = NULL;
748+
int socknum = 0;
742749
int maxfd = -1;
743750
char pbuf[NI_MAXSERV];
744751
struct addrinfo hints, *ai0, *ai;
@@ -753,8 +760,10 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
753760
hints.ai_flags = AI_PASSIVE;
754761

755762
gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
756-
if (gai)
757-
die("getaddrinfo() failed: %s", gai_strerror(gai));
763+
if (gai) {
764+
logerror("getaddrinfo() for %s failed: %s", listen_addr, gai_strerror(gai));
765+
return 0;
766+
}
758767

759768
for (ai = ai0; ai; ai = ai->ai_next) {
760769
int sockfd;
@@ -795,22 +804,22 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
795804
if (flags >= 0)
796805
fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
797806

798-
socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
799-
socklist[socknum++] = sockfd;
807+
ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc);
808+
socklist->list[socklist->nr++] = sockfd;
809+
socknum++;
800810

801811
if (maxfd < sockfd)
802812
maxfd = sockfd;
803813
}
804814

805815
freeaddrinfo(ai0);
806816

807-
*socklist_p = socklist;
808817
return socknum;
809818
}
810819

811820
#else /* NO_IPV6 */
812821

813-
static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
822+
static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist)
814823
{
815824
struct sockaddr_in sin;
816825
int sockfd;
@@ -851,22 +860,39 @@ static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
851860
if (flags >= 0)
852861
fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
853862

854-
*socklist_p = xmalloc(sizeof(int));
855-
**socklist_p = sockfd;
863+
ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc);
864+
socklist->list[socklist->nr++] = sockfd;
856865
return 1;
857866
}
858867

859868
#endif
860869

861-
static int service_loop(int socknum, int *socklist)
870+
static void socksetup(struct string_list *listen_addr, int listen_port, struct socketlist *socklist)
871+
{
872+
if (!listen_addr->nr)
873+
setup_named_sock(NULL, listen_port, socklist);
874+
else {
875+
int i, socknum;
876+
for (i = 0; i < listen_addr->nr; i++) {
877+
socknum = setup_named_sock(listen_addr->items[i].string,
878+
listen_port, socklist);
879+
880+
if (socknum == 0)
881+
logerror("unable to allocate any listen sockets for host %s on port %u",
882+
listen_addr->items[i].string, listen_port);
883+
}
884+
}
885+
}
886+
887+
static int service_loop(struct socketlist *socklist)
862888
{
863889
struct pollfd *pfd;
864890
int i;
865891

866-
pfd = xcalloc(socknum, sizeof(struct pollfd));
892+
pfd = xcalloc(socklist->nr, sizeof(struct pollfd));
867893

868-
for (i = 0; i < socknum; i++) {
869-
pfd[i].fd = socklist[i];
894+
for (i = 0; i < socklist->nr; i++) {
895+
pfd[i].fd = socklist->list[i];
870896
pfd[i].events = POLLIN;
871897
}
872898

@@ -877,7 +903,7 @@ static int service_loop(int socknum, int *socklist)
877903

878904
check_dead_children();
879905

880-
if (poll(pfd, socknum, -1) < 0) {
906+
if (poll(pfd, socklist->nr, -1) < 0) {
881907
if (errno != EINTR) {
882908
logerror("Poll failed, resuming: %s",
883909
strerror(errno));
@@ -886,7 +912,7 @@ static int service_loop(int socknum, int *socklist)
886912
continue;
887913
}
888914

889-
for (i = 0; i < socknum; i++) {
915+
for (i = 0; i < socklist->nr; i++) {
890916
if (pfd[i].revents & POLLIN) {
891917
struct sockaddr_storage ss;
892918
unsigned int sslen = sizeof(ss);
@@ -946,27 +972,27 @@ static void store_pid(const char *path)
946972
die_errno("failed to write pid file '%s'", path);
947973
}
948974

949-
static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
975+
static int serve(struct string_list *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
950976
{
951-
int socknum, *socklist;
977+
struct socketlist socklist = { NULL, 0, 0 };
952978

953-
socknum = socksetup(listen_addr, listen_port, &socklist);
954-
if (socknum == 0)
955-
die("unable to allocate any listen sockets on host %s port %u",
956-
listen_addr, listen_port);
979+
socksetup(listen_addr, listen_port, &socklist);
980+
if (socklist.nr == 0)
981+
die("unable to allocate any listen sockets on port %u",
982+
listen_port);
957983

958984
if (pass && gid &&
959985
(initgroups(pass->pw_name, gid) || setgid (gid) ||
960986
setuid(pass->pw_uid)))
961987
die("cannot drop privileges");
962988

963-
return service_loop(socknum, socklist);
989+
return service_loop(&socklist);
964990
}
965991

966992
int main(int argc, char **argv)
967993
{
968994
int listen_port = 0;
969-
char *listen_addr = NULL;
995+
struct string_list listen_addr = STRING_LIST_INIT_NODUP;
970996
int inetd_mode = 0;
971997
const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
972998
int detach = 0;
@@ -981,7 +1007,7 @@ int main(int argc, char **argv)
9811007
char *arg = argv[i];
9821008

9831009
if (!prefixcmp(arg, "--listen=")) {
984-
listen_addr = xstrdup_tolower(arg + 9);
1010+
string_list_append(&listen_addr, xstrdup_tolower(arg + 9));
9851011
continue;
9861012
}
9871013
if (!prefixcmp(arg, "--port=")) {
@@ -1106,7 +1132,7 @@ int main(int argc, char **argv)
11061132
if (inetd_mode && (group_name || user_name))
11071133
die("--user and --group are incompatible with --inetd");
11081134

1109-
if (inetd_mode && (listen_port || listen_addr))
1135+
if (inetd_mode && (listen_port || (listen_addr.nr > 0)))
11101136
die("--listen= and --port= are incompatible with --inetd");
11111137
else if (listen_port == 0)
11121138
listen_port = DEFAULT_GIT_PORT;
@@ -1161,5 +1187,5 @@ int main(int argc, char **argv)
11611187
if (pid_file)
11621188
store_pid(pid_file);
11631189

1164-
return serve(listen_addr, listen_port, pass, gid);
1190+
return serve(&listen_addr, listen_port, pass, gid);
11651191
}

0 commit comments

Comments
 (0)