Compare commits
No commits in common. 'i10cs' and 'c9' have entirely different histories.
@ -1 +1 @@
|
|||||||
864374a3e573d4997753b34290d50072463570c9 SOURCES/dnsmasq-2.90.tar.xz
|
256ec628587ab2b20bba3fc2773046dab8f2874c SOURCES/dnsmasq-2.85.tar.xz
|
||||||
|
@ -1 +1 @@
|
|||||||
SOURCES/dnsmasq-2.90.tar.xz
|
SOURCES/dnsmasq-2.85.tar.xz
|
||||||
|
@ -0,0 +1,99 @@
|
|||||||
|
From b027daaa8ef168122a712e5e4ec71642964d8f4d Mon Sep 17 00:00:00 2001
|
||||||
|
From: rpm-build <rpm-build>
|
||||||
|
Date: Mon, 22 Aug 2022 21:59:42 +0200
|
||||||
|
Subject: [PATCH] Ensure also server_domains_cleanup is called always
|
||||||
|
|
||||||
|
Fixes issue in patch dnsmasq-2.79-server-domain-rh1919894.patch.
|
||||||
|
|
||||||
|
When /etc/resolv.conf is changed, dnsmasq reloads used servers. But it
|
||||||
|
does not call cleanup of server domains in this case. It might cause
|
||||||
|
serv_domain->last_server to become non-null, but pointing released
|
||||||
|
server. Ensure it is checked before any cleanup_servers() action always
|
||||||
|
and from all other places, like dbus setting.
|
||||||
|
|
||||||
|
Caused unending loop in forward_query function, rhbz#2106361.
|
||||||
|
---
|
||||||
|
src/network.c | 49 +++++++++++++++++++++++++------------------------
|
||||||
|
1 file changed, 25 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/network.c b/src/network.c
|
||||||
|
index 1fa81ff..cf2f2e2 100644
|
||||||
|
--- a/src/network.c
|
||||||
|
+++ b/src/network.c
|
||||||
|
@@ -1511,10 +1511,35 @@ void mark_servers(int flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void server_domains_cleanup(void)
|
||||||
|
+{
|
||||||
|
+ struct server_domain *sd, *tmp, **up;
|
||||||
|
+
|
||||||
|
+ /* unlink and free anything still marked. */
|
||||||
|
+ for (up = &daemon->server_domains, sd=*up; sd; sd = tmp)
|
||||||
|
+ {
|
||||||
|
+ tmp = sd->next;
|
||||||
|
+ if (sd->flags & SERV_MARK)
|
||||||
|
+ {
|
||||||
|
+ *up = sd->next;
|
||||||
|
+ if (sd->domain)
|
||||||
|
+ free(sd->domain);
|
||||||
|
+ free(sd);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ up = &sd->next;
|
||||||
|
+ if (sd->last_server && (sd->last_server->flags & SERV_MARK))
|
||||||
|
+ sd->last_server = NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void cleanup_servers(void)
|
||||||
|
{
|
||||||
|
struct server *serv, *tmp, **up;
|
||||||
|
|
||||||
|
+ server_domains_cleanup();
|
||||||
|
+
|
||||||
|
/* unlink and free anything still marked. */
|
||||||
|
for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
|
||||||
|
{
|
||||||
|
@@ -1537,29 +1562,6 @@ void cleanup_servers(void)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void server_domains_cleanup(void)
|
||||||
|
-{
|
||||||
|
- struct server_domain *sd, *tmp, **up;
|
||||||
|
-
|
||||||
|
- /* unlink and free anything still marked. */
|
||||||
|
- for (up = &daemon->server_domains, sd=*up; sd; sd = tmp)
|
||||||
|
- {
|
||||||
|
- tmp = sd->next;
|
||||||
|
- if (sd->flags & SERV_MARK)
|
||||||
|
- {
|
||||||
|
- *up = sd->next;
|
||||||
|
- if (sd->domain)
|
||||||
|
- free(sd->domain);
|
||||||
|
- free(sd);
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- up = &sd->next;
|
||||||
|
- if (sd->last_server && (sd->last_server->flags & SERV_MARK))
|
||||||
|
- sd->last_server = NULL;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
void add_update_server(int flags,
|
||||||
|
union mysockaddr *addr,
|
||||||
|
union mysockaddr *source_addr,
|
||||||
|
@@ -1849,7 +1851,6 @@ void check_servers(void)
|
||||||
|
up = &sfd->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
- server_domains_cleanup();
|
||||||
|
cleanup_servers();
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.37.2
|
||||||
|
|
@ -0,0 +1,471 @@
|
|||||||
|
From 5747d7b3dffdcd45d4410bb380e466818734cb27 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Mon, 19 Apr 2021 13:56:23 +0200
|
||||||
|
Subject: [PATCH] Use load-balancing also for --server=/domains/
|
||||||
|
|
||||||
|
Do not (yet) move servers to server_domain structure. Instead use
|
||||||
|
separate server_domains to store just last_server and requests count and
|
||||||
|
time.
|
||||||
|
|
||||||
|
Introduces domain information duplicity, but minimizes required changes
|
||||||
|
to daemon->servers usage.
|
||||||
|
|
||||||
|
Optimize server domain record
|
||||||
|
|
||||||
|
Set pointer to domain record when struct server is created. When
|
||||||
|
searching for domain pointer, use this pointer to make it quick.
|
||||||
|
---
|
||||||
|
src/dnsmasq.h | 18 +++++++--
|
||||||
|
src/forward.c | 52 ++++++++++++++++----------
|
||||||
|
src/network.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
src/option.c | 5 +++
|
||||||
|
4 files changed, 146 insertions(+), 30 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
||||||
|
index 1e21005..b6dcc50 100644
|
||||||
|
--- a/src/dnsmasq.h
|
||||||
|
+++ b/src/dnsmasq.h
|
||||||
|
@@ -559,6 +559,17 @@ struct randfd_list {
|
||||||
|
struct randfd_list *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
+/* contains domain specific set of servers.
|
||||||
|
+ * If domain is NULL, just normal servers. */
|
||||||
|
+struct server_domain {
|
||||||
|
+ char *domain;
|
||||||
|
+ struct server *last_server;
|
||||||
|
+ time_t forwardtime;
|
||||||
|
+ int forwardcount;
|
||||||
|
+ unsigned int flags; /* server.flags alternative */
|
||||||
|
+ struct server_domain *next;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
struct server {
|
||||||
|
union mysockaddr addr, source_addr;
|
||||||
|
char interface[IF_NAMESIZE+1];
|
||||||
|
@@ -571,6 +582,7 @@ struct server {
|
||||||
|
#ifdef HAVE_LOOP
|
||||||
|
u32 uid;
|
||||||
|
#endif
|
||||||
|
+ struct server_domain *serv_domain;
|
||||||
|
struct server *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -1053,6 +1065,7 @@ extern struct daemon {
|
||||||
|
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
|
||||||
|
struct bogus_addr *bogus_addr, *ignore_addr;
|
||||||
|
struct server *servers;
|
||||||
|
+ struct server_domain *server_domains;
|
||||||
|
struct ipsets *ipsets;
|
||||||
|
int log_fac; /* log facility */
|
||||||
|
char *log_file; /* optional log file */
|
||||||
|
@@ -1121,9 +1134,6 @@ extern struct daemon {
|
||||||
|
struct serverfd *sfds;
|
||||||
|
struct irec *interfaces;
|
||||||
|
struct listener *listeners;
|
||||||
|
- struct server *last_server;
|
||||||
|
- time_t forwardtime;
|
||||||
|
- int forwardcount;
|
||||||
|
struct server *srv_save; /* Used for resend on DoD */
|
||||||
|
size_t packet_len; /* " " */
|
||||||
|
int fd_save; /* " " */
|
||||||
|
@@ -1394,6 +1404,8 @@ int label_exception(int index, int family, union all_addr *addr);
|
||||||
|
int fix_fd(int fd);
|
||||||
|
int tcp_interface(int fd, int af);
|
||||||
|
int set_ipv6pktinfo(int fd);
|
||||||
|
+struct server_domain *server_domain_find_domain(const char *domain);
|
||||||
|
+struct server_domain *server_domain_new(struct server *serv);
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
void join_multicast(int dienow);
|
||||||
|
#endif
|
||||||
|
diff --git a/src/forward.c b/src/forward.c
|
||||||
|
index 9322b6a..b09dc96 100644
|
||||||
|
--- a/src/forward.c
|
||||||
|
+++ b/src/forward.c
|
||||||
|
@@ -107,7 +107,8 @@ int send_from(int fd, int nowild, char *packet, size_t len,
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned int qtype,
|
||||||
|
- char *qdomain, int *type, char **domain, int *norebind)
|
||||||
|
+ char *qdomain, int *type, char **domain, int *norebind,
|
||||||
|
+ struct server_domain **serv_domain)
|
||||||
|
|
||||||
|
{
|
||||||
|
/* If the query ends in the domain in one of our servers, set
|
||||||
|
@@ -120,6 +121,9 @@ static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned
|
||||||
|
unsigned int flags = 0;
|
||||||
|
static union all_addr zero;
|
||||||
|
|
||||||
|
+ if (serv_domain)
|
||||||
|
+ *serv_domain = NULL;
|
||||||
|
+
|
||||||
|
for (serv = daemon->servers; serv; serv=serv->next)
|
||||||
|
if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC))
|
||||||
|
continue;
|
||||||
|
@@ -187,6 +191,8 @@ static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned
|
||||||
|
{
|
||||||
|
*type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_DO_DNSSEC);
|
||||||
|
*domain = serv->domain;
|
||||||
|
+ if (serv_domain)
|
||||||
|
+ *serv_domain = serv->serv_domain;
|
||||||
|
matchlen = domainlen;
|
||||||
|
if (serv->flags & SERV_NO_ADDR)
|
||||||
|
flags = F_NXDOMAIN;
|
||||||
|
@@ -243,6 +249,8 @@ static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned
|
||||||
|
*type = 0; /* use normal servers for this domain */
|
||||||
|
*domain = NULL;
|
||||||
|
}
|
||||||
|
+ if (serv_domain && !*serv_domain)
|
||||||
|
+ *serv_domain = server_domain_find_domain(*domain);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -304,6 +312,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||||
|
unsigned int flags = 0;
|
||||||
|
unsigned int fwd_flags = 0;
|
||||||
|
struct server *start = NULL;
|
||||||
|
+ struct server_domain *sd = NULL;
|
||||||
|
void *hash = hash_questions(header, plen, daemon->namebuff);
|
||||||
|
#ifdef HAVE_DNSSEC
|
||||||
|
int do_dnssec = 0;
|
||||||
|
@@ -422,8 +431,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||||
|
forward->sentto->failed_queries++;
|
||||||
|
if (!option_bool(OPT_ORDER) && old_src)
|
||||||
|
{
|
||||||
|
+ sd = forward->sentto->serv_domain;
|
||||||
|
forward->forwardall = 1;
|
||||||
|
- daemon->last_server = NULL;
|
||||||
|
+ if (sd)
|
||||||
|
+ sd->last_server = NULL;
|
||||||
|
}
|
||||||
|
type = forward->sentto->flags & SERV_TYPE;
|
||||||
|
#ifdef HAVE_DNSSEC
|
||||||
|
@@ -439,8 +450,8 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||||
|
/* new query */
|
||||||
|
|
||||||
|
if (gotname)
|
||||||
|
- flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
|
||||||
|
-
|
||||||
|
+ flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind, &sd);
|
||||||
|
+
|
||||||
|
#ifdef HAVE_DNSSEC
|
||||||
|
do_dnssec = type & SERV_DO_DNSSEC;
|
||||||
|
#endif
|
||||||
|
@@ -482,18 +493,18 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||||
|
always try all the available servers,
|
||||||
|
otherwise, use the one last known to work. */
|
||||||
|
|
||||||
|
- if (type == 0)
|
||||||
|
+ if (sd)
|
||||||
|
{
|
||||||
|
if (option_bool(OPT_ORDER))
|
||||||
|
start = daemon->servers;
|
||||||
|
- else if (!(start = daemon->last_server) ||
|
||||||
|
- daemon->forwardcount++ > FORWARD_TEST ||
|
||||||
|
- difftime(now, daemon->forwardtime) > FORWARD_TIME)
|
||||||
|
+ else if (!(start = sd->last_server) ||
|
||||||
|
+ sd->forwardcount++ > FORWARD_TEST ||
|
||||||
|
+ difftime(now, sd->forwardtime) > FORWARD_TIME)
|
||||||
|
{
|
||||||
|
start = daemon->servers;
|
||||||
|
forward->forwardall = 1;
|
||||||
|
- daemon->forwardcount = 0;
|
||||||
|
- daemon->forwardtime = now;
|
||||||
|
+ sd->forwardcount = 0;
|
||||||
|
+ sd->forwardtime = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
@@ -844,6 +855,7 @@ void reply_query(int fd, time_t now)
|
||||||
|
size_t nn;
|
||||||
|
struct server *server;
|
||||||
|
void *hash;
|
||||||
|
+ struct server_domain *sd;
|
||||||
|
|
||||||
|
/* packet buffer overwritten */
|
||||||
|
daemon->srv_save = NULL;
|
||||||
|
@@ -968,7 +980,8 @@ void reply_query(int fd, time_t now)
|
||||||
|
}
|
||||||
|
|
||||||
|
server = forward->sentto;
|
||||||
|
- if ((forward->sentto->flags & SERV_TYPE) == 0)
|
||||||
|
+ sd = server->serv_domain;
|
||||||
|
+ if (sd)
|
||||||
|
{
|
||||||
|
if (RCODE(header) == REFUSED)
|
||||||
|
server = NULL;
|
||||||
|
@@ -986,7 +999,7 @@ void reply_query(int fd, time_t now)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!option_bool(OPT_ALL_SERVERS))
|
||||||
|
- daemon->last_server = server;
|
||||||
|
+ sd->last_server = server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We tried resending to this server with a smaller maximum size and got an answer.
|
||||||
|
@@ -1093,7 +1106,7 @@ void reply_query(int fd, time_t now)
|
||||||
|
/* Find server to forward to. This will normally be the
|
||||||
|
same as for the original query, but may be another if
|
||||||
|
servers for domains are involved. */
|
||||||
|
- if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL) == 0)
|
||||||
|
+ if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL, &sd) == 0)
|
||||||
|
{
|
||||||
|
struct server *start, *new_server = NULL;
|
||||||
|
start = server = forward->sentto;
|
||||||
|
@@ -1664,7 +1677,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
||||||
|
/* Find server to forward to. This will normally be the
|
||||||
|
same as for the original query, but may be another if
|
||||||
|
servers for domains are involved. */
|
||||||
|
- if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL) != 0)
|
||||||
|
+ if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL, NULL) != 0)
|
||||||
|
{
|
||||||
|
new_status = STAT_ABANDONED;
|
||||||
|
break;
|
||||||
|
@@ -1944,12 +1957,13 @@ unsigned char *tcp_request(int confd, time_t now,
|
||||||
|
union all_addr *addrp = NULL;
|
||||||
|
int type = SERV_DO_DNSSEC;
|
||||||
|
char *domain = NULL;
|
||||||
|
+ struct server_domain *sd = NULL;
|
||||||
|
unsigned char *oph = find_pseudoheader(header, size, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet, &cacheable);
|
||||||
|
|
||||||
|
if (gotname)
|
||||||
|
- flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
|
||||||
|
+ flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind, &sd);
|
||||||
|
|
||||||
|
#ifdef HAVE_DNSSEC
|
||||||
|
if (option_bool(OPT_DNSSEC_VALID) && (type & SERV_DO_DNSSEC))
|
||||||
|
@@ -1970,10 +1984,10 @@ unsigned char *tcp_request(int confd, time_t now,
|
||||||
|
|
||||||
|
type &= ~SERV_DO_DNSSEC;
|
||||||
|
|
||||||
|
- if (type != 0 || option_bool(OPT_ORDER) || !daemon->last_server)
|
||||||
|
+ if (!sd || option_bool(OPT_ORDER) || !sd->last_server)
|
||||||
|
last_server = daemon->servers;
|
||||||
|
else
|
||||||
|
- last_server = daemon->last_server;
|
||||||
|
+ last_server = sd->last_server;
|
||||||
|
|
||||||
|
if (!flags && last_server)
|
||||||
|
{
|
||||||
|
@@ -2567,9 +2581,7 @@ void server_gone(struct server *server)
|
||||||
|
if (daemon->randomsocks[i].refcount != 0 && daemon->randomsocks[i].serv == server)
|
||||||
|
daemon->randomsocks[i].serv = NULL;
|
||||||
|
|
||||||
|
- if (daemon->last_server == server)
|
||||||
|
- daemon->last_server = NULL;
|
||||||
|
-
|
||||||
|
+ /* last_server cleared by server_domains_cleanup */
|
||||||
|
if (daemon->srv_save == server)
|
||||||
|
daemon->srv_save = NULL;
|
||||||
|
}
|
||||||
|
diff --git a/src/network.c b/src/network.c
|
||||||
|
index 3600250..1fa81ff 100644
|
||||||
|
--- a/src/network.c
|
||||||
|
+++ b/src/network.c
|
||||||
|
@@ -1537,6 +1537,29 @@ void cleanup_servers(void)
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void server_domains_cleanup(void)
|
||||||
|
+{
|
||||||
|
+ struct server_domain *sd, *tmp, **up;
|
||||||
|
+
|
||||||
|
+ /* unlink and free anything still marked. */
|
||||||
|
+ for (up = &daemon->server_domains, sd=*up; sd; sd = tmp)
|
||||||
|
+ {
|
||||||
|
+ tmp = sd->next;
|
||||||
|
+ if (sd->flags & SERV_MARK)
|
||||||
|
+ {
|
||||||
|
+ *up = sd->next;
|
||||||
|
+ if (sd->domain)
|
||||||
|
+ free(sd->domain);
|
||||||
|
+ free(sd);
|
||||||
|
+ }
|
||||||
|
+ else {
|
||||||
|
+ up = &sd->next;
|
||||||
|
+ if (sd->last_server && (sd->last_server->flags & SERV_MARK))
|
||||||
|
+ sd->last_server = NULL;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void add_update_server(int flags,
|
||||||
|
union mysockaddr *addr,
|
||||||
|
union mysockaddr *source_addr,
|
||||||
|
@@ -1616,10 +1639,72 @@ void add_update_server(int flags,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static const char *server_get_domain(const struct server *serv)
|
||||||
|
+{
|
||||||
|
+ const char *domain = serv->domain;
|
||||||
|
+
|
||||||
|
+ if (serv->flags & SERV_HAS_DOMAIN)
|
||||||
|
+ /* .example.com is valid */
|
||||||
|
+ while (*domain == '.')
|
||||||
|
+ domain++;
|
||||||
|
+
|
||||||
|
+ return domain;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+struct server_domain *server_domain_find_domain(const char *domain)
|
||||||
|
+{
|
||||||
|
+ struct server_domain *sd;
|
||||||
|
+ for (sd = daemon->server_domains; sd; sd = sd->next)
|
||||||
|
+ if ((!domain && sd->domain == domain) || (domain && sd->domain && hostname_isequal(domain, sd->domain)))
|
||||||
|
+ return sd;
|
||||||
|
+ return NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**< Test structure has already set domain pointer.
|
||||||
|
+ *
|
||||||
|
+ * If not, create a new record. */
|
||||||
|
+struct server_domain *server_domain_new(struct server *serv)
|
||||||
|
+{
|
||||||
|
+ struct server_domain *sd;
|
||||||
|
+
|
||||||
|
+ if ((sd = whine_malloc(sizeof(struct server_domain))))
|
||||||
|
+ {
|
||||||
|
+ const char *domain = server_get_domain(serv);
|
||||||
|
+
|
||||||
|
+ /* Ensure all serv->domain values have own record in server_domain.
|
||||||
|
+ * Add a new record. */
|
||||||
|
+ if (domain)
|
||||||
|
+ {
|
||||||
|
+ size_t len = strlen(domain)+1;
|
||||||
|
+ sd->domain = whine_malloc(len);
|
||||||
|
+ if (sd->domain)
|
||||||
|
+ memcpy(sd->domain, domain, len);
|
||||||
|
+ }
|
||||||
|
+ sd->next = daemon->server_domains;
|
||||||
|
+ serv->serv_domain = sd;
|
||||||
|
+ daemon->server_domains = sd;
|
||||||
|
+ }
|
||||||
|
+ return sd;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/**< Test structure has already set domain pointer.
|
||||||
|
+ *
|
||||||
|
+ * If not, create a new record. */
|
||||||
|
+static void server_domain_check(struct server *serv)
|
||||||
|
+{
|
||||||
|
+ struct server_domain *sd = serv->serv_domain;
|
||||||
|
+
|
||||||
|
+ if (sd)
|
||||||
|
+ sd->flags &= (~SERV_MARK); /* found domain, mark active */
|
||||||
|
+ else
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void check_servers(void)
|
||||||
|
{
|
||||||
|
struct irec *iface;
|
||||||
|
struct server *serv;
|
||||||
|
+ struct server_domain *sd;
|
||||||
|
struct serverfd *sfd, *tmp, **up;
|
||||||
|
int port = 0, count;
|
||||||
|
int locals = 0;
|
||||||
|
@@ -1632,10 +1717,14 @@ void check_servers(void)
|
||||||
|
for (sfd = daemon->sfds; sfd; sfd = sfd->next)
|
||||||
|
sfd->used = sfd->preallocated;
|
||||||
|
|
||||||
|
+ for (sd = daemon->server_domains; sd; sd = sd->next)
|
||||||
|
+ sd->flags |= SERV_MARK;
|
||||||
|
+
|
||||||
|
for (count = 0, serv = daemon->servers; serv; serv = serv->next)
|
||||||
|
{
|
||||||
|
if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
|
||||||
|
{
|
||||||
|
+
|
||||||
|
/* Init edns_pktsz for newly created server records. */
|
||||||
|
if (serv->edns_pktsz == 0)
|
||||||
|
serv->edns_pktsz = daemon->edns_pktsz;
|
||||||
|
@@ -1651,12 +1740,8 @@ void check_servers(void)
|
||||||
|
if (serv->flags & SERV_HAS_DOMAIN)
|
||||||
|
{
|
||||||
|
struct ds_config *ds;
|
||||||
|
- char *domain = serv->domain;
|
||||||
|
-
|
||||||
|
- /* .example.com is valid */
|
||||||
|
- while (*domain == '.')
|
||||||
|
- domain++;
|
||||||
|
-
|
||||||
|
+ const char *domain = server_get_domain(serv);
|
||||||
|
+
|
||||||
|
for (ds = daemon->ds; ds; ds = ds->next)
|
||||||
|
if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
|
||||||
|
break;
|
||||||
|
@@ -1666,7 +1751,6 @@ void check_servers(void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
-
|
||||||
|
port = prettyprint_addr(&serv->addr, daemon->namebuff);
|
||||||
|
|
||||||
|
/* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
|
||||||
|
@@ -1701,6 +1785,8 @@ void check_servers(void)
|
||||||
|
|
||||||
|
if (serv->sfd)
|
||||||
|
serv->sfd->used = 1;
|
||||||
|
+
|
||||||
|
+ server_domain_check(serv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
|
||||||
|
@@ -1763,6 +1849,7 @@ void check_servers(void)
|
||||||
|
up = &sfd->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ server_domains_cleanup();
|
||||||
|
cleanup_servers();
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/option.c b/src/option.c
|
||||||
|
index 6de5914..e4e3182 100644
|
||||||
|
--- a/src/option.c
|
||||||
|
+++ b/src/option.c
|
||||||
|
@@ -928,6 +928,7 @@ static struct server *add_rev4(struct in_addr addr, int msize)
|
||||||
|
p += sprintf(p, "in-addr.arpa");
|
||||||
|
|
||||||
|
serv->flags = SERV_HAS_DOMAIN;
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
|
||||||
|
@@ -952,6 +953,7 @@ static struct server *add_rev6(struct in6_addr *addr, int msize)
|
||||||
|
p += sprintf(p, "ip6.arpa");
|
||||||
|
|
||||||
|
serv->flags = SERV_HAS_DOMAIN;
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
|
||||||
|
@@ -2292,6 +2294,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
memset(serv, 0, sizeof(struct server));
|
||||||
|
serv->domain = d;
|
||||||
|
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
}
|
||||||
|
@@ -2335,6 +2338,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
memset(serv, 0, sizeof(struct server));
|
||||||
|
serv->domain = d;
|
||||||
|
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
}
|
||||||
|
@@ -2587,6 +2591,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
newlist = serv;
|
||||||
|
serv->domain = domain;
|
||||||
|
serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
arg = end;
|
||||||
|
if (rebind)
|
||||||
|
break;
|
||||||
|
--
|
||||||
|
2.34.1
|
||||||
|
|
@ -0,0 +1,106 @@
|
|||||||
|
From e046f32d882b6acf2090cbe8830c2dea6279aa8e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Fri, 9 Jun 2023 22:11:01 +0200
|
||||||
|
Subject: [PATCH] Use serv_domain only for regular servers
|
||||||
|
|
||||||
|
Do not try to use it for --local=/x/ or --address=/x/#. Some users use
|
||||||
|
quite long list of blocks, which slows down walking trough domain list
|
||||||
|
considerably. But searching by server_domain_find_domain is needed only
|
||||||
|
for normal servers, which may store there last used server and number
|
||||||
|
of recent forwarded queries. Local addresses overrides store there no
|
||||||
|
useful information, avoid searching and adding new domains for such
|
||||||
|
records.
|
||||||
|
|
||||||
|
Would also speed up searching servers when blocklists are used, because
|
||||||
|
only domains of servers are tested.
|
||||||
|
|
||||||
|
Resolves: rhbz#2209031
|
||||||
|
---
|
||||||
|
src/forward.c | 2 +-
|
||||||
|
src/option.c | 15 +++++++++------
|
||||||
|
2 files changed, 10 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/forward.c b/src/forward.c
|
||||||
|
index fffab7a..3d1227b 100644
|
||||||
|
--- a/src/forward.c
|
||||||
|
+++ b/src/forward.c
|
||||||
|
@@ -249,7 +249,7 @@ static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned
|
||||||
|
*type = 0; /* use normal servers for this domain */
|
||||||
|
*domain = NULL;
|
||||||
|
}
|
||||||
|
- if (serv_domain && !*serv_domain)
|
||||||
|
+ if (serv_domain && !*serv_domain && (*type & SERV_HAS_DOMAIN)==0)
|
||||||
|
*serv_domain = server_domain_find_domain(NULL);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
diff --git a/src/option.c b/src/option.c
|
||||||
|
index e4e3182..25680c0 100644
|
||||||
|
--- a/src/option.c
|
||||||
|
+++ b/src/option.c
|
||||||
|
@@ -928,7 +928,7 @@ static struct server *add_rev4(struct in_addr addr, int msize)
|
||||||
|
p += sprintf(p, "in-addr.arpa");
|
||||||
|
|
||||||
|
serv->flags = SERV_HAS_DOMAIN;
|
||||||
|
- server_domain_new(serv);
|
||||||
|
+ serv->serv_domain = NULL;
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
|
||||||
|
@@ -953,7 +953,7 @@ static struct server *add_rev6(struct in6_addr *addr, int msize)
|
||||||
|
p += sprintf(p, "ip6.arpa");
|
||||||
|
|
||||||
|
serv->flags = SERV_HAS_DOMAIN;
|
||||||
|
- server_domain_new(serv);
|
||||||
|
+ serv->serv_domain = NULL;
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
|
||||||
|
@@ -2294,7 +2294,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
memset(serv, 0, sizeof(struct server));
|
||||||
|
serv->domain = d;
|
||||||
|
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
|
||||||
|
- server_domain_new(serv);
|
||||||
|
+ serv->serv_domain = NULL;
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
}
|
||||||
|
@@ -2338,7 +2338,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
memset(serv, 0, sizeof(struct server));
|
||||||
|
serv->domain = d;
|
||||||
|
serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
|
||||||
|
- server_domain_new(serv);
|
||||||
|
+ serv->serv_domain = NULL;
|
||||||
|
serv->next = daemon->servers;
|
||||||
|
daemon->servers = serv;
|
||||||
|
}
|
||||||
|
@@ -2591,7 +2591,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
newlist = serv;
|
||||||
|
serv->domain = domain;
|
||||||
|
serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
|
||||||
|
- server_domain_new(serv);
|
||||||
|
+ serv->serv_domain = NULL;
|
||||||
|
arg = end;
|
||||||
|
if (rebind)
|
||||||
|
break;
|
||||||
|
@@ -2639,6 +2639,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
server_list_free(newlist);
|
||||||
|
ret_err(err);
|
||||||
|
}
|
||||||
|
+ if ((newlist->flags & SERV_LITERAL_ADDRESS)==0)
|
||||||
|
+ server_domain_new(newlist);
|
||||||
|
}
|
||||||
|
|
||||||
|
serv = newlist;
|
||||||
|
@@ -2682,7 +2684,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||||
|
serv = add_rev6(&addr6, size);
|
||||||
|
else
|
||||||
|
ret_err(gen_err);
|
||||||
|
-
|
||||||
|
+
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
string = parse_server(comma, &serv->addr, &serv->source_addr, serv->interface, &serv->flags);
|
||||||
|
|
||||||
|
if (string)
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,50 @@
|
|||||||
|
From d75a9691edaa2b2efd8b51f2de492c62cb57c629 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Fri, 5 May 2023 17:51:56 +0200
|
||||||
|
Subject: [PATCH] Ensure search_servers domain is set on dnssec
|
||||||
|
|
||||||
|
When dnssec validation is enabled the domain variable used when fetching
|
||||||
|
dnssec key or domain were not properly initialized always. It were read
|
||||||
|
anyway inside search_servers. Because it is changed only sometime, do
|
||||||
|
not use its value on the end of function. domain can be NULL only at
|
||||||
|
that point, use that value right away.
|
||||||
|
|
||||||
|
Include also TCP.
|
||||||
|
---
|
||||||
|
src/forward.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/forward.c b/src/forward.c
|
||||||
|
index b09dc96..fffab7a 100644
|
||||||
|
--- a/src/forward.c
|
||||||
|
+++ b/src/forward.c
|
||||||
|
@@ -250,7 +250,7 @@ static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned
|
||||||
|
*domain = NULL;
|
||||||
|
}
|
||||||
|
if (serv_domain && !*serv_domain)
|
||||||
|
- *serv_domain = server_domain_find_domain(*domain);
|
||||||
|
+ *serv_domain = server_domain_find_domain(NULL);
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1097,7 +1097,7 @@ void reply_query(int fd, time_t now)
|
||||||
|
{
|
||||||
|
int querytype, fd, type = SERV_DO_DNSSEC;
|
||||||
|
struct frec *next = new->next;
|
||||||
|
- char *domain;
|
||||||
|
+ char *domain = NULL;
|
||||||
|
|
||||||
|
*new = *forward; /* copy everything, then overwrite */
|
||||||
|
new->next = next;
|
||||||
|
@@ -1633,7 +1633,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int type = SERV_DO_DNSSEC;
|
||||||
|
- char *domain;
|
||||||
|
+ char *domain = NULL;
|
||||||
|
size_t m;
|
||||||
|
unsigned char c1, c2;
|
||||||
|
struct server *firstsendto = NULL;
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,83 @@
|
|||||||
|
From 4650d0aef20db4b7e129895ffcb93ca4609e6347 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Wed, 10 May 2023 12:57:17 +0200
|
||||||
|
Subject: [PATCH] fixup! Correct releasing of serv_domain
|
||||||
|
|
||||||
|
---
|
||||||
|
src/dnsmasq.h | 2 +-
|
||||||
|
src/network.c | 20 +++++++++++---------
|
||||||
|
2 files changed, 12 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
||||||
|
index b6dcc50..c62c3d0 100644
|
||||||
|
--- a/src/dnsmasq.h
|
||||||
|
+++ b/src/dnsmasq.h
|
||||||
|
@@ -1405,7 +1405,7 @@ int fix_fd(int fd);
|
||||||
|
int tcp_interface(int fd, int af);
|
||||||
|
int set_ipv6pktinfo(int fd);
|
||||||
|
struct server_domain *server_domain_find_domain(const char *domain);
|
||||||
|
-struct server_domain *server_domain_new(struct server *serv);
|
||||||
|
+void server_domain_new(struct server *serv);
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
void join_multicast(int dienow);
|
||||||
|
#endif
|
||||||
|
diff --git a/src/network.c b/src/network.c
|
||||||
|
index 8152cac..e42220c 100644
|
||||||
|
--- a/src/network.c
|
||||||
|
+++ b/src/network.c
|
||||||
|
@@ -1653,6 +1653,7 @@ void add_update_server(int flags,
|
||||||
|
serv->addr = *addr;
|
||||||
|
if (source_addr)
|
||||||
|
serv->source_addr = *source_addr;
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1680,14 +1681,20 @@ struct server_domain *server_domain_find_domain(const char *domain)
|
||||||
|
/**< Test structure has already set domain pointer.
|
||||||
|
*
|
||||||
|
* If not, create a new record. */
|
||||||
|
-struct server_domain *server_domain_new(struct server *serv)
|
||||||
|
+void server_domain_new(struct server *serv)
|
||||||
|
{
|
||||||
|
struct server_domain *sd;
|
||||||
|
+ const char *domain = server_get_domain(serv);
|
||||||
|
|
||||||
|
- if ((sd = whine_malloc(sizeof(struct server_domain))))
|
||||||
|
+ sd = server_domain_find_domain(domain);
|
||||||
|
+ if (sd)
|
||||||
|
{
|
||||||
|
- const char *domain = server_get_domain(serv);
|
||||||
|
+ serv->serv_domain = sd;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
+ if ((sd = whine_malloc(sizeof(struct server_domain))))
|
||||||
|
+ {
|
||||||
|
/* Ensure all serv->domain values have own record in server_domain.
|
||||||
|
* Add a new record. */
|
||||||
|
if (domain)
|
||||||
|
@@ -1701,7 +1708,6 @@ struct server_domain *server_domain_new(struct server *serv)
|
||||||
|
serv->serv_domain = sd;
|
||||||
|
daemon->server_domains = sd;
|
||||||
|
}
|
||||||
|
- return sd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**< Test structure has already set domain pointer.
|
||||||
|
@@ -1714,11 +1720,7 @@ static void server_domain_check(struct server *serv)
|
||||||
|
if (sd)
|
||||||
|
sd->flags &= (~SERV_MARK); /* found domain, mark active */
|
||||||
|
else
|
||||||
|
- {
|
||||||
|
- sd = server_domain_find_domain(serv->domain);
|
||||||
|
- if (!sd)
|
||||||
|
- server_domain_new(serv);
|
||||||
|
- }
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_servers(void)
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,108 @@
|
|||||||
|
From c0e0202736f55195104dad9fec98c20d0d15df21 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Fri, 21 Apr 2023 17:04:53 +0200
|
||||||
|
Subject: [PATCH] Correct releasing of serv_domain
|
||||||
|
|
||||||
|
In case the server->serv_domain points to domain also when it is not the
|
||||||
|
last server used, ensure the reference to last_server is always reset.
|
||||||
|
Some records might reference the server_domain, but cannot ever become
|
||||||
|
last_server. Such as server=/example.com/#
|
||||||
|
|
||||||
|
Correct detection of used server_domains for standard resolvers case.
|
||||||
|
Mark domain used even in that case, so it is not freed during
|
||||||
|
resolv.conf reading or other nameservers change.
|
||||||
|
---
|
||||||
|
src/network.c | 40 +++++++++++++++++++++++++++++++---------
|
||||||
|
1 file changed, 31 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/network.c b/src/network.c
|
||||||
|
index cf2f2e2..8152cac 100644
|
||||||
|
--- a/src/network.c
|
||||||
|
+++ b/src/network.c
|
||||||
|
@@ -1511,7 +1511,18 @@ void mark_servers(int flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void server_domains_cleanup(void)
|
||||||
|
+static void server_domains_pre_cleanup(void)
|
||||||
|
+{
|
||||||
|
+ struct server_domain *sd;
|
||||||
|
+
|
||||||
|
+ /* reset removed last_server. */
|
||||||
|
+ for (sd = daemon->server_domains; sd; sd = sd->next)
|
||||||
|
+ if ((sd->flags & SERV_MARK) == 0 && sd->last_server &&
|
||||||
|
+ (sd->last_server->flags & SERV_MARK) != 0)
|
||||||
|
+ sd->last_server = NULL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void server_domains_post_cleanup(void)
|
||||||
|
{
|
||||||
|
struct server_domain *sd, *tmp, **up;
|
||||||
|
|
||||||
|
@@ -1528,8 +1539,6 @@ static void server_domains_cleanup(void)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
up = &sd->next;
|
||||||
|
- if (sd->last_server && (sd->last_server->flags & SERV_MARK))
|
||||||
|
- sd->last_server = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1538,7 +1547,7 @@ void cleanup_servers(void)
|
||||||
|
{
|
||||||
|
struct server *serv, *tmp, **up;
|
||||||
|
|
||||||
|
- server_domains_cleanup();
|
||||||
|
+ server_domains_pre_cleanup();
|
||||||
|
|
||||||
|
/* unlink and free anything still marked. */
|
||||||
|
for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
|
||||||
|
@@ -1552,10 +1561,16 @@ void cleanup_servers(void)
|
||||||
|
free(serv->domain);
|
||||||
|
free(serv);
|
||||||
|
}
|
||||||
|
- else
|
||||||
|
- up = &serv->next;
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ up = &serv->next;
|
||||||
|
+ if (serv->serv_domain && (serv->serv_domain->flags & SERV_MARK) != 0)
|
||||||
|
+ serv->serv_domain = NULL;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
+ server_domains_post_cleanup();
|
||||||
|
+
|
||||||
|
#ifdef HAVE_LOOP
|
||||||
|
/* Now we have a new set of servers, test for loops. */
|
||||||
|
loop_send_probes();
|
||||||
|
@@ -1699,7 +1714,11 @@ static void server_domain_check(struct server *serv)
|
||||||
|
if (sd)
|
||||||
|
sd->flags &= (~SERV_MARK); /* found domain, mark active */
|
||||||
|
else
|
||||||
|
- server_domain_new(serv);
|
||||||
|
+ {
|
||||||
|
+ sd = server_domain_find_domain(serv->domain);
|
||||||
|
+ if (!sd)
|
||||||
|
+ server_domain_new(serv);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_servers(void)
|
||||||
|
@@ -1808,8 +1827,11 @@ void check_servers(void)
|
||||||
|
else if (strlen(serv->domain) == 0)
|
||||||
|
s1 = _("default"), s2 = "";
|
||||||
|
else
|
||||||
|
- s1 = _("domain"), s2 = serv->domain;
|
||||||
|
-
|
||||||
|
+ {
|
||||||
|
+ s1 = _("domain"), s2 = serv->domain;
|
||||||
|
+ server_domain_check(serv);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (serv->flags & SERV_NO_ADDR)
|
||||||
|
{
|
||||||
|
count--;
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIzBAABCAAdFiEE1urL1u5GuDQkjRESFc3aauGRNaIFAmBuGPsACgkQFc3aauGR
|
||||||
|
NaIg6A//Xfcu62aItiHf/jTeFHUSqHrdqanDqLRWSpgdeKO2adk+s66p5CqVHC8K
|
||||||
|
JfxPo6eTUj8uX53Idy5oiwUz4d40iiOjfxHs4Nme0ozyIAHGw/Tfwx7/+NV882vi
|
||||||
|
+rtqhjF83dRsnqIR95FD17tVI+cR0sq6XKzwBtPicjmPt79sQ2UtkBo7I+IS9B5g
|
||||||
|
o+i21gGYm34EgY6EavveWfGkKgJLz+cF59h4i16lc1eRGNsy5clURDxiJ65Zz0zb
|
||||||
|
ZARLudEclbFNdoUu/4idmOUhZCGWrqf9o+rQDYW3vN85saxCPbTChqqy1VC6OBnX
|
||||||
|
VLN3cAJlk1hS5X0HzewhXkOqulzjg81KWRQ8EYATdOQP7u6apv4q87hnmr+uL9E8
|
||||||
|
0VZ3ECyhH7n6qNXfqNS2Fp3Yp0sm1hgRy+6bu/IgVTPs/Ro22HqTiw5YXZQkPMbe
|
||||||
|
A4acAep59nIV9dEB5DYF1N0S0P6OcVtUsZAFlGS1cD0owFuI44W/lg8w9xA9gyJv
|
||||||
|
uqZvZqkQDM8bi9zJ2d7fjf65pjS+7S9ISxDoPHp34lLMB7D/rAuW8GVBkL1KxMWb
|
||||||
|
sRHIBDKM01CXZeRBlbxAYHlH7s2QehRk/t57ksTmPtT3IAVMSajEG0+1YElUGg8s
|
||||||
|
2gqLtCLdmB6Lwl4RFripSERvPzYOAsd8DiqDL9wYOECBStUGuEw=
|
||||||
|
=W3WM
|
||||||
|
-----END PGP SIGNATURE-----
|
@ -0,0 +1,107 @@
|
|||||||
|
From 268080fc19990711a1d1e1acd68a50aa2f6cb5fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Fri, 17 Sep 2021 20:12:21 +0200
|
||||||
|
Subject: [PATCH] Offer alternative DHCPv6 address if requested is taken
|
||||||
|
|
||||||
|
In some cases multiple requests might arrive from single DUID. It may
|
||||||
|
happen just one address is offered to different IAID requests. When
|
||||||
|
the first request confirms lease, another would be offered alternative
|
||||||
|
address instead of address in use error.
|
||||||
|
|
||||||
|
Includes check on such Rapid commit equivalents and returns NotOnLink
|
||||||
|
error, required by RFC 8145, if requested address were not on any
|
||||||
|
supported prefix.
|
||||||
|
---
|
||||||
|
src/rfc3315.c | 39 ++++++++++++++++++++++++++++-----------
|
||||||
|
1 file changed, 28 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/rfc3315.c b/src/rfc3315.c
|
||||||
|
index 5c2ff97..d1534ad 100644
|
||||||
|
--- a/src/rfc3315.c
|
||||||
|
+++ b/src/rfc3315.c
|
||||||
|
@@ -614,7 +614,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
|
||||||
|
case DHCP6SOLICIT:
|
||||||
|
{
|
||||||
|
- int address_assigned = 0;
|
||||||
|
+ int address_assigned = 0, ia_invalid = 0;
|
||||||
|
/* tags without all prefix-class tags */
|
||||||
|
struct dhcp_netid *solicit_tags;
|
||||||
|
struct dhcp_context *c;
|
||||||
|
@@ -697,6 +697,8 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
get_context_tag(state, c);
|
||||||
|
address_assigned = 1;
|
||||||
|
}
|
||||||
|
+ else
|
||||||
|
+ ia_invalid++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Suggest configured address(es) */
|
||||||
|
@@ -782,11 +784,26 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
tagif = add_options(state, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
- {
|
||||||
|
+ {
|
||||||
|
+ char *errmsg;
|
||||||
|
/* no address, return error */
|
||||||
|
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||||
|
- put_opt6_short(DHCP6NOADDRS);
|
||||||
|
- put_opt6_string(_("no addresses available"));
|
||||||
|
+ if (state->lease_allocate && ia_invalid)
|
||||||
|
+ {
|
||||||
|
+ /* RFC 8415, Section 18.3.2:
|
||||||
|
+ If any of the prefixes of the included addresses are not
|
||||||
|
+ appropriate for the link to which the client is connected,
|
||||||
|
+ the server MUST return the IA to the client with a Status
|
||||||
|
+ Code option with the value NotOnLink. */
|
||||||
|
+ put_opt6_short(DHCP6NOTONLINK);
|
||||||
|
+ errmsg = _("not on link");
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ put_opt6_short(DHCP6NOADDRS);
|
||||||
|
+ errmsg = _("no addresses available");
|
||||||
|
+ }
|
||||||
|
+ put_opt6_string(errmsg);
|
||||||
|
end_opt6(o1);
|
||||||
|
|
||||||
|
/* Some clients will ask repeatedly when we're not giving
|
||||||
|
@@ -795,7 +812,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
for (c = state->context; c; c = c->current)
|
||||||
|
if (!(c->flags & CONTEXT_RA_STATELESS))
|
||||||
|
{
|
||||||
|
- log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, _("no addresses available"));
|
||||||
|
+ log6_packet(state, state->lease_allocate ? "DHCPREPLY" : "DHCPADVERTISE", NULL, errmsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -831,7 +848,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
/* If we get a request with an IA_*A without addresses, treat it exactly like
|
||||||
|
a SOLICT with rapid commit set. */
|
||||||
|
save_counter(start);
|
||||||
|
- goto request_no_address;
|
||||||
|
+ goto request_no_address;
|
||||||
|
}
|
||||||
|
|
||||||
|
o = build_ia(state, &t1cntr);
|
||||||
|
@@ -861,11 +878,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
}
|
||||||
|
else if (!check_address(state, &req_addr))
|
||||||
|
{
|
||||||
|
- /* Address leased to another DUID/IAID */
|
||||||
|
- o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||||
|
- put_opt6_short(DHCP6UNSPEC);
|
||||||
|
- put_opt6_string(_("address in use"));
|
||||||
|
- end_opt6(o1);
|
||||||
|
+ /* Address leased to another DUID/IAID.
|
||||||
|
+ Find another address for the client, treat it exactly like
|
||||||
|
+ a SOLICT with rapid commit set. */
|
||||||
|
+ save_counter(start);
|
||||||
|
+ goto request_no_address;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,28 @@
|
|||||||
|
From 4272580bb586180e596e5ed30b68455826acc8c1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Wed, 22 Sep 2021 14:54:01 +0200
|
||||||
|
Subject: [PATCH] Add support for option6 names of RFC 5970
|
||||||
|
|
||||||
|
Client Network Interface Identifier and Client System Architecture Type
|
||||||
|
options were not understood by dnsmasq. Add it to supported option
|
||||||
|
types.
|
||||||
|
---
|
||||||
|
src/dhcp-common.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
|
||||||
|
index 36bc38a..528e8e7 100644
|
||||||
|
--- a/src/dhcp-common.c
|
||||||
|
+++ b/src/dhcp-common.c
|
||||||
|
@@ -659,6 +659,8 @@ static const struct opttab_t opttab6[] = {
|
||||||
|
{ "ntp-server", 56, 0 /* OT_ADDR_LIST | OT_RFC1035_NAME */ },
|
||||||
|
{ "bootfile-url", 59, OT_NAME },
|
||||||
|
{ "bootfile-param", 60, OT_CSTRING },
|
||||||
|
+ { "client-arch", 61, 2 | OT_DEC }, /* RFC 5970 */
|
||||||
|
+ { "client-interface-id", 62, 1 | OT_DEC }, /* RFC 5970 */
|
||||||
|
{ NULL, 0, 0 }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
--
|
||||||
|
2.31.1
|
||||||
|
|
@ -0,0 +1,113 @@
|
|||||||
|
From 32e0e81715f60ca35738818370f5d3aacf9e2d2c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||||
|
Date: Fri, 9 Apr 2021 16:08:05 +0100
|
||||||
|
Subject: [PATCH] Fix bug in TCP process handling.
|
||||||
|
|
||||||
|
Fix bug which caused dnsmasq to lose track of processes forked
|
||||||
|
to handle TCP DNS connections under heavy load. The code
|
||||||
|
checked that at least one free process table slot was
|
||||||
|
available before listening on TCP sockets, but didn't take
|
||||||
|
into account that more than one TCP connection could
|
||||||
|
arrive, so that check was not sufficient to ensure that
|
||||||
|
there would be slots for all new processes. It compounded
|
||||||
|
this error by silently failing to store the process when
|
||||||
|
it did run out of slots. Even when this bug is triggered,
|
||||||
|
all the right things happen, and answers are still returned.
|
||||||
|
Only under very exceptional circumstances, does the bug
|
||||||
|
manifest itself: see
|
||||||
|
https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2021q2/014976.html
|
||||||
|
|
||||||
|
Thanks to Tijs Van Buggenhout for finding the conditions under
|
||||||
|
which the bug manifests itself, and then working out
|
||||||
|
exactly what was going on.
|
||||||
|
|
||||||
|
(cherry picked from commit ad90eb075dfeeb1936e8bc0f323fcc23f89364d4)
|
||||||
|
---
|
||||||
|
src/dnsmasq.c | 44 +++++++++++++++++++++++++-------------------
|
||||||
|
1 file changed, 25 insertions(+), 19 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
|
||||||
|
index 979e33d..af9132f 100644
|
||||||
|
--- a/src/dnsmasq.c
|
||||||
|
+++ b/src/dnsmasq.c
|
||||||
|
@@ -1720,22 +1720,24 @@ static int set_dns_listeners(time_t now)
|
||||||
|
for (rfl = daemon->rfl_poll; rfl; rfl = rfl->next)
|
||||||
|
poll_listen(rfl->rfd->fd, POLLIN);
|
||||||
|
|
||||||
|
+ /* check to see if we have free tcp process slots. */
|
||||||
|
+ for (i = MAX_PROCS - 1; i >= 0; i--)
|
||||||
|
+ if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
for (listener = daemon->listeners; listener; listener = listener->next)
|
||||||
|
{
|
||||||
|
/* only listen for queries if we have resources */
|
||||||
|
if (listener->fd != -1 && wait == 0)
|
||||||
|
poll_listen(listener->fd, POLLIN);
|
||||||
|
|
||||||
|
- /* death of a child goes through the select loop, so
|
||||||
|
- we don't need to explicitly arrange to wake up here */
|
||||||
|
- if (listener->tcpfd != -1)
|
||||||
|
- for (i = 0; i < MAX_PROCS; i++)
|
||||||
|
- if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
||||||
|
- {
|
||||||
|
- poll_listen(listener->tcpfd, POLLIN);
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ /* Only listen for TCP connections when a process slot
|
||||||
|
+ is available. Death of a child goes through the select loop, so
|
||||||
|
+ we don't need to explicitly arrange to wake up here,
|
||||||
|
+ we'll be called again when a slot becomes available. */
|
||||||
|
+ if (listener->tcpfd != -1 && i >= 0)
|
||||||
|
+ poll_listen(listener->tcpfd, POLLIN);
|
||||||
|
+
|
||||||
|
#ifdef HAVE_TFTP
|
||||||
|
/* tftp == 0 in single-port mode. */
|
||||||
|
if (tftp <= daemon->tftp_max && listener->tftpfd != -1)
|
||||||
|
@@ -1801,7 +1803,16 @@ static void check_dns_listeners(time_t now)
|
||||||
|
tftp_request(listener, now);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- if (listener->tcpfd != -1 && poll_check(listener->tcpfd, POLLIN))
|
||||||
|
+ /* check to see if we have a free tcp process slot.
|
||||||
|
+ Note that we can't assume that because we had
|
||||||
|
+ at least one a poll() time, that we still do.
|
||||||
|
+ There may be more waiting connections after
|
||||||
|
+ poll() returns then free process slots. */
|
||||||
|
+ for (i = MAX_PROCS - 1; i >= 0; i--)
|
||||||
|
+ if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
+ if (listener->tcpfd != -1 && i >= 0 && poll_check(listener->tcpfd, POLLIN))
|
||||||
|
{
|
||||||
|
int confd, client_ok = 1;
|
||||||
|
struct irec *iface = NULL;
|
||||||
|
@@ -1891,7 +1902,6 @@ static void check_dns_listeners(time_t now)
|
||||||
|
close(pipefd[0]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
- int i;
|
||||||
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
/* The child process inherits the netlink socket,
|
||||||
|
which it never uses, but when the parent (us)
|
||||||
|
@@ -1911,13 +1921,9 @@ static void check_dns_listeners(time_t now)
|
||||||
|
read_write(pipefd[0], &a, 1, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
- for (i = 0; i < MAX_PROCS; i++)
|
||||||
|
- if (daemon->tcp_pids[i] == 0 && daemon->tcp_pipes[i] == -1)
|
||||||
|
- {
|
||||||
|
- daemon->tcp_pids[i] = p;
|
||||||
|
- daemon->tcp_pipes[i] = pipefd[0];
|
||||||
|
- break;
|
||||||
|
- }
|
||||||
|
+ /* i holds index of free slot */
|
||||||
|
+ daemon->tcp_pids[i] = p;
|
||||||
|
+ daemon->tcp_pipes[i] = pipefd[0];
|
||||||
|
}
|
||||||
|
close(confd);
|
||||||
|
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,172 @@
|
|||||||
|
From 5d1b75b542f128f757606668a44ce60ebb3c47f0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||||
|
Date: Thu, 31 Mar 2022 21:35:20 +0100
|
||||||
|
Subject: [PATCH] Fix write-after-free error in DHCPv6 code. CVE-2022-0934
|
||||||
|
refers.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/rfc3315.c | 48 +++++++++++++++++++++++++++---------------------
|
||||||
|
1 file changed, 27 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/rfc3315.c b/src/rfc3315.c
|
||||||
|
index fbb6876..d2ebf15 100644
|
||||||
|
--- a/src/rfc3315.c
|
||||||
|
+++ b/src/rfc3315.c
|
||||||
|
@@ -33,9 +33,9 @@ struct state {
|
||||||
|
unsigned int mac_len, mac_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
|
||||||
|
+static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
|
||||||
|
struct in6_addr *client_addr, int is_unicast, time_t now);
|
||||||
|
-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||||
|
+static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now);
|
||||||
|
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_quiet(struct state *state, char *type, struct in6_addr *addr, char *string);
|
||||||
|
@@ -104,12 +104,12 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This cost me blood to write, it will probably cost you blood to understand - srk. */
|
||||||
|
-static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
|
||||||
|
+static int dhcp6_maybe_relay(struct state *state, unsigned char *inbuff, size_t sz,
|
||||||
|
struct in6_addr *client_addr, int is_unicast, time_t now)
|
||||||
|
{
|
||||||
|
void *end = inbuff + sz;
|
||||||
|
void *opts = inbuff + 34;
|
||||||
|
- int msg_type = *((unsigned char *)inbuff);
|
||||||
|
+ int msg_type = *inbuff;
|
||||||
|
unsigned char *outmsgtypep;
|
||||||
|
void *opt;
|
||||||
|
struct dhcp_vendor *vendor;
|
||||||
|
@@ -259,15 +259,15 @@ static int dhcp6_maybe_relay(struct state *state, void *inbuff, size_t sz,
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||||
|
+static int dhcp6_no_relay(struct state *state, int msg_type, unsigned char *inbuff, size_t sz, int is_unicast, time_t now)
|
||||||
|
{
|
||||||
|
void *opt;
|
||||||
|
- int i, o, o1, start_opts;
|
||||||
|
+ int i, o, o1, start_opts, start_msg;
|
||||||
|
struct dhcp_opt *opt_cfg;
|
||||||
|
struct dhcp_netid *tagif;
|
||||||
|
struct dhcp_config *config = NULL;
|
||||||
|
struct dhcp_netid known_id, iface_id, v6_id;
|
||||||
|
- unsigned char *outmsgtypep;
|
||||||
|
+ unsigned char outmsgtype;
|
||||||
|
struct dhcp_vendor *vendor;
|
||||||
|
struct dhcp_context *context_tmp;
|
||||||
|
struct dhcp_mac *mac_opt;
|
||||||
|
@@ -296,12 +296,13 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
v6_id.next = state->tags;
|
||||||
|
state->tags = &v6_id;
|
||||||
|
|
||||||
|
- /* copy over transaction-id, and save pointer to message type */
|
||||||
|
- if (!(outmsgtypep = put_opt6(inbuff, 4)))
|
||||||
|
+ start_msg = save_counter(-1);
|
||||||
|
+ /* copy over transaction-id */
|
||||||
|
+ if (!put_opt6(inbuff, 4))
|
||||||
|
return 0;
|
||||||
|
start_opts = save_counter(-1);
|
||||||
|
- state->xid = outmsgtypep[3] | outmsgtypep[2] << 8 | outmsgtypep[1] << 16;
|
||||||
|
-
|
||||||
|
+ state->xid = inbuff[3] | inbuff[2] << 8 | inbuff[1] << 16;
|
||||||
|
+
|
||||||
|
/* We're going to be linking tags from all context we use.
|
||||||
|
mark them as unused so we don't link one twice and break the list */
|
||||||
|
for (context_tmp = state->context; context_tmp; context_tmp = context_tmp->current)
|
||||||
|
@@ -347,7 +348,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
(msg_type == DHCP6REQUEST || msg_type == DHCP6RENEW || msg_type == DHCP6RELEASE || msg_type == DHCP6DECLINE))
|
||||||
|
|
||||||
|
{
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||||
|
put_opt6_short(DHCP6USEMULTI);
|
||||||
|
put_opt6_string("Use multicast");
|
||||||
|
@@ -619,11 +620,11 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
struct dhcp_netid *solicit_tags;
|
||||||
|
struct dhcp_context *c;
|
||||||
|
|
||||||
|
- *outmsgtypep = DHCP6ADVERTISE;
|
||||||
|
+ outmsgtype = DHCP6ADVERTISE;
|
||||||
|
|
||||||
|
if (opt6_find(state->packet_options, state->end, OPTION6_RAPID_COMMIT, 0))
|
||||||
|
{
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
state->lease_allocate = 1;
|
||||||
|
o = new_opt6(OPTION6_RAPID_COMMIT);
|
||||||
|
end_opt6(o);
|
||||||
|
@@ -826,7 +827,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
int start = save_counter(-1);
|
||||||
|
|
||||||
|
/* set reply message type */
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
state->lease_allocate = 1;
|
||||||
|
|
||||||
|
log6_quiet(state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
|
||||||
|
@@ -938,7 +939,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
case DHCP6RENEW:
|
||||||
|
{
|
||||||
|
/* set reply message type */
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
|
||||||
|
log6_quiet(state, "DHCPRENEW", NULL, NULL);
|
||||||
|
|
||||||
|
@@ -1050,7 +1051,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
int good_addr = 0;
|
||||||
|
|
||||||
|
/* set reply message type */
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
|
||||||
|
log6_quiet(state, "DHCPCONFIRM", NULL, NULL);
|
||||||
|
|
||||||
|
@@ -1114,7 +1115,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
log6_quiet(state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state->hostname);
|
||||||
|
if (ignore)
|
||||||
|
return 0;
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
tagif = add_options(state, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1123,7 +1124,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
case DHCP6RELEASE:
|
||||||
|
{
|
||||||
|
/* set reply message type */
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
|
||||||
|
log6_quiet(state, "DHCPRELEASE", NULL, NULL);
|
||||||
|
|
||||||
|
@@ -1188,7 +1189,7 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
case DHCP6DECLINE:
|
||||||
|
{
|
||||||
|
/* set reply message type */
|
||||||
|
- *outmsgtypep = DHCP6REPLY;
|
||||||
|
+ outmsgtype = DHCP6REPLY;
|
||||||
|
|
||||||
|
log6_quiet(state, "DHCPDECLINE", NULL, NULL);
|
||||||
|
|
||||||
|
@@ -1268,7 +1269,12 @@ static int dhcp6_no_relay(struct state *state, int msg_type, void *inbuff, size_
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+
|
||||||
|
+ /* Fill in the message type. Note that we store the offset,
|
||||||
|
+ not a direct pointer, since the packet memory may have been
|
||||||
|
+ reallocated. */
|
||||||
|
+ ((unsigned char *)(daemon->outpacket.iov_base))[start_msg] = outmsgtype;
|
||||||
|
+
|
||||||
|
log_tags(tagif, state->xid);
|
||||||
|
log6_opts(0, state->xid, daemon->outpacket.iov_base + start_opts, daemon->outpacket.iov_base + save_counter(-1));
|
||||||
|
|
||||||
|
--
|
||||||
|
2.39.1
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
From 2f45670951d2159ebf588e1e4943c0bc9e1cd20b Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Wed, 18 Aug 2021 14:59:23 +0200
|
||||||
|
Subject: [PATCH] Add safety checks to places pointed by Coverity
|
||||||
|
|
||||||
|
GCC Analyzer (experimental)
|
||||||
|
|
||||||
|
1. dnsmasq-2.85/src/forward.c:0: scope_hint: In function 'allocate_rfd.part.0'
|
||||||
|
2. dnsmasq-2.85/src/forward.c:2321:18: warning[-Wanalyzer-null-dereference]: dereference of NULL 'rfd'
|
||||||
|
# 2319| *fdlp = rfl;
|
||||||
|
# 2320|
|
||||||
|
# 2321|-> return rfl->rfd->fd;
|
||||||
|
# 2322| }
|
||||||
|
# 2323|
|
||||||
|
|
||||||
|
1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'log_query'
|
||||||
|
2. dnsmasq-2.85/src/cache.c:1969:20: warning[-Wanalyzer-null-dereference]: dereference of NULL 'name'
|
||||||
|
# 1967| source = "cached";
|
||||||
|
# 1968|
|
||||||
|
# 1969|-> if (strlen(name) == 0)
|
||||||
|
# 1970| name = ".";
|
||||||
|
# 1971|
|
||||||
|
|
||||||
|
1. dnsmasq-2.85/src/cache.c:0: scope_hint: In function 'cache_scan_free'
|
||||||
|
2. dnsmasq-2.85/src/cache.c:436:20: warning[-Wanalyzer-null-argument]: use of NULL 'addr' where non-null expected
|
||||||
|
40. /usr/include/sys/un.h:37: included_from: Included from here.
|
||||||
|
41. dnsmasq-2.85/src/dnsmasq.h:101: included_from: Included from here.
|
||||||
|
42. dnsmasq-2.85/src/cache.c:17: included_from: Included from here.
|
||||||
|
43. /usr/include/string.h:64:12: note: argument 2 of 'memcmp' must be non-null
|
||||||
|
# 434| (flags & crecp->flags & F_REVERSE) &&
|
||||||
|
# 435| (flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
|
||||||
|
# 436|-> memcmp(&crecp->addr, addr, addrlen) == 0)
|
||||||
|
# 437| {
|
||||||
|
# 438| *up = crecp->hash_next;
|
||||||
|
---
|
||||||
|
src/cache.c | 4 ++--
|
||||||
|
src/forward.c | 2 +-
|
||||||
|
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/cache.c b/src/cache.c
|
||||||
|
index b3b3c7c..8f97947 100644
|
||||||
|
--- a/src/cache.c
|
||||||
|
+++ b/src/cache.c
|
||||||
|
@@ -483,7 +483,7 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
|
||||||
|
else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) &&
|
||||||
|
(flags & crecp->flags & F_REVERSE) &&
|
||||||
|
(flags & crecp->flags & (F_IPV4 | F_IPV6)) &&
|
||||||
|
- memcmp(&crecp->addr, addr, addrlen) == 0)
|
||||||
|
+ addr && memcmp(&crecp->addr, addr, addrlen) == 0)
|
||||||
|
{
|
||||||
|
*up = crecp->hash_next;
|
||||||
|
cache_unlink(crecp);
|
||||||
|
@@ -2067,7 +2067,7 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
|
||||||
|
else
|
||||||
|
source = "cached";
|
||||||
|
|
||||||
|
- if (strlen(name) == 0)
|
||||||
|
+ if (name && !name[0])
|
||||||
|
name = ".";
|
||||||
|
|
||||||
|
if (option_bool(OPT_EXTRALOG))
|
||||||
|
diff --git a/src/forward.c b/src/forward.c
|
||||||
|
index 434ba77..f3c38d7 100644
|
||||||
|
--- a/src/forward.c
|
||||||
|
+++ b/src/forward.c
|
||||||
|
@@ -2274,7 +2274,7 @@ int allocate_rfd(struct randfd_list **fdlp, struct server *serv)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (j == daemon->numrrand)
|
||||||
|
+ if (!rfd) /* should be when j == daemon->numrrand */
|
||||||
|
{
|
||||||
|
struct randfd_list *rfl_poll;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.41.0
|
||||||
|
|
@ -0,0 +1,64 @@
|
|||||||
|
From e342e4d5c3093d8dd9e2d622e46d36f67bfb4925 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
|
||||||
|
Date: Mon, 10 Jan 2022 12:34:42 +0100
|
||||||
|
Subject: [PATCH] Add root group writeable flag to log file
|
||||||
|
|
||||||
|
Some systems strips even root process capability of writing to different
|
||||||
|
users file. That include systemd under Fedora. When
|
||||||
|
log-facility=/var/log/dnsmasq.log is used, log file with mode 0640
|
||||||
|
is created. But restart then fails, because such log file can be used
|
||||||
|
only when created new. Existing file cannot be opened by root when
|
||||||
|
starting, causing fatal error. Avoid that by adding root group writeable flag.
|
||||||
|
|
||||||
|
Ensure group is always root when granting write access. If it is
|
||||||
|
anything else, administrator has to configure correct rights.
|
||||||
|
|
||||||
|
(cherry picked from commit 1f8f78a49b8fd6b2862a3882053b1c6e6e111e5c)
|
||||||
|
---
|
||||||
|
src/log.c | 23 ++++++++++++++++++-----
|
||||||
|
1 file changed, 18 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/log.c b/src/log.c
|
||||||
|
index 1ec3447..bcd6e52 100644
|
||||||
|
--- a/src/log.c
|
||||||
|
+++ b/src/log.c
|
||||||
|
@@ -100,10 +100,23 @@ int log_start(struct passwd *ent_pw, int errfd)
|
||||||
|
/* If we're running as root and going to change uid later,
|
||||||
|
change the ownership here so that the file is always owned by
|
||||||
|
the dnsmasq user. Then logrotate can just copy the owner.
|
||||||
|
- Failure of the chown call is OK, (for instance when started as non-root) */
|
||||||
|
- if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0 &&
|
||||||
|
- fchown(log_fd, ent_pw->pw_uid, -1) != 0)
|
||||||
|
- ret = errno;
|
||||||
|
+ Failure of the chown call is OK, (for instance when started as non-root).
|
||||||
|
+
|
||||||
|
+ If we've created a file with group-id root, we also make
|
||||||
|
+ the file group-writable. This gives processes in the root group
|
||||||
|
+ write access to the file and avoids the problem that on some systems,
|
||||||
|
+ once the file is owned by the dnsmasq user, it can't be written
|
||||||
|
+ whilst dnsmasq is running as root during startup.
|
||||||
|
+ */
|
||||||
|
+ if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0)
|
||||||
|
+ {
|
||||||
|
+ struct stat ls;
|
||||||
|
+ if (getgid() == 0 && fstat(log_fd, &ls) == 0 && ls.st_gid == 0 &&
|
||||||
|
+ (ls.st_mode & S_IWGRP) == 0)
|
||||||
|
+ (void)fchmod(log_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
|
||||||
|
+ if (fchown(log_fd, ent_pw->pw_uid, -1) != 0)
|
||||||
|
+ ret = errno;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@@ -118,7 +131,7 @@ int log_reopen(char *log_file)
|
||||||
|
/* NOTE: umask is set to 022 by the time this gets called */
|
||||||
|
|
||||||
|
if (log_file)
|
||||||
|
- log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
|
||||||
|
+ log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if defined(HAVE_SOLARIS_NETWORK) || defined(__ANDROID__)
|
||||||
|
--
|
||||||
|
2.40.1
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From 9d8270be2e2b31437684f2d87add9a28a41f0c75 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||||
|
Date: Tue, 7 Mar 2023 22:07:46 +0000
|
||||||
|
Subject: [PATCH] Set the default maximum DNS UDP packet size to 1232.
|
||||||
|
|
||||||
|
http://www.dnsflagday.net/2020/ refers.
|
||||||
|
|
||||||
|
Thanks to Xiang Li for the prompt.
|
||||||
|
|
||||||
|
(cherry picked from commit eb92fb32b746f2104b0f370b5b295bb8dd4bd5e5)
|
||||||
|
---
|
||||||
|
man/dnsmasq.8 | 3 ++-
|
||||||
|
src/config.h | 2 +-
|
||||||
|
2 files changed, 3 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
|
||||||
|
index fce580f..4b0b180 100644
|
||||||
|
--- a/man/dnsmasq.8
|
||||||
|
+++ b/man/dnsmasq.8
|
||||||
|
@@ -171,7 +171,8 @@ to zero completely disables DNS function, leaving only DHCP and/or TFTP.
|
||||||
|
.TP
|
||||||
|
.B \-P, --edns-packet-max=<size>
|
||||||
|
Specify the largest EDNS.0 UDP packet which is supported by the DNS
|
||||||
|
-forwarder. Defaults to 4096, which is the RFC5625-recommended size.
|
||||||
|
+forwarder. Defaults to 1232, which is the recommended size following the
|
||||||
|
+DNS flag day in 2020. Only increase if you know what you are doing.
|
||||||
|
.TP
|
||||||
|
.B \-Q, --query-port=<query_port>
|
||||||
|
Send outbound DNS queries from, and listen for their replies on, the
|
||||||
|
diff --git a/src/config.h b/src/config.h
|
||||||
|
index 8c41943..62b7fa1 100644
|
||||||
|
--- a/src/config.h
|
||||||
|
+++ b/src/config.h
|
||||||
|
@@ -19,7 +19,7 @@
|
||||||
|
#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_BACKLOG 32 /* kernel backlog limit for TCP connections */
|
||||||
|
-#define EDNS_PKTSZ 4096 /* default max EDNS.0 UDP packet from RFC5625 */
|
||||||
|
+#define EDNS_PKTSZ 1232 /* default max EDNS.0 UDP packet from from /dnsflagday.net/2020 */
|
||||||
|
#define SAFE_PKTSZ 1280 /* "go anywhere" UDP packet size */
|
||||||
|
#define KEYBLOCK_LEN 40 /* choose to minimise fragmentation when storing DNSSEC keys */
|
||||||
|
#define DNSSEC_WORK 50 /* Max number of queries to validate one question */
|
||||||
|
--
|
||||||
|
2.39.2
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -1,16 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQIzBAABCAAdFiEE1urL1u5GuDQkjRESFc3aauGRNaIFAmXLc7MACgkQFc3aauGR
|
|
||||||
NaKwug/7BIZ9TOBB65sR/rBg0JU/4jBG1WQglmEckSkK7NWagXVbjlVVl0F1AUZo
|
|
||||||
JBaW6qIvFZ9q7OlOB50gpZNC0wvIYRa8bdvicWjktxW/KFC/NZo5iI6DHH0p6LK2
|
|
||||||
pymMCGyRkAgVc8Yxv3BDTqw70ld4gA8WamNWQsfS14n0VF/abOv/A0x70XkHPdIc
|
|
||||||
U9ZZX+1/Zn6s08arzUSEAnuR3+SW6Amq6MJKwCT8eVDNvTG35o0+HWAmyo+EjRmo
|
|
||||||
PdiIa1fmOcY8V80E5Xs2V11kMZeAZymD/GzCUTwW4Q2T7WW3OsMc9KlH35bAhfvI
|
|
||||||
iiBDbmYqI6AgLi6rIB1X6CKZ5V3VR93nxbSieaocZ145BAukxFOLuBTqjR1jhZt7
|
|
||||||
63HfbYv3aViwMX2Ggk0XIh/OvIr6dFAsqiD6n+pYKLOVs1nyhXK1UP+J/9BhvJfx
|
|
||||||
4Dzx38K1iFilyR35tUiRosiZHgEHiZtJJ2u4B+nVENHpcVPG1cZQ92x7b2UDBfL4
|
|
||||||
wcZ2U4guxdN4iBE7zzCseJNFL7NZ0U476RWEG9NybAnGGlpDY8m5AuQ5nHT0AjV7
|
|
||||||
d+Fq0EaKr0rfjDk1bjYf88VRW0Khx4Fz5IsmnGw/p+09xBEhQftK+M42FpIbbscx
|
|
||||||
uZQ5i7CNkMAsft/lUGYEdLcTi5HuDWBtbXjVMLvzFRPz7W9l0J0=
|
|
||||||
=iZdM
|
|
||||||
-----END PGP SIGNATURE-----
|
|
Loading…
Reference in new issue