From 1a5832cbb93a80db7c3afc2923567c5836a87642 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 2 Feb 2007 10:13:18 +0000 Subject: [PATCH] IPV6_V6ONLY and IP6_MIN_MTU socket options needed. git-svn-id: file:///svn/unbound/trunk@53 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 1 + services/listen_dnsport.c | 41 ++++++++++++++++++++++++++++++++++++-- services/outside_network.c | 20 +++++++++---------- 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 4546e1f6c..fc7f0c319 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index d28012326..6652edda0 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -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; diff --git a/services/outside_network.c b/services/outside_network.c index 788927e37..0238ac88e 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -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; kudp4_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"); -- 2.47.2