[Dnsmasq-discuss] Error returning query result from FreeBSD jail

Jan Seiffert kaffeemonster at googlemail.com
Wed Apr 11 19:49:09 BST 2012

David Nelson schrieb:
> Hi,
> I have been trying to get dnsmasq 2.60.1 working on my FreeNAS server within a FreeBSD 8.2 jail without any luck.
> Dnsmasq is able to receive requests, resolve them either by the local hosts file or external dns servers but then it can't reply back to the enquirer.
> Running in --no-daemon the logs for a local lookup look like this:
> dnsmasq: started, version 2.60 cachesize 150
> dnsmasq: compile time options: IPv6 GNU-getopt no-DBus i18n IDN DHCP DHCPv6 no-Lua TFTP no-conntrack
> dnsmasq: reading /etc/resolv.conf
> dnsmasq: using nameserver
> dnsmasq: using nameserver
> dnsmasq: read /etc/hosts - 5 addresses
> dnsmasq: query[A] athena from 192.168.x.104
> dnsmasq: /etc/hosts athena is 192.168.x.6
> dnsmasq: failed to send packet: Invalid argument

This is the important line. I guess it's forward.c at 113.
This means that the FreeBSD kernel is refusing to send send the packet, because he
does not like the call parameters.
The problem is, that sendmsg takes lots of parameters, thanks to this whole msg
You could try to start dnsmask with the OPT_NOWILD option (i think it's -z) to see if
this code path is generating the bad parameters.

But i guess the problem runs a little bit deeper.
All BSD-Kernel are a bit schizophrenic when it comes to sa_len. On the one hand
they inserted the sa_len field into struct sockaddr{|_in|_in6}, on the other hand
they are the inventors of the BSD-Socket API which takes some form of sa_len as
an extra argument on all functions.
And to make matters worse they are a little bit picky. If:
a) the sa_len field is not properly set even when it is not used (but the
socklen_t passed into the API) OR
b) the socklen_t passed into the API is not _exactly_ appropriate for the AF_FAMILIY
of the fd
you get an EINVAL.
The last point means you get an EINVAL error if you tell the kernel "i have space for
16 bytes" (you have "unified" addresses storage), but it is only an ipv4 socket, so it
expects 4 byte. (when i found this out i was ... dissatisfied.)

I think the dnsmasq code is to blame here. First in util.c we have the sa_len function.
It returns the sa_len field for OS which have it. Instead it should strictly go by
sa_family, no matter what the OS. And second, i can not find any place in the 2.60 source
code which actually sets the sa_len field, so it is probably sometimes mem garbage.

> TIA,
> Dave Nelson



More information about the Dnsmasq-discuss mailing list