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>
This commit is contained in:
parent
cbefd2d632
commit
f9c87be6b4
79
daemon.c
79
daemon.c
@ -516,37 +516,14 @@ static void parse_host_arg(char *extra_args, int buflen)
|
||||
}
|
||||
|
||||
|
||||
static int execute(struct sockaddr *addr)
|
||||
static int execute(void)
|
||||
{
|
||||
static char line[1000];
|
||||
int pktlen, len, i;
|
||||
char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");
|
||||
|
||||
if (addr) {
|
||||
char addrbuf[256] = "";
|
||||
int port = -1;
|
||||
|
||||
if (addr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin_addr = (void *) addr;
|
||||
inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
|
||||
port = ntohs(sin_addr->sin_port);
|
||||
#ifndef NO_IPV6
|
||||
} else if (addr && addr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6_addr = (void *) addr;
|
||||
|
||||
char *buf = addrbuf;
|
||||
*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
|
||||
inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
|
||||
strcat(buf, "]");
|
||||
|
||||
port = ntohs(sin6_addr->sin6_port);
|
||||
#endif
|
||||
}
|
||||
loginfo("Connection from %s:%d", addrbuf, port);
|
||||
setenv("REMOTE_ADDR", addrbuf, 1);
|
||||
}
|
||||
else {
|
||||
unsetenv("REMOTE_ADDR");
|
||||
}
|
||||
if (addr)
|
||||
loginfo("Connection from %s:%s", addr, port);
|
||||
|
||||
alarm(init_timeout ? init_timeout : timeout);
|
||||
pktlen = packet_read_line(0, line, sizeof(line));
|
||||
@ -680,6 +657,8 @@ static char **cld_argv;
|
||||
static void handle(int incoming, struct sockaddr *addr, int addrlen)
|
||||
{
|
||||
struct child_process cld = { 0 };
|
||||
char addrbuf[300] = "REMOTE_ADDR=", portbuf[300];
|
||||
char *env[] = { addrbuf, portbuf, NULL };
|
||||
|
||||
if (max_connections && live_children >= max_connections) {
|
||||
kill_some_child();
|
||||
@ -692,6 +671,28 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
|
||||
}
|
||||
}
|
||||
|
||||
if (addr->sa_family == AF_INET) {
|
||||
struct sockaddr_in *sin_addr = (void *) addr;
|
||||
inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,
|
||||
sizeof(addrbuf) - 12);
|
||||
snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
|
||||
ntohs(sin_addr->sin_port));
|
||||
#ifndef NO_IPV6
|
||||
} else if (addr && addr->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *sin6_addr = (void *) addr;
|
||||
|
||||
char *buf = addrbuf + 12;
|
||||
*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
|
||||
inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,
|
||||
sizeof(addrbuf) - 13);
|
||||
strcat(buf, "]");
|
||||
|
||||
snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
|
||||
ntohs(sin6_addr->sin6_port));
|
||||
#endif
|
||||
}
|
||||
|
||||
cld.env = (const char **)env;
|
||||
cld.argv = (const char **)cld_argv;
|
||||
cld.in = incoming;
|
||||
cld.out = dup(incoming);
|
||||
@ -902,9 +903,15 @@ static int service_loop(struct socketlist *socklist)
|
||||
|
||||
for (i = 0; i < socklist->nr; i++) {
|
||||
if (pfd[i].revents & POLLIN) {
|
||||
struct sockaddr_storage ss;
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in sai;
|
||||
#ifndef NO_IPV6
|
||||
struct sockaddr_in6 sai6;
|
||||
#endif
|
||||
} ss;
|
||||
unsigned int sslen = sizeof(ss);
|
||||
int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
|
||||
int incoming = accept(pfd[i].fd, &ss.sa, &sslen);
|
||||
if (incoming < 0) {
|
||||
switch (errno) {
|
||||
case EAGAIN:
|
||||
@ -915,7 +922,7 @@ static int service_loop(struct socketlist *socklist)
|
||||
die_errno("accept returned");
|
||||
}
|
||||
}
|
||||
handle(incoming, (struct sockaddr *)&ss, sslen);
|
||||
handle(incoming, &ss.sa, sslen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1160,16 +1167,8 @@ int main(int argc, char **argv)
|
||||
die_errno("failed to redirect stderr to /dev/null");
|
||||
}
|
||||
|
||||
if (inetd_mode || serve_mode) {
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr *peer = (struct sockaddr *)&ss;
|
||||
socklen_t slen = sizeof(ss);
|
||||
|
||||
if (getpeername(0, peer, &slen))
|
||||
return execute(NULL);
|
||||
else
|
||||
return execute(peer);
|
||||
}
|
||||
if (inetd_mode || serve_mode)
|
||||
return execute();
|
||||
|
||||
if (detach) {
|
||||
daemonize();
|
||||
|
Loading…
Reference in New Issue
Block a user