create_udp_sock(struct addrinfo *addr)
{
int s, flag;
+ int on=1;
verbose_print_addr(addr);
if((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
log_err("can't create socket: %s", strerror(errno));
return -1;
}
+ if(addr->ai_family == AF_INET6) {
+# if defined(IPV6_V6ONLY)
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
+ &on, sizeof(on)) < 0) {
+ log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
+ strerror(errno));
+ return -1;
+ }
+# endif
+# if defined(IPV6_USE_MIN_MTU)
+ /*
+ * There is no fragmentation of IPv6 datagrams
+ * during forwarding in the network. Therefore
+ * we do not send UDP datagrams larger than
+ * the minimum IPv6 MTU of 1280 octets. The
+ * EDNS0 message length can be larger if the
+ * network stack supports IPV6_USE_MIN_MTU.
+ */
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+ &on, sizeof(on)) < 0) {
+ log_msg(LOG_ERR, "setsockopt(..., IPV6_USE_MIN_MTU, "
+ "...) failed: %s", strerror(errno));
+ return -1;
+ }
+# endif
+ }
if(bind(s, (struct sockaddr*)addr->ai_addr, addr->ai_addrlen) != 0) {
log_err("can't bind socket: %s", strerror(errno));
return -1;
create_tcp_accept_sock(struct addrinfo *addr)
{
int s, flag;
-#ifdef SO_REUSEADDR
+#if defined(SO_REUSEADDR) || defined(IPV6_V6ONLY)
int on = 1;
-#endif /* SO_REUSEADDR */
+#endif /* SO_REUSEADDR || IPV6_V6ONLY */
verbose_print_addr(addr);
if((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
log_err("can't create socket: %s", strerror(errno));
return -1;
}
#endif /* SO_REUSEADDR */
+#if defined(IPV6_V6ONLY)
+ if(addr->ai_family == AF_INET6) {
+ if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
+ &on, sizeof(on)) < 0) {
+ log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
+ strerror(errno));
+ return -1;
+ }
+ }
+#endif /* IPV6_V6ONLY */
if(bind(s, (struct sockaddr*)addr->ai_addr, addr->ai_addrlen) != 0) {
log_err("can't bind socket: %s", strerror(errno));
return -1;
outside_network_delete(outnet);
return NULL;
}
- /* open ip4 ports first, to get them apart from ip6 ports. */
+ /* Try to get ip6 and ip4 ports. Ip6 first, in case second fails. */
if(num_ifs == 0) {
- if(do_ip4) {
- outnet->num_udp4 = make_udp_range(outnet->udp4_ports,
- NULL, num_ports, 1, 0, port_base, outnet);
- }
if(do_ip6) {
outnet->num_udp6 = make_udp_range(outnet->udp6_ports,
NULL, num_ports, 0, 1, port_base, outnet);
}
+ if(do_ip4) {
+ outnet->num_udp4 = make_udp_range(outnet->udp4_ports,
+ NULL, num_ports, 1, 0, port_base, outnet);
+ }
if(outnet->num_udp4 != num_ports ||
outnet->num_udp6 != num_ports) {
log_err("Could not open all networkside ports");
else {
size_t done_4 = 0, done_6 = 0;
for(k=0; k<num_ifs; k++) {
- if(!str_is_ip6(ifs[k]) && do_ip4) {
- done_4 += make_udp_range(
- outnet->udp4_ports+done_4, ifs[k],
- num_ports, 1, 0, port_base, outnet);
- }
if(str_is_ip6(ifs[k]) && do_ip6) {
done_6 += make_udp_range(
outnet->udp6_ports+done_6, ifs[k],
num_ports, 0, 1, port_base, outnet);
}
+ if(!str_is_ip6(ifs[k]) && do_ip4) {
+ done_4 += make_udp_range(
+ outnet->udp4_ports+done_4, ifs[k],
+ num_ports, 1, 0, port_base, outnet);
+ }
}
if(done_6 != outnet->num_udp6 || done_4 != outnet->num_udp4) {
log_err("Could not open all ports on all interfaces");