IPV6_V6ONLY and IP6_MIN_MTU socket options needed.

git-svn-id: file:///svn/unbound/trunk@53 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2007-02-02 10:13:18 +00:00
parent 71d6a178cf
commit 1a5832cbb9
3 changed files with 50 additions and 12 deletions

View File

@ -1,6 +1,7 @@
2 February 2007: Wouter
- Created udp4 and udp6 port arrays to provide service for both
address families.
- uses IPV6_USE_MIN_MTU for udp6 ,IPV6_V6ONLY to make ip6 sockets.
1 February 2007: Wouter
- outside network more UDP work.

View File

@ -83,11 +83,38 @@ int
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;
@ -113,9 +140,9 @@ static int
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));
@ -129,6 +156,16 @@ create_tcp_accept_sock(struct addrinfo *addr)
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;

View File

@ -245,16 +245,16 @@ outside_network_create(struct comm_base *base, size_t bufsize,
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");
@ -265,16 +265,16 @@ outside_network_create(struct comm_base *base, size_t bufsize,
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");