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

Matthias Andree matthias.andree at gmx.de
Mon Apr 16 00:36:28 BST 2012

Am 11.04.2012 21:13, schrieb Simon Kelley:
> On 11/04/12 19:49, Jan Seiffert wrote:
>> 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
>> foobar.
>> 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
>> 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.
> You're greping for the wrong thing: the field is set using the sin_len
> or sin6_len union elements.
> It will be something like this, but if it was the address that was
> wrong, it would fail when --bind-interfaces is set too, and it doesn't
> (Dave mailed me off list). There must be something wrong with the
> parameters sent only when setting the source address, or maybe that's
> not possible in a jail?

The jail is a security compartment and doesn't permit, for one, raw
sockets without further ado, or communication using an address not
assigned to the jail.

The FreeBSD man pages are available online, see, for instance:


or the handbook:


I don't have time to dig deeper right now, but I suspect that this
explains the "jailed" behaviour -- do I read your paraphrase of Dave's
mail correctly as "--bind-interfaces fixes this"?

More information about the Dnsmasq-discuss mailing list