A bug in gentoo linux https://bugs.gentoo.org/945183 reported that dnsmasq 2.90 fails to compile with GCC 15.
The issue is that while previous versions of GCC defaulted to the C17 standard and C23 could be selected with
"-std=c23" or "-std=gnu23", GCC 15 defaults to C23. In C23 incompatible pointer types are an error instead of
a warning, so the "int (*callback)()" incomplete prototypes cause errors.
For example, compiling dnsmasq 2.90 with gcc 14.2.1 and "-std=gnu23" fails with errors such as:
lease.c: In function `lease_find_interfaces':
lease.c:467:34: warning: passing argument 3 of `iface_enumerate' from incompatible pointer type [-Wincompatible-pointer-types[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wincompatible-pointer-types]]
467 | iface_enumerate(AF_INET, &now, find_interface_v4);
| ^~~~~~~~~~~~~~~~~
| |
| int (*)(struct in_addr, int, char *, struct in_addr, struct in_addr, void *)
In file included from lease.c:17:
dnsmasq.h:1662:50: note: expected `int (*)(void)' but argument is of type `int (*)(struct in_addr, int, char *, struct in_addr, struct in_addr, void *)'
1662 | int iface_enumerate(int family, void *parm, int (callback)());
| ~~~~~^~~~~~~~~~~
This patch uses a typedef'ed union of pointer types to get type checking of the pointers. If that's too complicated,
another way might be to use (void *) casts to disable type checking.
Also, some of the IPv6 callbacks had "int preferred, int valid" and some had
"unsigned int preferred, unsigned int valid". This patch changes them all to "unsigned int"
so they're the same and to avoid casting "u32" to "int", eg:
u32 preferred = 0xffffffff;
callback(..., (int)preferred, ...)
Even if those cast values aren't used in the callback, casting u32 to "int" feels bad, especially if "int" is 32 bits.
At startup, the leases file is read by lease_init(), and
in lease_init() undecorated hostnames are expanded into
FQDNs by adding the domain associated with the address
of the lease.
lease_init() happens relavtively early in the startup, party because
if it calls the dhcp-lease helper script, we don't want that to inherit
a load of sensitive file descriptors. This has implications if domains
are defined using the --domain=example.com,eth0 format since it's long
before we call enumerate_interfaces(), so get_domain fails for such domains.
The patch just moves the hostname expansion function to a seperate
subroutine that gets called later, after enumerate_interfaces().
Move few patters with whine_malloc, if (successful) copy+free, to a new
whine_realloc. It should do the same thing, but with a help from OS it
can avoid unnecessary copy and free if allocation of more data after
current data is possible.
Added few setting remanining space to 0, because realloc does not use
calloc like whine_malloc does. There is no advantage of zeroing what we
will immediately overwrite. Zero only remaining space.
We detected a performance issue on a dnsmasq running many dhcp sessions
(more than 10 000). At the end of the day, the server was only releasing
old DHCP leases but was consuming a lot of CPU.
It looks like curent dhcp pruning:
1) it's pruning old sessions (iterate on all current leases). It's
important to note that it's only pruning session expired since more
than one second
2) it's looking for next lease to expire (iterate on all current leases
again)
3) it launchs an alarm to catch next expiration found in step 2). This
value can be zero for leases just expired (but not pruned).
So, for a second, dnsmasq could fall in a "prune loop" by doing:
* Not pruning anything, since difftime() is not > 0
* Run alarm again with zero as argument
On a server with very large number of leases and releasing often
sessions, that can waste a very big CPU time.
Signed-off-by: Florent Fourcot <florent.fourcot@wifirst.fr>
There's no reason to stop reading the existing lease file
when dnsmasq is started and an invalid entry is found, it
can just be ignored. This was fallout from an Openstack
bug where the file was being written incorrectly with []
around IPv6 addresses.
- With nested prefixes reside on different interfaces of single host
(e.g., in 6to4, 2002::/16 on WAN and 2002:<IPv4>:<subnet>::/64 on LAN),
current matching mechanism might return the interface with shorter prefix
length instead of the longer one, if it appears later in the netlink message.
Signed-off-by: Lung-Pin Chang <changlp@cs.nctu.edu.tw>
Previously, if the DUID wasn't read from the lease-file or
script, a new one was created _after_ the helper process fork,
so for that first run, the script calls got an empty DUID.
Also, use a DUID_LL format DUID when there's no stable lease
storage, as well as when the RTC is broken. That has a chance of
evaluating to the same value on each startup.