daemon: get remote host address from root-process
Get remote host in the process that accept() and pass it through the REMOTE_ADDR environment variable to the handler-process. Introduce the REMOTE_PORT environmen variable for the port. Use these variables for reporting instead of doing getpeername(0, ...), which doesn't work on Windows. Signed-off-by: Erik Faye-Lund <kusmabite@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Erik Faye-Lund committed
Nov 4, 2010 at 02:35 UTC
f9c87be6b42dd0f8b31a4bb8c6a44326879fdd1a
1 file changed
+39
-40
daemon.c
+39
-40
@@ -516,37 +516,14 @@ static void parse_host_arg(char *extra_args, int buflen)
516
}
517
518
519
-static int execute(struct sockaddr *addr)
519
+static int execute(void)
520
{
521
static char line[1000];
522
int pktlen, len, i;
523
+ char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");
524
524
- if (addr) {
525
- char addrbuf[256] = "";
526
- int port = -1;
527
-
528
- if (addr->sa_family == AF_INET) {
529
- struct sockaddr_in *sin_addr = (void *) addr;
530
- inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
531
- port = ntohs(sin_addr->sin_port);
532
-#ifndef NO_IPV6
533
- } else if (addr && addr->sa_family == AF_INET6) {
534
- struct sockaddr_in6 *sin6_addr = (void *) addr;
535
-
536
- char *buf = addrbuf;
537
- *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
538
- inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
539
- strcat(buf, "]");
540
-
541
- port = ntohs(sin6_addr->sin6_port);
542
-#endif
543
- }
544
- loginfo("Connection from %s:%d", addrbuf, port);
545
- setenv("REMOTE_ADDR", addrbuf, 1);
546
- }
547
- else {
548
- unsetenv("REMOTE_ADDR");
549
- }
525
+ if (addr)
526
+ loginfo("Connection from %s:%s", addr, port);
527
528
alarm(init_timeout ? init_timeout : timeout);
529
pktlen = packet_read_line(0, line, sizeof(line));
@@ -680,6 +657,8 @@ static char **cld_argv;
657
static void handle(int incoming, struct sockaddr *addr, int addrlen)
658
{
659
struct child_process cld = { 0 };
660
+ char addrbuf[300] = "REMOTE_ADDR=", portbuf[300];
661
+ char *env[] = { addrbuf, portbuf, NULL };
662
663
if (max_connections && live_children >= max_connections) {
664
kill_some_child();
@@ -692,6 +671,28 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
671
}
672
}
673
674
+ if (addr->sa_family == AF_INET) {
675
+ struct sockaddr_in *sin_addr = (void *) addr;
676
+ inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,
677
+ sizeof(addrbuf) - 12);
678
+ snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
679
+ ntohs(sin_addr->sin_port));
680
+#ifndef NO_IPV6
681
+ } else if (addr && addr->sa_family == AF_INET6) {
682
+ struct sockaddr_in6 *sin6_addr = (void *) addr;
683
+
684
+ char *buf = addrbuf + 12;
685
+ *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
686
+ inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,
687
+ sizeof(addrbuf) - 13);
688
+ strcat(buf, "]");
689
+
690
+ snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
691
+ ntohs(sin6_addr->sin6_port));
692
+#endif
693
+ }
694
+
695
+ cld.env = (const char **)env;
696
cld.argv = (const char **)cld_argv;
697
cld.in = incoming;
698
cld.out = dup(incoming);
@@ -902,9 +903,15 @@ static int service_loop(struct socketlist *socklist)
903
904
for (i = 0; i < socklist->nr; i++) {
905
if (pfd[i].revents & POLLIN) {
905
- struct sockaddr_storage ss;
906
+ union {
907
+ struct sockaddr sa;
908
+ struct sockaddr_in sai;
909
+#ifndef NO_IPV6
910
+ struct sockaddr_in6 sai6;
911
+#endif
912
+ } ss;
913
unsigned int sslen = sizeof(ss);
907
- int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
914
+ int incoming = accept(pfd[i].fd, &ss.sa, &sslen);
915
if (incoming < 0) {
916
switch (errno) {
917
case EAGAIN:
@@ -915,7 +922,7 @@ static int service_loop(struct socketlist *socklist)
922
die_errno("accept returned");
923
}
924
}
918
- handle(incoming, (struct sockaddr *)&ss, sslen);
925
+ handle(incoming, &ss.sa, sslen);
926
}
927
}
928
}
@@ -1160,16 +1167,8 @@ int main(int argc, char **argv)
1167
die_errno("failed to redirect stderr to /dev/null");
1168
}
1169
1163
- if (inetd_mode || serve_mode) {
1164
- struct sockaddr_storage ss;
1165
- struct sockaddr *peer = (struct sockaddr *)&ss;
1166
- socklen_t slen = sizeof(ss);
1167
-
1168
- if (getpeername(0, peer, &slen))
1169
- return execute(NULL);
1170
- else
1171
- return execute(peer);
1172
- }
1170
+ if (inetd_mode || serve_mode)
1171
+ return execute();
1172
1173
if (detach) {
1174
daemonize();