@matheusbsbs / matheus-bagliano / commits / f9c87be6b4
Fork 0

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();