From: des Date: Wed, 9 Aug 2006 09:36:29 +0000 (+0000) Subject: Rewrite open_tcp(): use only one listening socket. Try for a combined X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4de15b4bca3d768531702848df5916aa4cb5f34;p=varnish Rewrite open_tcp(): use only one listening socket. Try for a combined IPv6 / IPv4 socket; if IPv6 is not available, fall back to an IPv4 socket. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@776 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- diff --git a/varnish-cache/bin/varnishd/cache_acceptor.c b/varnish-cache/bin/varnishd/cache_acceptor.c index b7351945..b09627d3 100644 --- a/varnish-cache/bin/varnishd/cache_acceptor.c +++ b/varnish-cache/bin/varnishd/cache_acceptor.c @@ -194,12 +194,8 @@ vca_main(void *arg) AZ(pipe(pipes)); vca_poll(pipes[0]); - for (u = 0; u < HERITAGE_NSOCKS; u++) { - if (heritage.sock_local[u] >= 0) - vca_poll(heritage.sock_local[u]); - if (heritage.sock_remote[u] >= 0) - vca_poll(heritage.sock_remote[u]); - } + if (heritage.socket >= 0) + vca_poll(heritage.socket); while (1) { v = poll(pollfd, npoll, 5000); @@ -213,17 +209,10 @@ vca_main(void *arg) else vca_rcvhdev(sp); } - for (u = 0; v && u < HERITAGE_NSOCKS; u++) { - if (heritage.sock_local[u] >= 0 && - pollfd[heritage.sock_local[u]].revents) { - accept_f(heritage.sock_local[u]); - v--; - } - if (heritage.sock_remote[u] >= 0 && - pollfd[heritage.sock_remote[u]].revents) { - accept_f(heritage.sock_remote[u]); - v--; - } + if (heritage.socket >= 0 && + pollfd[heritage.socket].revents) { + accept_f(heritage.socket); + v--; } clock_gettime(CLOCK_MONOTONIC, &t); TAILQ_FOREACH_SAFE(sp, &sesshead, list, sp2) { @@ -322,19 +311,11 @@ vca_main(void *arg) assert(kq >= 0); - for (u = 0; u < HERITAGE_NSOCKS; u++) { - if (heritage.sock_local[u] >= 0) { - memset(&ke, 0, sizeof ke); - EV_SET(&ke, heritage.sock_local[u], - EVFILT_READ, EV_ADD, 0, 0, accept_f); - AZ(kevent(kq, &ke, 1, NULL, 0, NULL)); - } - if (heritage.sock_remote[u] >= 0) { - memset(&ke, 0, sizeof ke); - EV_SET(&ke, heritage.sock_remote[u], - EVFILT_READ, EV_ADD, 0, 0, accept_f); - AZ(kevent(kq, &ke, 1, NULL, 0, NULL)); - } + if (heritage.socket >= 0) { + memset(&ke, 0, sizeof ke); + EV_SET(&ke, heritage.socket, + EVFILT_READ, EV_ADD, 0, 0, accept_f); + AZ(kevent(kq, &ke, 1, NULL, 0, NULL)); } while (1) { diff --git a/varnish-cache/bin/varnishd/heritage.h b/varnish-cache/bin/varnishd/heritage.h index 995f177b..0fa64dc3 100644 --- a/varnish-cache/bin/varnishd/heritage.h +++ b/varnish-cache/bin/varnishd/heritage.h @@ -12,14 +12,8 @@ struct heritage { */ int fds[4]; - /* - * Two sockets from which to accept connections, one bound to - * loopback only and one bound for wildcard (or possibly a specific - * interface IP number). - */ -#define HERITAGE_NSOCKS 2 /* IPv4 + IPv6 */ - int sock_local[HERITAGE_NSOCKS]; - int sock_remote[HERITAGE_NSOCKS]; + /* Socket from which to accept connections */ + int socket; /* Share memory log fd and size (incl header) */ int vsl_fd; diff --git a/varnish-cache/bin/varnishd/tcp.c b/varnish-cache/bin/varnishd/tcp.c index 61a65272..39fa4955 100644 --- a/varnish-cache/bin/varnishd/tcp.c +++ b/varnish-cache/bin/varnishd/tcp.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "compat/strlcpy.h" #include "heritage.h" @@ -64,74 +65,66 @@ accept_filter(int fd) } #endif -static void -create_listen_socket(const char *addr, const char *port, int *sp, int nsp) -{ - struct addrinfo ai, *r0, *r1; - int i, j, s; - - memset(&ai, 0, sizeof ai); - ai.ai_family = PF_UNSPEC; - ai.ai_socktype = SOCK_STREAM; - ai.ai_flags = AI_PASSIVE; - i = getaddrinfo(addr, port, &ai, &r0); - - if (i) { - fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(i)); - return; - } - - for (r1 = r0; r1 != NULL && nsp > 0; r1 = r1->ai_next) { - s = socket(r1->ai_family, r1->ai_socktype, r1->ai_protocol); - if (s < 0) - continue; - j = 1; - i = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &j, sizeof j); - assert(i == 0); - - i = bind(s, r1->ai_addr, r1->ai_addrlen); - if (i != 0) { - perror("bind"); - continue; - } - assert(i == 0); - *sp = s; - sp++; - nsp--; - } - - freeaddrinfo(r0); -} - int open_tcp(const char *port) { - unsigned u; - - for (u = 0; u < HERITAGE_NSOCKS; u++) { - heritage.sock_local[u] = -1; - heritage.sock_remote[u] = -1; + struct addrinfo hints, *res; + int ret, sd, val; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_INET6; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; + if ((ret = getaddrinfo(NULL, port, &hints, &res)) != 0) { + fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret)); + return (-1); } - create_listen_socket("localhost", port, - &heritage.sock_local[0], HERITAGE_NSOCKS); - - create_listen_socket(NULL, port, - &heritage.sock_remote[0], HERITAGE_NSOCKS); - - for (u = 0; u < HERITAGE_NSOCKS; u++) { - if (heritage.sock_local[u] >= 0) { - AZ(listen(heritage.sock_local[u], 16)); -#ifdef HAVE_ACCEPT_FILTERS - accept_filter(heritage.sock_local[u]); -#endif + sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sd < 0 && errno == EPROTONOSUPPORT) { + freeaddrinfo(res); + hints.ai_family = AF_INET; + if ((ret = getaddrinfo(NULL, port, &hints, &res)) != 0) { + fprintf(stderr, "getaddrinfo failed: %s\n", gai_strerror(ret)); + return (-1); } - if (heritage.sock_remote[u] >= 0) { - AZ(listen(heritage.sock_remote[u], 16)); + sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + } + if (sd < 0) { + perror("socket()"); + freeaddrinfo(res); + return (-1); + } + val = 1; + if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof val) != 0) { + perror("setsockopt(SO_REUSEADDR, 1)"); + freeaddrinfo(res); + close(sd); + return (-1); + } + val = 0; + if (res->ai_family == AF_INET6 && + setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof val) != 0) { + perror("setsockopt(IPV6_V6ONLY, 0)"); + freeaddrinfo(res); + close(sd); + return (-1); + } + if (bind(sd, res->ai_addr, res->ai_addrlen) != 0) { + perror("bind()"); + freeaddrinfo(res); + close(sd); + return (-1); + } + if (listen(sd, 16) != 0) { + perror("listen()"); + freeaddrinfo(res); + close(sd); + return (-1); + } #ifdef HAVE_ACCEPT_FILTERS - accept_filter(heritage.sock_remote[u]); + accept_filter(sd); #endif - } - } + heritage.socket = sd; return (0); }