Blame SOURCES/dnsmasq-2.79-server-domain-rh1919894.patch

6fa8a9
From b15c92e5d793c9767591dbf8910bf3466aba92ee Mon Sep 17 00:00:00 2001
6fa8a9
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
6fa8a9
Date: Mon, 19 Apr 2021 13:56:23 +0200
6fa8a9
Subject: [PATCH] Use load-balancing also for --server=/domains/
6fa8a9
6fa8a9
Do not (yet) move servers to server_domain structure. Instead use
6fa8a9
separate server_domains to store just last_server and requests count and
6fa8a9
time.
6fa8a9
6fa8a9
Introduces domain information duplicity, but minimizes required changes
6fa8a9
to daemon->servers usage.
6fa8a9
6fa8a9
Optimize server domain record
6fa8a9
6fa8a9
Set pointer to domain record when struct server is created. When
6fa8a9
searching for domain pointer, use this pointer to make it quick.
6fa8a9
---
6fa8a9
 src/dnsmasq.h |  18 +++++++--
6fa8a9
 src/forward.c |  54 ++++++++++++++++-----------
6fa8a9
 src/network.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++----
6fa8a9
 src/option.c  |   5 +++
6fa8a9
 4 files changed, 147 insertions(+), 31 deletions(-)
6fa8a9
6fa8a9
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
6fa8a9
index 4beef35..27ff86a 100644
6fa8a9
--- a/src/dnsmasq.h
6fa8a9
+++ b/src/dnsmasq.h
6fa8a9
@@ -531,6 +531,17 @@ struct randfd_list {
6fa8a9
   struct randfd_list *next;
6fa8a9
 };
6fa8a9
 
6fa8a9
+/* contains domain specific set of servers.
6fa8a9
+ * If domain is NULL, just normal servers. */
6fa8a9
+struct server_domain {
6fa8a9
+  char *domain;
6fa8a9
+  struct server *last_server;
6fa8a9
+  time_t forwardtime;
6fa8a9
+  int forwardcount;
6fa8a9
+  unsigned int flags; /* server.flags alternative */
6fa8a9
+  struct server_domain *next;
6fa8a9
+};
6fa8a9
+
6fa8a9
 struct server {
6fa8a9
   union mysockaddr addr, source_addr;
6fa8a9
   char interface[IF_NAMESIZE+1];
6fa8a9
@@ -543,6 +554,7 @@ struct server {
6fa8a9
 #ifdef HAVE_LOOP
6fa8a9
   u32 uid;
6fa8a9
 #endif
6fa8a9
+  struct server_domain *serv_domain;
6fa8a9
   struct server *next; 
6fa8a9
 };
6fa8a9
 
6fa8a9
@@ -995,6 +1007,7 @@ extern struct daemon {
6fa8a9
   struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
6fa8a9
   struct bogus_addr *bogus_addr, *ignore_addr;
6fa8a9
   struct server *servers;
6fa8a9
+  struct server_domain *server_domains;
6fa8a9
   struct ipsets *ipsets;
6fa8a9
   int log_fac; /* log facility */
6fa8a9
   char *log_file; /* optional log file */
6fa8a9
@@ -1061,9 +1074,6 @@ extern struct daemon {
6fa8a9
   struct serverfd *sfds;
6fa8a9
   struct irec *interfaces;
6fa8a9
   struct listener *listeners;
6fa8a9
-  struct server *last_server;
6fa8a9
-  time_t forwardtime;
6fa8a9
-  int forwardcount;
6fa8a9
   struct server *srv_save; /* Used for resend on DoD */
6fa8a9
   size_t packet_len;       /*      "        "        */
6fa8a9
   int    fd_save;          /*      "        "        */
6fa8a9
@@ -1319,6 +1329,8 @@ int loopback_exception(int fd, int family, struct all_addr *addr, char *name);
6fa8a9
 int label_exception(int index, int family, struct all_addr *addr);
6fa8a9
 int fix_fd(int fd);
6fa8a9
 int tcp_interface(int fd, int af);
6fa8a9
+struct server_domain *server_domain_find_domain(const char *domain);
6fa8a9
+struct server_domain *server_domain_new(struct server *serv);
6fa8a9
 #ifdef HAVE_IPV6
6fa8a9
 int set_ipv6pktinfo(int fd);
6fa8a9
 #endif
6fa8a9
diff --git a/src/forward.c b/src/forward.c
6fa8a9
index 11e0310..d8e845a 100644
6fa8a9
--- a/src/forward.c
6fa8a9
+++ b/src/forward.c
6fa8a9
@@ -109,7 +109,8 @@ int send_from(int fd, int nowild, char *packet, size_t len,
6fa8a9
 }
6fa8a9
           
6fa8a9
 static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigned int qtype,
6fa8a9
-				   char *qdomain, int *type, char **domain, int *norebind)
6fa8a9
+				   char *qdomain, int *type, char **domain, int *norebind,
6fa8a9
+				   struct server_domain **serv_domain)
6fa8a9
 			      
6fa8a9
 {
6fa8a9
   /* If the query ends in the domain in one of our servers, set
6fa8a9
@@ -121,6 +122,9 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
6fa8a9
   struct server *serv;
6fa8a9
   unsigned int flags = 0;
6fa8a9
   
6fa8a9
+  if (serv_domain)
6fa8a9
+    *serv_domain = NULL;
6fa8a9
+
6fa8a9
   for (serv = daemon->servers; serv; serv=serv->next)
6fa8a9
     if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC))
6fa8a9
       continue;
6fa8a9
@@ -181,6 +185,8 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
6fa8a9
 		  {
6fa8a9
 		    *type = serv->flags & (SERV_HAS_DOMAIN | SERV_USE_RESOLV | SERV_NO_REBIND | SERV_DO_DNSSEC);
6fa8a9
 		    *domain = serv->domain;
6fa8a9
+		    if (serv_domain)
6fa8a9
+		      *serv_domain = serv->serv_domain;
6fa8a9
 		    matchlen = domainlen;
6fa8a9
 		    if (serv->flags & SERV_NO_ADDR)
6fa8a9
 		      flags = F_NXDOMAIN;
6fa8a9
@@ -228,6 +234,8 @@ static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigne
6fa8a9
       *type = 0; /* use normal servers for this domain */
6fa8a9
       *domain = NULL;
6fa8a9
     }
6fa8a9
+  if (serv_domain && !*serv_domain)
6fa8a9
+    *serv_domain = server_domain_find_domain(*domain);
6fa8a9
   return  flags;
6fa8a9
 }
6fa8a9
 
6fa8a9
@@ -242,6 +250,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
6fa8a9
   unsigned int flags = 0;
6fa8a9
   unsigned int fwd_flags = 0;
6fa8a9
   struct server *start = NULL;
6fa8a9
+  struct server_domain *sd = NULL;
6fa8a9
   void *hash = hash_questions(header, plen, daemon->namebuff);
6fa8a9
 #ifdef HAVE_DNSSEC
6fa8a9
   int do_dnssec = 0;
6fa8a9
@@ -313,8 +322,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
6fa8a9
       forward->sentto->failed_queries++;
6fa8a9
       if (!option_bool(OPT_ORDER))
6fa8a9
 	{
6fa8a9
+	  sd = forward->sentto->serv_domain;
6fa8a9
 	  forward->forwardall = 1;
6fa8a9
-	  daemon->last_server = NULL;
6fa8a9
+	  if (sd)
6fa8a9
+	    sd->last_server = NULL;
6fa8a9
 	}
6fa8a9
       type = forward->sentto->flags & SERV_TYPE;
6fa8a9
 #ifdef HAVE_DNSSEC
6fa8a9
@@ -363,10 +374,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
6fa8a9
 	  
6fa8a9
 	  return 1;
6fa8a9
 	}
6fa8a9
-	
6fa8a9
+
6fa8a9
       if (gotname)
6fa8a9
-	flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
6fa8a9
-      
6fa8a9
+	flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind, &sd);
6fa8a9
+
6fa8a9
 #ifdef HAVE_DNSSEC
6fa8a9
       do_dnssec = type & SERV_DO_DNSSEC;
6fa8a9
 #endif
6fa8a9
@@ -407,18 +418,18 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
6fa8a9
 	     always try all the available servers,
6fa8a9
 	     otherwise, use the one last known to work. */
6fa8a9
 	  
6fa8a9
-	  if (type == 0)
6fa8a9
+	  if (sd)
6fa8a9
 	    {
6fa8a9
 	      if (option_bool(OPT_ORDER))
6fa8a9
 		start = daemon->servers;
6fa8a9
-	      else if (!(start = daemon->last_server) ||
6fa8a9
-		       daemon->forwardcount++ > FORWARD_TEST ||
6fa8a9
-		       difftime(now, daemon->forwardtime) > FORWARD_TIME)
6fa8a9
+	      else if (!(start = sd->last_server) ||
6fa8a9
+		       sd->forwardcount++ > FORWARD_TEST ||
6fa8a9
+		       difftime(now, sd->forwardtime) > FORWARD_TIME)
6fa8a9
 		{
6fa8a9
 		  start = daemon->servers;
6fa8a9
 		  forward->forwardall = 1;
6fa8a9
-		  daemon->forwardcount = 0;
6fa8a9
-		  daemon->forwardtime = now;
6fa8a9
+		  sd->forwardcount = 0;
6fa8a9
+		  sd->forwardtime = now;
6fa8a9
 		}
6fa8a9
 	    }
6fa8a9
 	  else
6fa8a9
@@ -758,6 +769,7 @@ void reply_query(int fd, time_t now)
6fa8a9
   size_t nn;
6fa8a9
   struct server *server;
6fa8a9
   void *hash;
6fa8a9
+  struct server_domain *sd;
6fa8a9
 
6fa8a9
   /* packet buffer overwritten */
6fa8a9
   daemon->srv_save = NULL;
6fa8a9
@@ -845,7 +857,8 @@ void reply_query(int fd, time_t now)
6fa8a9
     }   
6fa8a9
    
6fa8a9
   server = forward->sentto;
6fa8a9
-  if ((forward->sentto->flags & SERV_TYPE) == 0)
6fa8a9
+  sd = server->serv_domain;
6fa8a9
+  if (sd)
6fa8a9
     {
6fa8a9
       if (RCODE(header) == REFUSED)
6fa8a9
 	server = NULL;
6fa8a9
@@ -863,7 +876,7 @@ void reply_query(int fd, time_t now)
6fa8a9
 	      }
6fa8a9
 	} 
6fa8a9
       if (!option_bool(OPT_ALL_SERVERS))
6fa8a9
-	daemon->last_server = server;
6fa8a9
+	sd->last_server = server;
6fa8a9
     }
6fa8a9
  
6fa8a9
   /* We tried resending to this server with a smaller maximum size and got an answer.
6fa8a9
@@ -964,7 +977,7 @@ void reply_query(int fd, time_t now)
6fa8a9
 		      /* Find server to forward to. This will normally be the 
6fa8a9
 			 same as for the original query, but may be another if
6fa8a9
 			 servers for domains are involved. */		      
6fa8a9
-		      if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL) == 0)
6fa8a9
+		      if (search_servers(now, NULL, F_DNSSECOK, daemon->keyname, &type, &domain, NULL, &sd) == 0)
6fa8a9
 			{
6fa8a9
 			  struct server *start = server, *new_server = NULL;
6fa8a9
 			  
6fa8a9
@@ -1541,7 +1554,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
6fa8a9
       /* Find server to forward to. This will normally be the 
6fa8a9
 	 same as for the original query, but may be another if
6fa8a9
 	 servers for domains are involved. */		      
6fa8a9
-      if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL) != 0)
6fa8a9
+      if (search_servers(now, NULL, F_DNSSECOK, keyname, &type, &domain, NULL, NULL) != 0)
6fa8a9
 	{
6fa8a9
 	  new_status = STAT_ABANDONED;
6fa8a9
 	  break;
6fa8a9
@@ -1814,11 +1827,12 @@ unsigned char *tcp_request(int confd, time_t now,
6fa8a9
 	      int type = SERV_DO_DNSSEC;
6fa8a9
 	      char *domain = NULL;
6fa8a9
 	      unsigned char *oph = find_pseudoheader(header, size, NULL, NULL, NULL, NULL);
6fa8a9
+	      struct server_domain *sd = NULL;
6fa8a9
 
6fa8a9
 	      size = add_edns0_config(header, size, ((unsigned char *) header) + 65536, &peer_addr, now, &check_subnet);
6fa8a9
 
6fa8a9
 	      if (gotname)
6fa8a9
-		flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind);
6fa8a9
+		flags = search_servers(now, &addrp, gotname, daemon->namebuff, &type, &domain, &norebind, &sd);
6fa8a9
 
6fa8a9
 #ifdef HAVE_DNSSEC
6fa8a9
 	      if (option_bool(OPT_DNSSEC_VALID) && (type & SERV_DO_DNSSEC))
6fa8a9
@@ -1839,10 +1853,10 @@ unsigned char *tcp_request(int confd, time_t now,
6fa8a9
 
6fa8a9
 	      type &= ~SERV_DO_DNSSEC;
6fa8a9
 	      
6fa8a9
-	      if (type != 0  || option_bool(OPT_ORDER) || !daemon->last_server)
6fa8a9
+	      if (!sd  || option_bool(OPT_ORDER) || !sd->last_server)
6fa8a9
 		last_server = daemon->servers;
6fa8a9
 	      else
6fa8a9
-		last_server = daemon->last_server;
6fa8a9
+		last_server = sd->last_server;
6fa8a9
 	      
6fa8a9
 	      if (!flags && last_server)
6fa8a9
 		{
6fa8a9
@@ -2439,9 +2453,7 @@ void server_gone(struct server *server)
6fa8a9
     if (daemon->randomsocks[i].refcount != 0 && daemon->randomsocks[i].serv == server)
6fa8a9
       daemon->randomsocks[i].serv = NULL;
6fa8a9
 
6fa8a9
-  if (daemon->last_server == server)
6fa8a9
-    daemon->last_server = NULL;
6fa8a9
-
6fa8a9
+  /* last_server cleared by server_domain_cleanup */
6fa8a9
   if (daemon->srv_save == server)
6fa8a9
     daemon->srv_save = NULL;
6fa8a9
 }
6fa8a9
diff --git a/src/network.c b/src/network.c
6fa8a9
index 4eda1fd..4d140bb 100644
6fa8a9
--- a/src/network.c
6fa8a9
+++ b/src/network.c
6fa8a9
@@ -1428,6 +1428,29 @@ void cleanup_servers(void)
6fa8a9
 #endif
6fa8a9
 }
6fa8a9
 
6fa8a9
+void server_domains_cleanup(void)
6fa8a9
+{
6fa8a9
+  struct server_domain *sd, *tmp, **up;
6fa8a9
+
6fa8a9
+  /* unlink and free anything still marked. */
6fa8a9
+  for (up = &daemon->server_domains, sd=*up; sd; sd = tmp)
6fa8a9
+    {
6fa8a9
+      tmp = sd->next;
6fa8a9
+      if (sd->flags & SERV_MARK)
6fa8a9
+       {
6fa8a9
+         *up = sd->next;
6fa8a9
+         if (sd->domain)
6fa8a9
+	   free(sd->domain);
6fa8a9
+	 free(sd);
6fa8a9
+       }
6fa8a9
+      else {
6fa8a9
+        up = &sd->next;
6fa8a9
+        if (sd->last_server && (sd->last_server->flags & SERV_MARK))
6fa8a9
+	  sd->last_server = NULL;
6fa8a9
+      }
6fa8a9
+    }
6fa8a9
+}
6fa8a9
+
6fa8a9
 void add_update_server(int flags,
6fa8a9
 		       union mysockaddr *addr,
6fa8a9
 		       union mysockaddr *source_addr,
6fa8a9
@@ -1507,10 +1530,72 @@ void add_update_server(int flags,
6fa8a9
     }
6fa8a9
 }
6fa8a9
 
6fa8a9
+static const char *server_get_domain(const struct server *serv)
6fa8a9
+{
6fa8a9
+  const char *domain = serv->domain;
6fa8a9
+
6fa8a9
+  if (serv->flags & SERV_HAS_DOMAIN)
6fa8a9
+		  /* .example.com is valid */
6fa8a9
+    while (*domain == '.')
6fa8a9
+      domain++;
6fa8a9
+
6fa8a9
+  return domain;
6fa8a9
+}
6fa8a9
+
6fa8a9
+struct server_domain *server_domain_find_domain(const char *domain)
6fa8a9
+{
6fa8a9
+  struct server_domain *sd;
6fa8a9
+  for (sd = daemon->server_domains; sd; sd = sd->next)
6fa8a9
+    if ((!domain && sd->domain == domain) || (domain && sd->domain && hostname_isequal(domain, sd->domain)))
6fa8a9
+      return sd;
6fa8a9
+  return NULL;
6fa8a9
+}
6fa8a9
+
6fa8a9
+/**< Test structure has already set domain pointer.
6fa8a9
+ *
6fa8a9
+ * If not, create a new record. */
6fa8a9
+struct server_domain *server_domain_new(struct server *serv)
6fa8a9
+{
6fa8a9
+  struct server_domain *sd;
6fa8a9
+
6fa8a9
+  if ((sd = whine_malloc(sizeof(struct server_domain))))
6fa8a9
+    {
6fa8a9
+      const char *domain = server_get_domain(serv);
6fa8a9
+
6fa8a9
+      /* Ensure all serv->domain values have own record in server_domain.
6fa8a9
+       * Add a new record. */
6fa8a9
+      if (domain)
6fa8a9
+	{
6fa8a9
+	  size_t len = strlen(domain)+1;
6fa8a9
+	  sd->domain = whine_malloc(len);
6fa8a9
+	  if (sd->domain)
6fa8a9
+	    memcpy(sd->domain, domain, len);
6fa8a9
+	}
6fa8a9
+      sd->next = daemon->server_domains;
6fa8a9
+      serv->serv_domain = sd;
6fa8a9
+      daemon->server_domains = sd;
6fa8a9
+    }
6fa8a9
+  return sd;
6fa8a9
+}
6fa8a9
+
6fa8a9
+/**< Test structure has already set domain pointer.
6fa8a9
+ *
6fa8a9
+ * If not, create a new record. */
6fa8a9
+static void server_domain_check(struct server *serv)
6fa8a9
+{
6fa8a9
+  struct server_domain *sd = serv->serv_domain;
6fa8a9
+
6fa8a9
+  if (sd)
6fa8a9
+    sd->flags &= (~SERV_MARK); /* found domain, mark active */
6fa8a9
+  else
6fa8a9
+    server_domain_new(serv);
6fa8a9
+}
6fa8a9
+
6fa8a9
 void check_servers(void)
6fa8a9
 {
6fa8a9
   struct irec *iface;
6fa8a9
   struct server *serv;
6fa8a9
+  struct server_domain *sd;
6fa8a9
   struct serverfd *sfd, *tmp, **up;
6fa8a9
   int port = 0, count;
6fa8a9
   int locals = 0;
6fa8a9
@@ -1522,10 +1607,14 @@ void check_servers(void)
6fa8a9
   for (sfd = daemon->sfds; sfd; sfd = sfd->next)
6fa8a9
     sfd->used = 0;
6fa8a9
 
6fa8a9
+  for (sd = daemon->server_domains; sd; sd = sd->next)
6fa8a9
+    sd->flags |= SERV_MARK;
6fa8a9
+
6fa8a9
   for (count = 0, serv = daemon->servers; serv; serv = serv->next)
6fa8a9
     {
6fa8a9
       if (!(serv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)))
6fa8a9
 	{
6fa8a9
+
6fa8a9
 	  /* Init edns_pktsz for newly created server records. */
6fa8a9
 	  if (serv->edns_pktsz == 0)
6fa8a9
 	    serv->edns_pktsz = daemon->edns_pktsz;
6fa8a9
@@ -1541,12 +1630,8 @@ void check_servers(void)
6fa8a9
 	      if (serv->flags & SERV_HAS_DOMAIN)
6fa8a9
 		{
6fa8a9
 		  struct ds_config *ds;
6fa8a9
-		  char *domain = serv->domain;
6fa8a9
-		  
6fa8a9
-		  /* .example.com is valid */
6fa8a9
-		  while (*domain == '.')
6fa8a9
-		    domain++;
6fa8a9
-		  
6fa8a9
+		  const char *domain = server_get_domain(serv);
6fa8a9
+
6fa8a9
 		  for (ds = daemon->ds; ds; ds = ds->next)
6fa8a9
 		    if (ds->name[0] != 0 && hostname_isequal(domain, ds->name))
6fa8a9
 		      break;
6fa8a9
@@ -1556,7 +1641,6 @@ void check_servers(void)
6fa8a9
 		}
6fa8a9
 	    }
6fa8a9
 #endif
6fa8a9
-
6fa8a9
 	  port = prettyprint_addr(&serv->addr, daemon->namebuff);
6fa8a9
 	  
6fa8a9
 	  /* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
6fa8a9
@@ -1591,6 +1675,8 @@ void check_servers(void)
6fa8a9
 	  
6fa8a9
 	  if (serv->sfd)
6fa8a9
 	    serv->sfd->used = 1;
6fa8a9
+
6fa8a9
+	  server_domain_check(serv);
6fa8a9
 	}
6fa8a9
       
6fa8a9
       if (!(serv->flags & SERV_NO_REBIND) && !(serv->flags & SERV_LITERAL_ADDRESS))
6fa8a9
@@ -1653,6 +1739,7 @@ void check_servers(void)
6fa8a9
 	up = &sfd->next;
6fa8a9
     }
6fa8a9
   
6fa8a9
+  server_domains_cleanup();
6fa8a9
   cleanup_servers();
6fa8a9
 }
6fa8a9
 
6fa8a9
diff --git a/src/option.c b/src/option.c
6fa8a9
index abc5a48..6fa7bbd 100644
6fa8a9
--- a/src/option.c
6fa8a9
+++ b/src/option.c
6fa8a9
@@ -906,6 +906,7 @@ static struct server *add_rev4(struct in_addr addr, int msize)
6fa8a9
   p += sprintf(p, "in-addr.arpa");
6fa8a9
   
6fa8a9
   serv->flags = SERV_HAS_DOMAIN;
6fa8a9
+  server_domain_new(serv);
6fa8a9
   serv->next = daemon->servers;
6fa8a9
   daemon->servers = serv;
6fa8a9
 
6fa8a9
@@ -930,6 +931,7 @@ static struct server *add_rev6(struct in6_addr *addr, int msize)
6fa8a9
   p += sprintf(p, "ip6.arpa");
6fa8a9
   
6fa8a9
   serv->flags = SERV_HAS_DOMAIN;
6fa8a9
+  server_domain_new(serv);
6fa8a9
   serv->next = daemon->servers;
6fa8a9
   daemon->servers = serv;
6fa8a9
   
6fa8a9
@@ -2231,6 +2233,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
6fa8a9
 				  memset(serv, 0, sizeof(struct server));
6fa8a9
 				  serv->domain = d;
6fa8a9
 				  serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
6fa8a9
+				  server_domain_new(serv);
6fa8a9
 				  serv->next = daemon->servers;
6fa8a9
 				  daemon->servers = serv;
6fa8a9
 				}
6fa8a9
@@ -2275,6 +2278,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
6fa8a9
 				  memset(serv, 0, sizeof(struct server));
6fa8a9
 				  serv->domain = d;
6fa8a9
 				  serv->flags = SERV_HAS_DOMAIN | SERV_NO_ADDR;
6fa8a9
+				  server_domain_new(serv);
6fa8a9
 				  serv->next = daemon->servers;
6fa8a9
 				  daemon->servers = serv;
6fa8a9
 				}
6fa8a9
@@ -2525,6 +2529,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
6fa8a9
 		newlist = serv;
6fa8a9
 		serv->domain = domain;
6fa8a9
 		serv->flags = domain ? SERV_HAS_DOMAIN : SERV_FOR_NODOTS;
6fa8a9
+		server_domain_new(serv);
6fa8a9
 		arg = end;
6fa8a9
 		if (rebind)
6fa8a9
 		  break;
6fa8a9
-- 
6fa8a9
2.34.1
6fa8a9