From: Wouter Wijngaards Date: Fri, 18 Jan 2008 09:09:55 +0000 (+0000) Subject: BSD fix for ip4. X-Git-Tag: release-0.9~65 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb3a1178b6194c2c533fc574168df42406f37731;p=thirdparty%2Funbound.git BSD fix for ip4. git-svn-id: file:///svn/unbound/trunk@875 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/doc/Changelog b/doc/Changelog index 8a338e506..290eb4978 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,6 +1,8 @@ 18 January 2008: Wouter - touch up of manpage for libunbound. - support for IP_RECVDSTADDR (for *BSD ip4). + - fix for BSD, do not use ip4to6 mapping, make two sockets, once + ip6 and once ip4, uses socket options. 17 January 2008: Wouter - fixup configure in case -lldns is installed. diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 22e3dad8f..6eb8eb8d6 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -239,48 +239,54 @@ port_insert(struct listen_port** list, int s, enum listen_type ftype) return 1; } -/** set IPV6_RECVPKTINFO on fd */ +/** set fd to receive source address packet info */ static int -set_ip6_recvpktinfo(int s) +set_recvpktinfo(int s, int family) { int on = 1; -#ifdef IPV6_RECVPKTINFO - if(setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, - &on, (socklen_t)sizeof(on)) < 0) { - log_err("setsockopt(..., IPV6_RECVPKTINFO, ...) failed: %s", - strerror(errno)); + if(family == AF_INET6) { +# ifdef IPV6_RECVPKTINFO + if(setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, + &on, (socklen_t)sizeof(on)) < 0) { + log_err("setsockopt(..., IPV6_RECVPKTINFO, ...) failed: %s", + strerror(errno)); + return 0; + } +# elif defined(IPV6_PKTINFO) + if(setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, + &on, (socklen_t)sizeof(on)) < 0) { + log_err("setsockopt(..., IPV6_PKTINFO, ...) failed: %s", + strerror(errno)); + return 0; + } +# else + log_err("no IPV6_RECVPKTINFO and no IPV6_PKTINFO option, please " + "disable interface-automatic in config"); return 0; - } -#elif defined(IPV6_PKTINFO) - if(setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, - &on, (socklen_t)sizeof(on)) < 0) { - log_err("setsockopt(..., IPV6_PKTINFO, ...) failed: %s", - strerror(errno)); +# endif /* defined IPV6_RECVPKTINFO */ + + } else if(family == AF_INET) { +# ifdef IP_RECVDSTADDR + if(setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, + &on, (socklen_t)sizeof(on)) < 0) { + log_err("setsockopt(..., IP_RECVDSTADDR, ...) failed: %s", + strerror(errno)); + return 0; + } +# elif defined(IP_PKTINFO) + if(setsockopt(s, IPPROTO_IP, IP_PKTINFO, + &on, (socklen_t)sizeof(on)) < 0) { + log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s", + strerror(errno)); + return 0; + } +# else + log_err("no IP_RECVDSTADDR or IP_PKTINFO option, please disable " + "interface-automatic in config"); return 0; - } -#else - log_err("no IPV6_RECVPKTINFO and no IPV6_PKTINFO option, please " - "disable interface-automatic in config"); - return 0; -#endif /* defined IPV6_RECVPKTINFO */ +# endif /* IP_PKTINFO */ -#ifdef IP_RECVDSTADDR - if(setsockopt(s, IPPROTO_IP, IP_RECVDSTADDR, - &on, (socklen_t)sizeof(on)) < 0) { - log_err("setsockopt(..., IP_RECVDSTADDR, ...) failed: %s", - strerror(errno)); - } -#elif defined(IP_PKTINFO) - if(setsockopt(s, IPPROTO_IP, IP_PKTINFO, - &on, (socklen_t)sizeof(on)) < 0) { - log_err("setsockopt(..., IP_PKTINFO, ...) failed: %s", - strerror(errno)); } -#else - log_err("no IP_RECVDSTADDR or IP_PKTINFO option, please disable " - "interface-automatic in config"); - return 0; -#endif /* IP_PKTINFO */ return 1; } @@ -305,16 +311,14 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, return 0; if(do_auto) { /* skip ip4 sockets, ip4 udp gets mapped to v6 */ - if(hints->ai_family == AF_INET6) { - if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 2)) - == -1) - return 0; - if(!set_ip6_recvpktinfo(s)) - return 0; - if(!port_insert(list, s, listen_type_udpancil)) { - close(s); - return 0; - } + /* TODO no mapping! */ + if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1)) == -1) + return 0; + if(!set_recvpktinfo(s, hints->ai_family)) + return 0; + if(!port_insert(list, s, listen_type_udpancil)) { + close(s); + return 0; } } else if(do_udp) { /* regular udp socket */ diff --git a/util/netevent.c b/util/netevent.c index 7f43b7715..15924fc60 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -369,7 +369,7 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg) } else if( cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_RECVDSTADDR) { rep.srctype = 4; - memmove(&rep.v4addr, CMSG_DATA(cmsg), + memmove(&rep.pktinfo.v4addr, CMSG_DATA(cmsg), sizeof(struct in_addr)); break; #elif defined(IP_PKTINFO)