Compare commits

...
Author SHA1 Message Date
Florian MargaineandClaude Opus 4.6 fc2286805f Preserve existing log file permissions when adding group-write bit.
Commit 1f8f78a49b ("Add root group writeable flag to log file")
introduced a fchmod() call in log_start() that resets the file mode
to a hardcoded value (0660), discarding any pre-existing permissions.
This broke our usage of dnsmasq where we create the log file with
specific permissions before starting dnsmasq in an LXC container
namespace, so that unprivileged users inside the container can read
the log. The hardcoded mode strips those permissions on startup.

Use the existing stat result to OR in S_IWGRP instead, equivalent
to chmod g+w, so that only the group-write bit is added without
disturbing other permission bits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-21 22:41:10 +01:00
Simon Kelley d158aeca75 Increase default limit on TCP handler processes from 20 to 30.
There's evidence that modern Chrome may need this. It has been 20
forever, and hardware inflation would support an increase.

https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2026q2/018450.html
2026-04-21 22:27:07 +01:00
Simon Kelley 36d081e374 Fix buffer overlow in log_query()
The addition of "(not supported)" to logs of DS and DNSKEY replies
overflows the buffer used to construct the string.

Re-arrange things to avoid this, and add checks to avoid the same  problem
if the logging calls change in the future.

Thanks to Yiwei Hou for finding this.

The problem exists is DNSSEC is enabled and query logging is also
enabled. The overwrite is of bounded length and the bytes
written are not in control of an attacker, so this is not considered
a likely remote-execution vector.
2026-04-21 22:14:41 +01:00
Toliak Purple 9eb0757da9 Fix crash with mal-formed config option.
Reproduction Steps. Both commands cause a segmentation fault:
```
dnsmasq --interface-name=,
dnsmasq --dynamic-host=,::,
```

Stack Trace (ASAN, v2.90)
```
==1817==ERROR: AddressSanitizer: SEGV on unknown address
0x000000000000 (pc 0x7f0203d22845 bp 0x7ffc3316b920 sp 0x7ffc3316b0a0
T0)
==1817==The signal is caused by a READ memory access.
==1817==Hint: address points to the zero page.
    #0 0x7f0203d22845 in __interceptor_strncmp
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:488
    #1 0x5563361feeb3 in iface_allowed /opt/dnsmasq/src/network.c:361
    #2 0x556336203aca in iface_allowed_v6 /opt/dnsmasq/src/network.c:622
    #3 0x55633625cc4c in iface_enumerate /opt/dnsmasq/src/netlink.c:291
    #4 0x55633620573c in enumerate_interfaces /opt/dnsmasq/src/network.c:836
    #5 0x55633615c3fe in main /opt/dnsmasq/src/dnsmasq.c:367
```

The fault occurs due to a null-pointer dereference in iface_allowed()
at line 361:
```
if (strncmp(label, int_name->intr, IF_NAMESIZE) == 0)      //// here
int_name->intr is NULL
```

That occurs due to a null-pointer assignment in the option.c at line 4856:
```
new->intr = opt_string_alloc(arg);               //// if arg is empty
string, the opt_string_alloc will return NULL
```
2026-04-21 21:49:35 +01:00
Simon Kelley 2d0e0c7a54 Tweak DHCPv6 replay decapsulation.
RFC 8415 doesn't exclude the possiblity that a relay-forward
message could contain _more_than_one relay-message option. The
existing code could, under certain circumstances, access freed
stack memory in this case.

Thanks to Dejan Alvadzijevic and his fuzzer for finding this
condition.

This patch fixes things so that dnsmasq does at least sensible
things with multiple relay-message options, and no longer
has the (remote) possibility of accessing dead memory.
2026-04-10 13:35:27 +01:00
Simon Kelley cfc2244c2a Bump copyrights to 2026. 2026-04-08 12:08:18 +01:00
49 changed files with 97 additions and 91 deletions

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
# dnsmasq is Copyright (c) 2000-2025 Simon Kelley # dnsmasq is Copyright (c) 2000-2026 Simon Kelley
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+18 -12
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -2331,7 +2331,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
return; return;
/* build query type string if requested */ /* build query type string if requested */
if (!(flags & (F_SERVER | F_IPSET | F_QUERY)) && type > 0) if (!(flags & (F_SERVER | F_IPSET | F_QUERY | F_KEYTAG | F_RR)) && type > 0)
arg = querystr(arg, type); arg = querystr(arg, type);
dest = arg; dest = arg;
@@ -2347,19 +2347,25 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
{ {
dest = daemon->addrbuff; dest = daemon->addrbuff;
if (flags & F_RR) if (flags & F_RR)
{ {
if (flags & F_KEYTAG) if (flags & F_KEYTAG)
dest = querystr(NULL, addr->rrblock.rrtype); dest = querystr(NULL, addr->rrblock.rrtype);
else else
dest = querystr(NULL, addr->rrdata.rrtype); dest = querystr(NULL, addr->rrdata.rrtype);
} }
else if (flags & F_KEYTAG) #ifdef HAVE_DNSSEC
sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest); else if (flags & F_KEYTAG)
{
snprintf(daemon->addrbuff, ADDRSTRLEN, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
if (type)
extra = " (not supported)";
}
#endif
else if (flags & F_RCODE) else if (flags & F_RCODE)
{ {
unsigned int rcode = addr->log.rcode; unsigned int rcode = addr->log.rcode;
if (rcode == SERVFAIL) if (rcode == SERVFAIL)
dest = "SERVFAIL"; dest = "SERVFAIL";
else if (rcode == REFUSED) else if (rcode == REFUSED)
+2 -2
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
*/ */
#define FTABSIZ 150 /* max number of outstanding requests (default) */ #define FTABSIZ 150 /* max number of outstanding requests (default) */
#define MAX_PROCS 20 /* default max no children for TCP requests */ #define MAX_PROCS 30 /* default max no children for TCP requests */
#define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */ #define CHILD_LIFETIME 150 /* secs 'till terminated (RFC1035 suggests > 120s) */
#define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */ #define TCP_MAX_QUERIES 100 /* Maximum number of queries per incoming TCP connection */
#define TCP_TIMEOUT 5 /* timeout waiting to connect to an upstream server - double this for answer */ #define TCP_TIMEOUT 5 /* timeout waiting to connect to an upstream server - double this for answer */
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+2 -2
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#define COPYRIGHT "Copyright (c) 2000-2025 Simon Kelley" #define COPYRIGHT "Copyright (c) 2000-2026 Simon Kelley"
/* We do defines that influence behavior of stdio.h, so complain /* We do defines that influence behavior of stdio.h, so complain
if included too early. */ if included too early. */
+3 -6
View File
@@ -1,5 +1,5 @@
/* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com> /* dnssec.c is Copyright (c) 2012 Giovanni Bajo <rasky@develer.com>
and Copyright (c) 2012-2025 Simon Kelley and Copyright (c) 2012-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -950,10 +950,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
a.log.keytag = keytag; a.log.keytag = keytag;
a.log.algo = algo; a.log.algo = algo;
if (algo_digest_name(algo)) log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu", !algo_digest_name(algo));
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu", 0);
else
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu (not supported)", 0);
} }
} }
@@ -1101,7 +1098,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
a.log.keytag = keytag; a.log.keytag = keytag;
a.log.algo = algo; a.log.algo = algo;
a.log.digest = digest; a.log.digest = digest;
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS for keytag %hu, algo %hu, digest %hu (not supported)", 0); log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS for keytag %hu, algo %hu, digest %hu", 1);
neg_ttl = ttl; neg_ttl = ttl;
} }
else if ((key = blockdata_alloc((char*)p, rdlen - 4))) else if ((key = blockdata_alloc((char*)p, rdlen - 4)))
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+2 -2
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -113,7 +113,7 @@ int log_start(struct passwd *ent_pw, int errfd)
struct stat ls; struct stat ls;
if (getgid() == 0 && fstat(log_fd, &ls) == 0 && ls.st_gid == 0 && if (getgid() == 0 && fstat(log_fd, &ls) == 0 && ls.st_gid == 0 &&
(ls.st_mode & S_IWGRP) == 0) (ls.st_mode & S_IWGRP) == 0)
(void)fchmod(log_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); (void)fchmod(log_fd, ls.st_mode | S_IWGRP);
if (fchown(log_fd, ent_pw->pw_uid, -1) != 0) if (fchown(log_fd, ent_pw->pw_uid, -1) != 0)
ret = errno; ret = errno;
} }
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+3 -2
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -4960,7 +4960,8 @@ err:
arg = NULL; /* provoke error below */ arg = NULL; /* provoke error below */
} }
if (!domain || !arg || !(new->name = canonicalise_opt(domain))) if (!domain || !arg || !new->intr ||
!(new->name = canonicalise_opt(domain)))
ret_err(option == LOPT_DYNHOST ? ret_err(option == LOPT_DYNHOST ?
_("bad dynamic host") : _("bad interface name")); _("bad dynamic host") : _("bad interface name"));
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+25 -23
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@ struct state {
int clid_len, ia_type, interface, hostname_auth, lease_allocate; int clid_len, ia_type, interface, hostname_auth, lease_allocate;
char *client_hostname, *hostname, *domain, *send_domain; char *client_hostname, *hostname, *domain, *send_domain;
struct dhcp_context *context; struct dhcp_context *context;
struct in6_addr *link_address, *fallback, *ll_addr, *ula_addr; struct in6_addr *relay_address, *fallback, *ll_addr, *ula_addr;
unsigned int xid, fqdn_flags, iaid; unsigned int xid, fqdn_flags, iaid;
char *iface_name; char *iface_name;
void *packet_options, *end; void *packet_options, *end;
@@ -34,7 +34,7 @@ struct state {
}; };
static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz, static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
struct in6_addr *client_addr, time_t now); struct in6_addr *client_addr, struct in6_addr *link_address, time_t now);
static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, time_t now); static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, time_t now);
static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts); static void log6_opts(int nest, unsigned int xid, void *start_opts, void *end_opts);
static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string); static void log6_packet(struct state *state, char *type, struct in6_addr *addr, char *string);
@@ -99,9 +99,8 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int multicast_dest, int
state.ula_addr = ula_addr; state.ula_addr = ula_addr;
state.mac_len = 0; state.mac_len = 0;
state.tags = NULL; state.tags = NULL;
state.link_address = NULL;
if (dhcp6_maybe_relay(&state, daemon->dhcp_packet.iov_base, sz, client_addr, NULL, now))
if (dhcp6_maybe_relay(&state, daemon->dhcp_packet.iov_base, sz, client_addr, now))
return msg_type == DHCP6RELAYFORW ? DHCPV6_SERVER_PORT : DHCPV6_CLIENT_PORT; return msg_type == DHCP6RELAYFORW ? DHCPV6_SERVER_PORT : DHCPV6_CLIENT_PORT;
return 0; return 0;
@@ -109,7 +108,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int multicast_dest, int
/* This cost me blood to write, it will probably cost you blood to understand - srk. */ /* This cost me blood to write, it will probably cost you blood to understand - srk. */
static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz, static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
struct in6_addr *client_addr, time_t now) struct in6_addr *client_addr, struct in6_addr *link_address, time_t now)
{ {
uint8_t *end = inbuff + sz; uint8_t *end = inbuff + sz;
uint8_t *opts = inbuff + 34; uint8_t *opts = inbuff + 34;
@@ -136,7 +135,7 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
link_address == NULL means there's no relay in use, so we try and find the client's link_address == NULL means there's no relay in use, so we try and find the client's
MAC address from the local ND cache. */ MAC address from the local ND cache. */
if (!state->link_address) if (!link_address)
get_client_mac(client_addr, state->interface, state->mac, &state->mac_len, &state->mac_type, now); get_client_mac(client_addr, state->interface, state->mac, &state->mac_len, &state->mac_type, now);
else else
{ {
@@ -144,9 +143,9 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
struct shared_network *share = NULL; struct shared_network *share = NULL;
state->context = NULL; state->context = NULL;
if (!IN6_IS_ADDR_LOOPBACK(state->link_address) && if (!IN6_IS_ADDR_LOOPBACK(link_address) &&
!IN6_IS_ADDR_LINKLOCAL(state->link_address) && !IN6_IS_ADDR_LINKLOCAL(link_address) &&
!IN6_IS_ADDR_MULTICAST(state->link_address)) !IN6_IS_ADDR_MULTICAST(link_address))
for (c = daemon->dhcp6; c; c = c->next) for (c = daemon->dhcp6; c; c = c->next)
{ {
for (share = daemon->shared_networks; share; share = share->next) for (share = daemon->shared_networks; share; share = share->next)
@@ -155,7 +154,7 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
continue; continue;
if (share->if_index != 0 || if (share->if_index != 0 ||
!IN6_ARE_ADDR_EQUAL(state->link_address, &share->match_addr6)) !IN6_ARE_ADDR_EQUAL(link_address, &share->match_addr6))
continue; continue;
if ((c->flags & CONTEXT_DHCP) && if ((c->flags & CONTEXT_DHCP) &&
@@ -168,8 +167,8 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
if (share || if (share ||
((c->flags & CONTEXT_DHCP) && ((c->flags & CONTEXT_DHCP) &&
!(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) && !(c->flags & (CONTEXT_TEMPLATE | CONTEXT_OLD)) &&
is_same_net6(state->link_address, &c->start6, c->prefix) && is_same_net6(link_address, &c->start6, c->prefix) &&
is_same_net6(state->link_address, &c->end6, c->prefix))) is_same_net6(link_address, &c->end6, c->prefix)))
{ {
c->preferred = c->valid = 0xffffffff; c->preferred = c->valid = 0xffffffff;
c->current = state->context; c->current = state->context;
@@ -179,7 +178,7 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
if (!state->context) if (!state->context)
{ {
inet_ntop(AF_INET6, state->link_address, daemon->addrbuff, ADDRSTRLEN); inet_ntop(AF_INET6, link_address, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_WARNING, my_syslog(MS_DHCP | LOG_WARNING,
_("no address range available for DHCPv6 request from relay at %s"), _("no address range available for DHCPv6 request from relay at %s"),
daemon->addrbuff); daemon->addrbuff);
@@ -194,6 +193,8 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
return 0; return 0;
} }
state->relay_address = link_address;
return dhcp6_no_relay(state, msg_type, inbuff, sz, now); return dhcp6_no_relay(state, msg_type, inbuff, sz, now);
} }
@@ -253,11 +254,12 @@ static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t
/* the packet data is unaligned, copy to aligned storage */ /* the packet data is unaligned, copy to aligned storage */
memcpy(&align, inbuff + 2, IN6ADDRSZ); memcpy(&align, inbuff + 2, IN6ADDRSZ);
/* RFC6221 para 4 says if link_address in encapulation
/* RFC6221 para 4 */ is zero, ignore it, and, by implication, use the link
if (!IN6_IS_ADDR_UNSPECIFIED(&align)) address of any enclosing encapsulation or, failing that
state->link_address = &align; of the arrival interface on the the server. */
if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr, now)) if (!dhcp6_maybe_relay(state, opt6_ptr(opt, 0), opt6_len(opt), client_addr,
IN6_IS_ADDR_UNSPECIFIED(&align) ? link_address : &align, now))
return 0; return 0;
} }
else else
@@ -1977,10 +1979,10 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
} }
} }
if (state->link_address) if (state->relay_address)
inet_ntop(AF_INET6, state->link_address, daemon->addrbuff, ADDRSTRLEN); inet_ntop(AF_INET6, state->relay_address, daemon->addrbuff, ADDRSTRLEN);
lease_add_extradata(lease, (unsigned char *)daemon->addrbuff, state->link_address ? strlen(daemon->addrbuff) : 0, 0); lease_add_extradata(lease, (unsigned char *)daemon->addrbuff, state->relay_address ? strlen(daemon->addrbuff) : 0, 0);
if ((opt = opt6_find(state->packet_options, state->end, OPTION6_USER_CLASS, 2))) if ((opt = opt6_find(state->packet_options, state->end, OPTION6_USER_CLASS, 2)))
{ {
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
+1 -1
View File
@@ -1,4 +1,4 @@
/* dnsmasq is Copyright (c) 2000-2025 Simon Kelley /* dnsmasq is Copyright (c) 2000-2026 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by