NO_IPV6 support for git daemon
This commit is contained in:
parent
918e723204
commit
6573faff34
2
Makefile
2
Makefile
@ -239,7 +239,7 @@ ifdef NO_STRCASESTR
|
|||||||
LIB_OBJS += compat/strcasestr.o
|
LIB_OBJS += compat/strcasestr.o
|
||||||
endif
|
endif
|
||||||
ifdef NO_IPV6
|
ifdef NO_IPV6
|
||||||
DEFINES += -DNO_IPV6
|
DEFINES += -DNO_IPV6 -Dsockaddr_storage=sockaddr_in
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef PPC_SHA1
|
ifdef PPC_SHA1
|
||||||
|
@ -397,7 +397,7 @@ static int git_tcp_connect(int fd[2], const char *prog, char *host, char *path)
|
|||||||
|
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&sa, 0, sizeof sa);
|
||||||
sa.sin_family = he->h_addrtype;
|
sa.sin_family = he->h_addrtype;
|
||||||
sa.sin_port = nport;
|
sa.sin_port = htons(nport);
|
||||||
memcpy(&sa.sin_addr, ap, he->h_length);
|
memcpy(&sa.sin_addr, ap, he->h_length);
|
||||||
|
|
||||||
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
|
if (connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
|
||||||
|
89
daemon.c
89
daemon.c
@ -1,9 +1,11 @@
|
|||||||
#include "cache.h"
|
#include "cache.h"
|
||||||
#include "pkt-line.h"
|
#include "pkt-line.h"
|
||||||
|
#include <alloca.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
@ -328,6 +330,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
|
|||||||
inet_ntop(AF_INET, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
|
inet_ntop(AF_INET, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
|
||||||
port = sin_addr->sin_port;
|
port = sin_addr->sin_port;
|
||||||
|
|
||||||
|
#ifndef NO_IPV6
|
||||||
} else if (addr->sa_family == AF_INET6) {
|
} else if (addr->sa_family == AF_INET6) {
|
||||||
struct sockaddr_in6 *sin6_addr = (void *) addr;
|
struct sockaddr_in6 *sin6_addr = (void *) addr;
|
||||||
|
|
||||||
@ -337,6 +340,7 @@ static void handle(int incoming, struct sockaddr *addr, int addrlen)
|
|||||||
strcat(buf, "]");
|
strcat(buf, "]");
|
||||||
|
|
||||||
port = sin6_addr->sin6_port;
|
port = sin6_addr->sin6_port;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
loginfo("Connection from %s:%d", addrbuf, port);
|
loginfo("Connection from %s:%d", addrbuf, port);
|
||||||
|
|
||||||
@ -369,16 +373,17 @@ static void child_handler(int signo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int serve(int port)
|
#ifndef NO_IPV6
|
||||||
|
|
||||||
|
static int socksetup(int port, int **socklist_p)
|
||||||
{
|
{
|
||||||
struct addrinfo hints, *ai0, *ai;
|
|
||||||
int gai;
|
|
||||||
int socknum = 0, *socklist = NULL;
|
int socknum = 0, *socklist = NULL;
|
||||||
int maxfd = -1;
|
int maxfd = -1;
|
||||||
fd_set fds_init, fds;
|
fd_set fds_init, fds;
|
||||||
char pbuf[NI_MAXSERV];
|
char pbuf[NI_MAXSERV];
|
||||||
|
|
||||||
signal(SIGCHLD, child_handler);
|
struct addrinfo hints, *ai0, *ai;
|
||||||
|
int gai;
|
||||||
|
|
||||||
sprintf(pbuf, "%d", port);
|
sprintf(pbuf, "%d", port);
|
||||||
memset(&hints, 0, sizeof(hints));
|
memset(&hints, 0, sizeof(hints));
|
||||||
@ -438,16 +443,59 @@ static int serve(int port)
|
|||||||
|
|
||||||
freeaddrinfo(ai0);
|
freeaddrinfo(ai0);
|
||||||
|
|
||||||
if (socknum == 0)
|
*socklist_p = socklist;
|
||||||
die("unable to allocate any listen sockets on port %u", port);
|
return socknum;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* NO_IPV6 */
|
||||||
|
|
||||||
|
static int socksetup(int port, int **socklist_p)
|
||||||
|
{
|
||||||
|
struct sockaddr_in sin;
|
||||||
|
int sockfd;
|
||||||
|
|
||||||
|
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (sockfd < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
memset(&sin, 0, sizeof sin);
|
||||||
|
sin.sin_family = AF_INET;
|
||||||
|
sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||||
|
sin.sin_port = htons(port);
|
||||||
|
|
||||||
|
if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
|
||||||
|
close(sockfd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
*socklist_p = malloc(sizeof(int));
|
||||||
|
if ( !*socklist_p )
|
||||||
|
die("memory allocation failed: %s", strerror(errno));
|
||||||
|
**socklist_p = sockfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int service_loop(int socknum, int *socklist)
|
||||||
|
{
|
||||||
|
struct pollfd *pfd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pfd = calloc(socknum, sizeof(struct pollfd));
|
||||||
|
if (!pfd)
|
||||||
|
die("memory allocation failed: %s", strerror(errno));
|
||||||
|
|
||||||
|
for (i = 0; i < socknum; i++) {
|
||||||
|
pfd[i].fd = socklist[i];
|
||||||
|
pfd[i].events = POLLIN;
|
||||||
|
}
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int i;
|
int i;
|
||||||
fds = fds_init;
|
|
||||||
|
|
||||||
if (select(maxfd + 1, &fds, NULL, NULL, NULL) < 0) {
|
if (poll(pfd, socknum, 0) < 0) {
|
||||||
if (errno != EINTR) {
|
if (errno != EINTR) {
|
||||||
error("select failed, resuming: %s",
|
error("poll failed, resuming: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
@ -455,12 +503,10 @@ static int serve(int port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < socknum; i++) {
|
for (i = 0; i < socknum; i++) {
|
||||||
int sockfd = socklist[i];
|
if (pfd[i].revents & POLLIN) {
|
||||||
|
|
||||||
if (FD_ISSET(sockfd, &fds)) {
|
|
||||||
struct sockaddr_storage ss;
|
struct sockaddr_storage ss;
|
||||||
int sslen = sizeof(ss);
|
int sslen = sizeof(ss);
|
||||||
int incoming = accept(sockfd, (struct sockaddr *)&ss, &sslen);
|
int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
|
||||||
if (incoming < 0) {
|
if (incoming < 0) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
@ -477,6 +523,19 @@ static int serve(int port)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int serve(int port)
|
||||||
|
{
|
||||||
|
int socknum, *socklist;
|
||||||
|
|
||||||
|
signal(SIGCHLD, child_handler);
|
||||||
|
|
||||||
|
socknum = socksetup(port, &socklist);
|
||||||
|
if (socknum == 0)
|
||||||
|
die("unable to allocate any listen sockets on port %u", port);
|
||||||
|
|
||||||
|
return service_loop(socknum, socklist);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int port = DEFAULT_GIT_PORT;
|
int port = DEFAULT_GIT_PORT;
|
||||||
@ -526,7 +585,7 @@ int main(int argc, char **argv)
|
|||||||
if (inetd_mode) {
|
if (inetd_mode) {
|
||||||
fclose(stderr); //FIXME: workaround
|
fclose(stderr); //FIXME: workaround
|
||||||
return execute();
|
return execute();
|
||||||
|
} else {
|
||||||
|
return serve(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
return serve(port);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user