Dynamic-host was implemented to ignore interface addresses with /32
(or /128 for IPv6) prefix lengths, since they are not useful for
synthesising addresses.
Due to a bug before 2.88, this didn't work for IPv4, and some have
used --dynamic-host=example.com,0.0.0.0,eth0 to do the equivalent of
--interface-name for such interfaces. When the bug was fixed in 2.88
these uses broke.
Since this behaviour seems to violate the principle of least surprise,
and since the 2.88 fix is breaking existing imstallations, this
commit removes the check on /32 and /128 prefix lengths to solve both
problems.
Signed-off-by: DL6ER <dl6er@dl6er.de>
If there exists a --address=/<domain>/ or --server=/<domain>/#
configuration but no upstream server config unqualified by
domain then when a query which doesnt match the domain is
recieved it will use the qualfied server config and in the process
possibly make an out-of-bounds memory access.
Thanks to Daniel Danzberger for spotting the bug.
Signed-off-by: DL6ER <dl6er@dl6er.de>
As defined in the C standard:
In all cases the argument is an int, the value of which shall
be representable as an unsigned char or shall equal the value
of the macro EOF. If the argument has any other value, the
behavior is undefined.
This is because they're designed to work with the int values returned
by getc or fgetc; they need extra work to handle a char value.
If EOF is -1 (as it almost always is), with 8-bit bytes, the allowed
inputs to the ctype(3) functions are:
{-1, 0, 1, 2, 3, ..., 255}.
However, on platforms where char is signed, such as x86 with the
usual ABI, code like
char *arg = ...;
... isspace(*arg) ...
may pass in values in the range:
{-128, -127, -126, ..., -2, -1, 0, 1, ..., 127}.
This has two problems:
1. Inputs in the set {-128, -127, -126, ..., -2} are forbidden.
2. The non-EOF byte 0xff is conflated with the value EOF = -1, so
even though the input is not forbidden, it may give the wrong
answer.
Casting char to int first before passing the result to ctype(3)
doesn't help: inputs like -128 are unchanged by this cast. It is
necessary to cast char inputs to unsigned char first; you can then
cast to int if you like but there's no need because the functions
will always convert the argument to int by definition. So the above
fragment needs to be:
char *arg = ...;
... isspace((unsigned char)*arg) ...
This patch inserts unsigned char casts where necessary, and changes
int casts to unsigned char casts where the input is char.
I left alone int casts where the input is unsigned char already --
they're not immediately harmful, although they would have the effect
of suppressing some compiler warnings if the input is ever changed to
be char instead of unsigned char, so it might be better to remove
those casts too.
I also left alone calls where the input is int to begin with because
it came from getc; casting to unsigned char here would be wrong, of
course.
Signed-off-by: DL6ER <dl6er@dl6er.de>
If there are multiple cache records with the same name but different
F_REVERSE and/or F_IMMORTAL flags, the code added in fe9a134b could
concievable break the REVERSE-FORWARD-IMMORTAL order invariant.
Reproducing this is damn near impossible, but it is responsible
for rare and otherwise inexplicable reversion between 2.87 and 2.88
which manifests itself as a cache internal error. All observed
cases have depended on DNSSEC being enabled, but the bug could in
theory manifest itself without DNSSEC
Thanks to Timo van Roermund for reporting the bug and huge
efforts to isolate it.
Signed-off-by: DL6ER <dl6er@dl6er.de>
If we detect that that reply from usptream is malformed,
transform it into a SERVFAIL reply before sending to the
original requestor.
Signed-off-by: DL6ER <dl6er@dl6er.de>
When re-reading upstream servers from /etc/resolv.conf or other
sources that can change dnsmasq tries to avoid memory fragmentation by
re-using existing records that are being re-read unchanged. This
involves seaching all the server records for each new one installed.
During startup this search is pointless, and can cause long start
times with thousands of --server options because the work needed is
O(n^2). Handle this case more intelligently. Thanks to Ye Zhou for
spotting the problem and an initial patch.
Signed-off-by: DL6ER <dl6er@dl6er.de>
The code added in6 c596f1cc1d92b2b90ef5ce043ace314eefa868b
fails to free the returned datastructures from gethostinfo()
because sdetails.hostinfo is used to loop through the addresses
and ends up NULL. In some libc implementations this results
in a SEGV when freeaddrinfo() is called.
Also fix FTBFS under BSD. Thanks to Johnny S. Lee for the bug report.
Signed-off-by: DL6ER <dl6er@dl6er.de>
Such a DS, as long as it is validated, should allow answers
in the domain is attests to be returned as unvalidated, and not
as a validation error.
Signed-off-by: DL6ER <dl6er@dl6er.de>
Use CryptoPro version of the hash function.
Handle the little-endian wire format of key data.
Get the wire order of S and R correct.
Note that Nettle version 3.6 or later is required for GOST support.
Signed-off-by: DL6ER <dl6er@dl6er.de>
This fixes a confusion if certain algorithms are not supported
because the version is the crypto library is too old. The validation
should be treated the same as for a completely unknown algorithm,
(ie return unverified answer) and not as a validation failure
(ie return SERVFAIL).
The algorithems affected are GOST and ED448.
Signed-off-by: DL6ER <dl6er@dl6er.de>
Also Dbus SetDomainServers method.
Revert getaddrinfo hints.ai_socktype to SOCK_DGRAM to eliminate
duplicating every address three times for DGRAM, STREAM and RAW
in the results.
Signed-off-by: DL6ER <dl6er@dl6er.de>
Saying we've "flushed x outdated entries" is confusing, since
the count is the total number of entries in the modified file,
most of which are going to get added straight back when the file
is re-read.
The log now looks like
dnsmasq: inotify: /tmp/dir/1 (new or modified)
dnsmasq: inotify: flushed 1 addresses read from /tmp/dir/1
dnsmasq: read /tmp/dir/1 - 2 addresses
which hopefully make it more obvious that /tmp/dir/1 contained one
address before, and now contains two.
Signed-off-by: Dominik Derigs <dl6er@dl6er.de>
1) Cosmetic: don't log the tags twice.
2) Functional. If a host has an old lease for a different address,
the rapid-commit will appear to work, but the old lease will
not be removed and the new lease will not be recorded, so
the client and server will have conflicting state, leading to
problems later.
Signed-off-by: Dominik Derigs <dl6er@dl6er.de>
A bug, introduced in 2.87, which could result in DNS
servers being removed from the configuration when reloading
server configuration from DBus, or re-reading /etc/resolv.conf
Only servers from the same source should be replaced, but some
servers from other sources (ie hard coded or another dynamic source)
could mysteriously disappear.
Signed-off-by: DL6ER <dl6er@dl6er.de>
The DBUS per-server stats method should combine the stats from
different records (for different domains) in the same way at the
logging code.
Signed-off-by: DL6ER <dl6er@dl6er.de>
No longer try and fail to open every port when the port range
is in complete use; go straight to re-using an existing socket.
Die at startup if port range is smaller than --port-limit, since
the code behaves badly in this case.
Signed-off-by: DL6ER <dl6er@dl6er.de>
1) It's expected to fail to bind a new source port when they
are scarce, suppress warning in log in this case.
2) Optimse bind_local when max_port - min_port is small. There's no
randomness in this case, so we try all possible source ports
rather than poking at random ones for an arbitrary number of tries.
3) In allocate_rfd() handle the case that all available source ports
are already open. In this case we need to pick an existing
socket/port to use, such that it has a different port from any we
already hold. This gives the required property that the set of ports
utilised by any given query is set by --port-limit and we don't
re-use any until we have port-limit different ones.
Signed-off-by: DL6ER <dl6er@dl6er.de>
This gives dnsmasq the ability to originate retries for upstream DNS
queries itself, rather than relying on the downstream client. This is
most useful when doing DNSSEC over unreliable upstream network. It
comes with some cost in memory usage and network bandwidth.
Signed-off-by: DL6ER <dl6er@dl6er.de>
By default, when sending a query via random ports to multiple upstream servers or
retrying a query dnsmasq will use a single random port for all the tries/retries.
This option allows a larger number of ports to be used, which can increase robustness
in certain network configurations. Note that increasing this to more than
two or three can have security and resource implications and should only
be done with understanding of those.
Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit resolves this by storing the PID of the SHM object creator in the settings object.
Each FTL instance reloads this shared memory instance now before performing any potentially dangerous operation and checks if the shared memory files on disk are still owned by this process. If this is not the case, we are in serious trouble and exit immediately.
This should allow the second instance (you could call it the "rightful owner" of the current existing SHM objects) a fairly good chance to never even notice this and continue to operate just fine.
Signed-off-by: DL6ER <dl6er@dl6er.de>
Sending the same query repeatedly to a dnsmasq instance which
doesn't get replies from upstream will eventually hit the
hard limit on frec_src structures and start gettin REFUSED
replies. This is OK, except that since the queries are no longer
being forwarded, an upstream server coming back doesn't reset the
situation. If there is any other traffic, frec allocation will
eventually delete the timed-out frec and get things moving again,
but that's not guaranteed.
To fix this we explicitly delete the frec once timed out in this case.
Thanks to Filip Jenicek for noticing and characterising this problem.
Signed-off-by: DL6ER <dl6er@dl6er.de>