[distcc] ipv6 & EAFNOSUPPORT
Martin Pool
mbp at sourcefrog.net
Tue Mar 2 04:23:23 GMT 2004
On 1 Mar 2004, Lisa Seelye <lisa at gentoo.org> wrote:
> On Mon, 2004-03-01 at 19:37, Martin Pool wrote:
> > So basically this should be done at runtime: if we wanted to create an
> > IPv6 socket but couldn't, then we should fall back to IPv4.
> >
> > Was my guess right that you did --enable-rfc2553 but the kernel didn't
> > have ipv6?
>
> Yeah, the user filed a bug and didn't have ipv6 compiled into their
> kernel. ("I was just planning ahead...")
>
> Testing at runtime seems like a good idea as you suggest (try ipv6, else
> ipv4 and throw a warning).
Could you ask them to try this, please?
--- srvnet.c.~1.46.~ 2004-02-19 14:09:38.000000000 +1100
+++ srvnet.c 2004-03-02 15:17:43.000000000 +1100
@@ -72,24 +72,17 @@
#include "netutil.h"
#include "dopt.h"
-/**
+/*
* Listen on a predetermined address (often the passive address). The way in
* which we get the address depends on the resolver API in use.
**/
-static int dcc_listen_by_addr(int *listen_fd,
+static int dcc_listen_by_addr(int fd,
struct sockaddr *sa,
size_t salen)
{
int one = 1;
- int fd;
char *sa_buf = NULL;
- fd = socket(sa->sa_family, SOCK_STREAM, 0);
- if (fd == -1) {
- rs_log_error("socket creation failed: %s", strerror(errno));
- return EXIT_BIND_FAILED;
- }
-
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one));
dcc_sockaddr_to_string(sa, salen, &sa_buf);
@@ -111,10 +104,8 @@ static int dcc_listen_by_addr(int *liste
close(fd);
return EXIT_BIND_FAILED;
}
-
- *listen_fd = fd;
- return 0;
+ return 0;
}
@@ -122,12 +113,13 @@ static int dcc_listen_by_addr(int *liste
#if defined(ENABLE_RFC2553)
/* This version uses getaddrinfo. It will probably use IPv6 if that's
* supported by your configuration, kernel, and library. */
-int dcc_socket_listen(int port, int *listen_fd, const char *listen_addr)
+int dcc_socket_listen(int port, int *fd_out, const char *listen_addr)
{
char portname[20];
struct addrinfo hints;
- struct addrinfo *res, *best;
+ struct addrinfo *res, *ai;
int error;
+ int ret;
/* getaddrinfo() ought to check for this, but some versions do not.
* (Debian Bug#192876.) */
@@ -155,11 +147,27 @@ int dcc_socket_listen(int port, int *lis
return EXIT_BIND_FAILED;
}
- /* For now we always just use the first entry. Is that OK? */
-
- return dcc_listen_by_addr(listen_fd, res->ai_addr, res->ai_addrlen);
+ /* The first sockaddr returned will typically be an IPv6 socket. Some
+ * kernels might not support that. */
+ for (ai = res; ai; ai=ai->ai_next) {
+ int af = ai->ai_addr->sa_family;
+ if ((*fd_out = socket(af, SOCK_STREAM, 0)) == -1) {
+ if (errno == EAFNOSUPPORT) {
+ rs_log_notice("socket address family %d not supported", af);
+ continue;
+ } else {
+ rs_log_error("socket creation failed: %s", strerror(errno));
+ return EXIT_BIND_FAILED;
+ }
+ } else {
+ ret = dcc_listen_by_addr(*fd_out, res->ai_addr, res->ai_addrlen);
+ freeaddrinfo(res);
+ return ret;
+ }
+ }
- /* FIXME: This leaks the res list. */
+ rs_log_error("failed to find any supported socket family");
+ return EXIT_BIND_FAILED;
}
#else /* ndef ENABLE_RFC2553 */
@@ -189,7 +197,12 @@ int dcc_socket_listen(int port, int *lis
sock.sin_addr.s_addr = INADDR_ANY;
}
- return dcc_listen_by_addr(listen_fd, (struct sockaddr *) &sock,
+ if ((*listen_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
+ rs_log_error("socket creation failed: %s", strerror(errno));
+ return EXIT_BIND_FAILED;
+ }
+
+ return dcc_listen_by_addr(*listen_fd, (struct sockaddr *) &sock,
sizeof sock);
}
#endif /* ndef ENABLE_RFC2553 */
--
Martin
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://lists.samba.org/archive/distcc/attachments/20040302/fd5e5892/attachment.bin
More information about the distcc
mailing list