]>
Commit | Line | Data |
---|---|---|
92c2e132 JR |
1 | --- common/network/TcpSocket.cxx.orig 2010-02-12 03:19:32.000000000 -0600 |
2 | +++ common/network/TcpSocket.cxx 2011-04-11 10:58:52.000000000 -0500 | |
3 | @@ -339,9 +339,38 @@ | |
4 | return; | |
5 | } | |
6 | ||
7 | + bool use_ipv6; | |
8 | + int af; | |
9 | +#ifdef AF_INET6 | |
10 | + // - localhostOnly will mean "127.0.0.1 only", no IPv6 | |
11 | + if (use_ipv6 = !localhostOnly) | |
12 | + af = AF_INET6; | |
13 | + else | |
14 | + af = AF_INET; | |
15 | +#else | |
16 | + use_ipv6 = false; | |
17 | + af = AF_INET; | |
18 | +#endif | |
19 | + | |
20 | initSockets(); | |
21 | - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) | |
22 | - throw SocketException("unable to create listening socket", errorNumber); | |
23 | + if ((fd = socket(af, SOCK_STREAM, 0)) < 0) { | |
24 | + // - Socket creation failed | |
25 | + if (use_ipv6) { | |
26 | + // - We were trying to make an IPv6-capable socket - try again, but IPv4-only | |
27 | + use_ipv6 = false; | |
28 | + af = AF_INET; | |
29 | + fd = socket(af, SOCK_STREAM, 0); | |
30 | + } | |
31 | + if (fd < 0) | |
32 | + throw SocketException("unable to create listening socket", errorNumber); | |
33 | + } else { | |
34 | + // - Socket creation succeeded | |
35 | + if (use_ipv6) { | |
36 | + // - We made an IPv6-capable socket, and we need it to do IPv4 too | |
37 | + int opt = 0; | |
38 | + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); | |
39 | + } | |
40 | + } | |
41 | ||
42 | #ifndef WIN32 | |
43 | // - By default, close the socket on exec() | |
44 | @@ -358,27 +387,39 @@ | |
45 | ||
46 | // - Bind it to the desired port | |
47 | struct sockaddr_in addr; | |
48 | - memset(&addr, 0, sizeof(addr)); | |
49 | - addr.sin_family = AF_INET; | |
50 | - | |
51 | - if (localhostOnly) { | |
52 | - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | |
53 | - } else if (listenaddr != NULL) { | |
54 | + struct sockaddr_in6 addr6; | |
55 | + struct sockaddr *sa; | |
56 | + int sa_len; | |
57 | + | |
58 | + if (use_ipv6) { | |
59 | + sa_len = sizeof(addr6); | |
60 | + memset(&addr6, 0, sa_len); | |
61 | + addr6.sin6_family = af; | |
62 | + addr6.sin6_port = htons(port); | |
63 | + sa = (struct sockaddr*) &addr6; | |
64 | + } else { | |
65 | + sa_len = sizeof(addr); | |
66 | + memset(&addr, 0, sa_len); | |
67 | + addr.sin_family = af; | |
68 | + addr.sin_port = htons(port); | |
69 | + if (localhostOnly) | |
70 | + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); | |
71 | + else if (listenaddr != NULL) { | |
72 | #ifdef HAVE_INET_ATON | |
73 | - if (inet_aton(listenaddr, &addr.sin_addr) == 0) | |
74 | + if (inet_aton(listenaddr, &addr.sin_addr) == 0) | |
75 | #else | |
76 | - /* Some systems (e.g. Windows) do not have inet_aton, sigh */ | |
77 | - if ((addr.sin_addr.s_addr = inet_addr(listenaddr)) == INADDR_NONE) | |
78 | + /* Some systems (e.g. Windows) do not have inet_aton, sigh */ | |
79 | + if ((addr.sin_addr.s_addr = inet_addr(listenaddr)) == INADDR_NONE) | |
80 | #endif | |
81 | - { | |
82 | - closesocket(fd); | |
83 | - throw Exception("invalid network interface address: %s", listenaddr); | |
84 | - } | |
85 | - } else | |
86 | - addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Bind to 0.0.0.0 by default. */ | |
87 | - | |
88 | - addr.sin_port = htons(port); | |
89 | - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { | |
90 | + { | |
91 | + closesocket(fd); | |
92 | + throw Exception("invalid network interface address: %s", listenaddr); | |
93 | + } | |
94 | + } else | |
95 | + addr.sin_addr.s_addr = htonl(INADDR_ANY); /* Bind to 0.0.0.0 by default. */ | |
96 | + sa = (struct sockaddr*) &addr; | |
97 | + } | |
98 | + if (bind(fd, sa, sa_len) < 0) { | |
99 | int e = errorNumber; | |
100 | closesocket(fd); | |
101 | throw SocketException("unable to bind listening socket", e); |