Re: [Dnsmasq-discuss] 2.68rc4: bind-interfaces, FreeBSD, IPv6 2001:... addr fails and loses error code, parallel build brittle
On 04/12/13 01:09, Matthias Andree wrote: I don't think so - I rather suspect that this is a rare occasion and I was the first to see and report it. It would seem we have four nondefault constraints for the bug to show: 1. IPv6 needs to be enabled on the external interface 2. a global IPv6 needs to be configured, either manually, or autoconfigured from an external router 3. dnsmasq needs to be installed 4. dnsmasq needs to use --bind-interfaces. I think you're right. Certainly I was able to reproduce the problem in my Freeb=BSD test VM, by adding a globally-routable IPv6 address which isn't normally there. Cheers, Simon. ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Re: [Dnsmasq-discuss] 2.68rc4: bind-interfaces, FreeBSD, IPv6 2001:... addr fails and loses error code, parallel build brittle
On 02/12/13 21:13, Matthias Andree wrote: Am 02.12.2013 13:01, schrieb Simon Kelley: On 01/12/13 01:59, Matthias Andree wrote: Greetings, testing 2.68rc4, I have found three issues, on FreeBSD 9.2 amd64: 1. the Makefiles might not thoroughly list all dependencies required to build the dnsmasq executable; I found my build miss cache.o when linking (compiling with make -j + high number), re-running make immediately after the failure solved the problem. I am using a local UFS file system, so no NFS time skew. I am using GNU make 3.82. By miss cache.o do you meant that cache.o was not included in the link command line, or that the link failed because cache.o had not been built. This is mysterious, and there's nothing different about cache.o versus the other object files. The latter, and I suspect that it might have been any other cache.o file. I'd be interested to know the status of those addresses, and Duplicate Address Detection, since that's the best explanation I have of the source of that error return. Is it possible to turn DAD off, and see if that fixes things? Yes, but it is neither the culprit nor does it fix things. I'm also interested in what's happening in bpf.c in the interface enumeration code: ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs-ifa_addr); if (fd != -1 ioctl(fd, SIOCGIFAFLAG_IN6,ifr6) != -1) { if (ifr6.ifr_ifru.ifru_flags6 IN6_IFF_TENTATIVE) flags |= IFACE_TENTATIVE; Should set IFACE_TENTATIVE in flags if the interface is still doing DAD. The address is marked with only the IN6_IFF_AUTOCONF flag. IN6_IFF_TENTATIVE in particular is unset. On the second another 2001:... address, I have automatic | temporary (private). Meaning that the ifconfig output renders the interface flags quite well. But that's not the issue here. The flags variable you pass through the callback on line 199 in bpf.c ends up as 0 for these two aliases on em0. Anyways I debugged this a bit more, and in network.c you have: 698 #ifdef HAVE_IPV6 699 if (family == AF_INET6 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,opt, sizeof(opt)) == -1) 700 goto err; 701 #endif 702 703 if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1) 704 goto err; When this is run on the 2001:. addresses, addr-in6.sin6_scope_id is not 0. Setting this to 0 only on the 2001:... addresses makes the bind succeed, and presents me with: dnsmasq: started, version 2.68rc4-2-g0861921 cachesize 150 dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack no-ipset auth dnsmasq: LOUD WARNING: listening on 2001:BLAH:BLAH:893e:a00:MAC:ADDR:HERE may accept requests via interfaces other than em0 dnsmasq: LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s) dnsmasq: using nameserver 127.0.0.1#53 dnsmasq: read /etc/hosts - 5 addresses Now we're getting somewhere, apparently FreeBSD chokes if you present a nonzero sin6_scope_id with a regular unicast address, rather than a link-local special address (which requires the interface index), whereas Linux appears to ignore it. Could you double-check iface_allowed_v6() and the network enumeration code that calls it, and the code in network.c:703 that calls bind()? Either needs to zero out the scope_id for non-link-local i'faces. That looks like a very good diagnosis: zeroing the scope_id in the appropriate cases should be easy. I wonder why this has just struck, the code has been like that for some time, and never previuosly hit a problem. FreeBSD change? I'm thinking of having a small tattoo, in a visible (to me) place that reads REMEMBER: IPv6 is not IPv4. That aside, I am not sure what this LOUD WARNING is about here, and if it applies to FreeBSD (it would seem Linux can do reverse path checking, too, and reject martians if the stuff arrives on the wrong interface's ingress). It's not a martian problem, it's the Weak End System Model which is used by Linux. I don't know if that's used by FreeBSD. When --bind-interfaces in in use dnsmasq --interface=em0 becomes functionally equivalent to dnsmasq --listen-address=address_of_em0 With a weak end system, packets arriving on _any_ interface will be accepted if their destination address in an address of em0. This equivalence is because --bind-interfaces mode is intended to work on platforms which don't support the API which returns the arrival interface of a the packet, so the only filtering of the bind()ing of the socket. The standard fix is to use --bind-dynamic, which can rely on the existence of the extended API. Unfortunately that doesn't work on FreeBSD because it also relies on a a method of getting asynchronous events when interfaces/address come and go. Does FreeBSD have an equivalent of the Linux netlink socket? (OpenBSD, last time I checked,
Re: [Dnsmasq-discuss] 2.68rc4: bind-interfaces, FreeBSD, IPv6 2001:... addr fails and loses error code, parallel build brittle
Am 03.12.2013 12:11, schrieb Simon Kelley: Could you double-check iface_allowed_v6() and the network enumeration code that calls it, and the code in network.c:703 that calls bind()? Either needs to zero out the scope_id for non-link-local i'faces. That looks like a very good diagnosis: zeroing the scope_id in the appropriate cases should be easy. I wonder why this has just struck, the code has been like that for some time, and never previuosly hit a problem. FreeBSD change? I don't think so - I rather suspect that this is a rare occasion and I was the first to see and report it. It would seem we have four nondefault constraints for the bug to show: 1. IPv6 needs to be enabled on the external interface 2. a global IPv6 needs to be configured, either manually, or autoconfigured from an external router 3. dnsmasq needs to be installed 4. dnsmasq needs to use --bind-interfaces. I'm thinking of having a small tattoo, in a visible (to me) place that reads REMEMBER: IPv6 is not IPv4. :) It's not a martian problem, it's the Weak End System Model which is used by Linux. I don't know if that's used by FreeBSD. I have never bothered to check, yet. The standard fix is to use --bind-dynamic, which can rely on the existence of the extended API. Unfortunately that doesn't work on FreeBSD because it also relies on a a method of getting asynchronous events when interfaces/address come and go. Does FreeBSD have an equivalent of the Linux netlink socket? I'm not aware of one, and address changes do not appear through devctl(4). This would best be asked on FreeBSD-hackers or similar lists. ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
Re: [Dnsmasq-discuss] 2.68rc4: bind-interfaces, FreeBSD, IPv6 2001:... addr fails and loses error code, parallel build brittle
On 01/12/13 01:59, Matthias Andree wrote: Greetings, testing 2.68rc4, I have found three issues, on FreeBSD 9.2 amd64: 1. the Makefiles might not thoroughly list all dependencies required to build the dnsmasq executable; I found my build miss cache.o when linking (compiling with make -j + high number), re-running make immediately after the failure solved the problem. I am using a local UFS file system, so no NFS time skew. I am using GNU make 3.82. By miss cache.o do you meant that cache.o was not included in the link command line, or that the link failed because cache.o had not been built. This is mysterious, and there's nothing different about cache.o versus the other object files. 2. Binding IPv6 addresses on FreeBSD does not appear to work properly, with bind-interfaces option. 3. And the error from 2. does not get properly reported either, the error code is apparently lost somewhere, or errno gets reset. OK, that's easy fix, when the bind fails, don't call close() on the socket before reporting the error, or save/restore errno. This is the dnsmasq.conf, domain made up (build configuration is below in the log of the successful start): domain-needed bogus-priv no-resolv no-poll server=127.0.0.1 except-interface=lo0 bind-interfaces expand-hosts domain=EXAMPLE.org This is the interface configuration, with some information masked: em0: flags=8843UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST metric 0 mtu 1500 options=9bRXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM ether ... inet 192.168.33.14 netmask 0xff00 broadcast 192.168.33.255 inet6 fe80::a00:..ff:fe..:1234%em0 prefixlen 64 scopeid 0x1 inet6 2001::::a00:..ff:fe..:1234 prefixlen 64 autoconf inet6 2001::::b0e1:f6da:: prefixlen 64 autoconf temporary nd6 options=23PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL media: Ethernet autoselect (1000baseTfull-duplex) status: active lo0: flags=8049UP,LOOPBACK,RUNNING,MULTICAST metric 0 mtu 16384 options=63RXCSUM,TXCSUM,RXCSUM_IPV6,TXCSUM_IPV6 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x4 inet 127.0.0.1 netmask 0xff00 nd6 options=21PERFORMNUD,AUTO_LINKLOCAL groups: lo This is the error when running things: $ LC_ALL=C sudo /var/tmp/usr/ports.svn/dns/dnsmasq-devel/work/stage/usr/local/sbin/dnsmasq -d dnsmasq: failed to create listening socket for 2001:4dd0:ff00:893e:b0e1:f6da:b2d8:9720%em0: No error: 0 Now, this doesn't help at all, so let's go for details and use truss: $ LC_ALL=C sudo truss dnsmasq -d 21 | egrep -v close.*ERR#9 mmap(0x0,32768,PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON,-1,0x0) = 34366386176 (0x800657000) issetugid(0x800857a60,0x7fffefc8,0x40,0x0,0x800800858a98,0x0) = 0 (0x0) ... open(/usr/local/etc/dnsmasq.conf,O_RDONLY,0666) = 3 (0x3) fstat(3,{ mode=-rw-r--r-- ,inode=10763926,size=25245,blksize=16384 }) = 0 (0x0) read(3,# Configuration file for dnsmasq...,16384) = 16384 (0x4000) read(3,#dhcp-option-force=208,f1:00:74:...,16384) = 8861 (0x229d) read(3,0x801c84000,16384)= 0 (0x0) close(3) = 0 (0x0) madvise(0x801cd2000,0x1000,0x5,0xd1,0x7fffce00,0x) = 0 (0x0) madvise(0x801ccf000,0x1000,0x5,0xce,0x7fffce00,0x) = 0 (0x0) madvise(0x801c84000,0x4000,0x5,0x83,0x7fffce00,0x) = 0 (0x0) open(/dev/null,O_RDWR,0160002740)= 3 (0x3) open(/dev/null,O_RDWR,0160002740)= 4 (0x4) open(/dev/null,O_RDWR,0160002740)= 5 (0x5) close(3) = 0 (0x0) close(4) = 0 (0x0) close(5) = 0 (0x0) clock_gettime(13,{1385861339.0 })= 0 (0x0) socket(PF_INET,SOCK_DGRAM,0) = 3 (0x3) __sysctl(0x7fffd730,0x6,0x0,0x7fffd748,0x0,0x0) = 0 (0x0) __sysctl(0x7fffd730,0x6,0x801c80400,0x7fffd748,0x0,0x0) = 0 (0x0) socket(PF_INET6,SOCK_DGRAM,0)= 4 (0x4) socket(PF_INET,SOCK_DGRAM,0) = 5 (0x5) ioctl(5,SIOCGIFINDEX,0xd730) = 0 (0x0) close(5) = 0 (0x0) ioctl(4,SIOCGIFAFLAG_IN6,0xd7d0) = 0 (0x0) ioctl(4,SIOCGIFALIFETIME_IN6,0xd7d0) = 0 (0x0) __sysctl(0x7fffd610,0x6,0x0,0x7fffd628,0x0,0x0) = 0 (0x0) __sysctl(0x7fffd610,0x6,0x801c80400,0x7fffd628,0x0,0x0) = 0 (0x0) ioctl(3,SIOCGIFFLAGS,0xd6e0) = 0 (0x0) ioctl(3,SIOCGIFMTU,0xd6e0) = 0 (0x0) socket(PF_INET,SOCK_DGRAM,0) = 5 (0x5) ioctl(5,SIOCGIFINDEX,0xd730) = 0 (0x0) close(5) = 0 (0x0) ioctl(4,SIOCGIFAFLAG_IN6,0xd7d0) = 0 (0x0) ioctl(4,SIOCGIFALIFETIME_IN6,0xd7d0) = 0 (0x0)
Re: [Dnsmasq-discuss] 2.68rc4: bind-interfaces, FreeBSD, IPv6 2001:... addr fails and loses error code, parallel build brittle
Am 02.12.2013 13:01, schrieb Simon Kelley: On 01/12/13 01:59, Matthias Andree wrote: Greetings, testing 2.68rc4, I have found three issues, on FreeBSD 9.2 amd64: 1. the Makefiles might not thoroughly list all dependencies required to build the dnsmasq executable; I found my build miss cache.o when linking (compiling with make -j + high number), re-running make immediately after the failure solved the problem. I am using a local UFS file system, so no NFS time skew. I am using GNU make 3.82. By miss cache.o do you meant that cache.o was not included in the link command line, or that the link failed because cache.o had not been built. This is mysterious, and there's nothing different about cache.o versus the other object files. The latter, and I suspect that it might have been any other cache.o file. I'd be interested to know the status of those addresses, and Duplicate Address Detection, since that's the best explanation I have of the source of that error return. Is it possible to turn DAD off, and see if that fixes things? Yes, but it is neither the culprit nor does it fix things. I'm also interested in what's happening in bpf.c in the interface enumeration code: ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs-ifa_addr); if (fd != -1 ioctl(fd, SIOCGIFAFLAG_IN6, ifr6) != -1) { if (ifr6.ifr_ifru.ifru_flags6 IN6_IFF_TENTATIVE) flags |= IFACE_TENTATIVE; Should set IFACE_TENTATIVE in flags if the interface is still doing DAD. The address is marked with only the IN6_IFF_AUTOCONF flag. IN6_IFF_TENTATIVE in particular is unset. On the second another 2001:... address, I have automatic | temporary (private). Meaning that the ifconfig output renders the interface flags quite well. But that's not the issue here. The flags variable you pass through the callback on line 199 in bpf.c ends up as 0 for these two aliases on em0. Anyways I debugged this a bit more, and in network.c you have: 698 #ifdef HAVE_IPV6 699if (family == AF_INET6 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, opt, sizeof(opt)) == -1) 700 goto err; 701 #endif 702 703if ((rc = bind(fd, (struct sockaddr *)addr, sa_len(addr))) == -1) 704 goto err; When this is run on the 2001:. addresses, addr-in6.sin6_scope_id is not 0. Setting this to 0 only on the 2001:... addresses makes the bind succeed, and presents me with: dnsmasq: started, version 2.68rc4-2-g0861921 cachesize 150 dnsmasq: compile time options: IPv6 GNU-getopt no-DBus no-i18n no-IDN DHCP DHCPv6 no-Lua TFTP no-conntrack no-ipset auth dnsmasq: LOUD WARNING: listening on 2001:BLAH:BLAH:893e:a00:MAC:ADDR:HERE may accept requests via interfaces other than em0 dnsmasq: LOUD WARNING: use --bind-dynamic rather than --bind-interfaces to avoid DNS amplification attacks via these interface(s) dnsmasq: using nameserver 127.0.0.1#53 dnsmasq: read /etc/hosts - 5 addresses Now we're getting somewhere, apparently FreeBSD chokes if you present a nonzero sin6_scope_id with a regular unicast address, rather than a link-local special address (which requires the interface index), whereas Linux appears to ignore it. Could you double-check iface_allowed_v6() and the network enumeration code that calls it, and the code in network.c:703 that calls bind()? Either needs to zero out the scope_id for non-link-local i'faces. That aside, I am not sure what this LOUD WARNING is about here, and if it applies to FreeBSD (it would seem Linux can do reverse path checking, too, and reject martians if the stuff arrives on the wrong interface's ingress). I'll commit a fix for the simple errno problem, to make things easier. Unfortunately, that does not appear to work either, I still get dnsmasq: failed to create listening socket for 2001:...c258%em0: No error: 0. (I am on git master, which is one commit ahead of 3dffbc3eb). I am attaching an incremental patch (use git am to apply it) to the current Git master that fixes the problem for me. It merely extends the scope of the errsav copy of the actual errno code. (Sending a Bcc: to Simon in case the list driver strips it.) Hope that helps. Best regards Matthias From 2a8601e1eefd19c8bd081e9f2fec363b6ff6da48 Mon Sep 17 00:00:00 2001 From: Matthias Andree matthias.and...@gmx.de Date: Mon, 2 Dec 2013 22:04:38 +0100 Subject: [PATCH] Really preserve error code when socket setup fails. --- src/network.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network.c b/src/network.c index 5225ec5..90ab873 100644 --- a/src/network.c +++ b/src/network.c @@ -657,7 +657,7 @@ static int make_sock(union mysockaddr *addr, int type, int dienow) if ((fd = socket(family, type, 0)) == -1) { - int port; + int port, errsav; char *s; /* No error if the kernel just doesn't support this IP flavour */ @@ -667,6 +667,7 @@ static int make_sock(union mysockaddr
Re: [Dnsmasq-discuss] 2.68rc4: bind-interfaces, FreeBSD, IPv6 2001:... addr fails and loses error code, parallel build brittle
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Am 02.12.2013 22:13, schrieb Matthias Andree: The latter, and I suspect that it might have been any other cache.o file. ... .o file than cache.o. Not quite clear what's causing it, a cursory glance over Makefile lets it look innocent to my eye. -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.11 (GNU/Linux) iEYEARECAAYFAlKc+cYACgkQvmGDOQUufZUUpwCgmbWTg7+anmf4GkVNCBKQOz4W mGUAmgOG2LQ8bGGBEGvPAW5G1y6mZC35 =p1M1 -END PGP SIGNATURE- ___ Dnsmasq-discuss mailing list Dnsmasq-discuss@lists.thekelleys.org.uk http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss