On Sun, Nov 20, 2022 at 01:50:10PM +0800, Ye Zhou wrote:
> Hi all,
> 
> I'm attaching a patch to optimize a speed issue introduced in version 2.86.
 
Now is the patch attached 

> I have two ISP upstreams and need to forward different sites to different
> ISP's DNS providers. For example:
> 
> server=/meituan.com/114.114.114.114
> ... (lots of records)
> server=/taobao.com/223.5.5.5
> ... (lots of records)
> 
> It works well before v2.86. Since v2.86 the configuration load time becomes
> extremely long (more than 1 minutes to load all server records). The time
> consuming part is inside the rewritten domain-match.c. When adding a new
> server record, the code will traverse all existing records so the
> configuration load becomes quadratic time complexity. The issue still
> persists on v2.88rc3.
> This patch will optimize the config load time by bypassing the time
> consuming code block. During the config load mark_servers() will never be
> called so does not need to waste time on the record traversal and re-order
> part.
> 
> Before:
> dnsmasq --test  77.50s user 0.30s system 99% cpu 1:17.84 total
> After:
> dnsmasq --test  0.16s user 0.02s system 99% cpu 0.188 total
> 
> https://gist.github.com/zhouye/adfd509f51645d314f53992331449c45

<screenshot documents="What the F">
stappers@alpaca:~/src/dnsmasq
$ wget -O fastreload.patch 
https://gist.github.com/zhouye/adfd509f51645d314f53992331449c45
--2022-11-20 08:23:57--  
https://gist.github.com/zhouye/adfd509f51645d314f53992331449c45
Resolving gist.github.com (gist.github.com)... 140.82.121.3
Connecting to gist.github.com (gist.github.com)|140.82.121.3|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: 'fastreload.patch'

fastreload.patch          [ <=>                             ]  91.26K  --.-KB/s 
   in 0.07s

2022-11-20 08:23:59 (1.30 MB/s) - 'fastreload.patch' saved [93447]

stappers@alpaca:~/src/dnsmasq
$ file fastreload.patch
fastreload.patch: HTML document, UTF-8 Unicode text, with very long lines
stappers@alpaca:~/src/dnsmasq
$
<screenshot>

curl --silent 
https://gist.githubusercontent.com/zhouye/adfd509f51645d314f53992331449c45/raw/3d948c9b4e7eac419a3c669ffba59b84341b4577/dnsmasq-server-fix.diff


diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 90dc986..5aaffcc 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1144,6 +1144,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, *servers_tail, *local_domains, **serverarray;
+  int servers_flag;
   struct rebind_domain *no_rebind;
   int server_has_wildcard;
   int serverarraysz, serverarrayhwm;
diff --git a/src/domain-match.c b/src/domain-match.c
index 76a1109..56ae015 100644
--- a/src/domain-match.c
+++ b/src/domain-match.c
@@ -552,6 +552,7 @@ void mark_servers(int flag)
   struct server *serv, **up;
 
   daemon->servers_tail = NULL;
+  daemon->servers_flag = flag;
   
   /* mark everything with argument flag */
   for (serv = daemon->servers; serv; serv = serv->next)
@@ -602,6 +603,8 @@ void cleanup_servers(void)
          daemon->servers_tail = serv;
        }
     }
+
+  daemon->servers_flag = 0;
 }
 
 int add_update_server(int flags,
@@ -663,29 +666,32 @@ int add_update_server(int flags,
     }
   else
     { 
-      /* Upstream servers. See if there is a suitable candidate, if so unmark
-        and move to the end of the list, for order. The entry found may already
-        be at the end. */
-      struct server **up, *tmp;
-      
-      for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
+      if (daemon->servers_flag)
        {
-         tmp = serv->next;
-         if ((serv->flags & SERV_MARK) &&
-             hostname_isequal(alloc_domain, serv->domain))
+         /* Upstream servers. See if there is a suitable candidate, if so 
unmark
+           and move to the end of the list, for order. The entry found may 
already
+           be at the end. */
+         struct server **up, *tmp;
+         
+         for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp)
            {
-             /* Need to move down? */
-             if (serv->next)
+             tmp = serv->next;
+             if ((serv->flags & SERV_MARK) &&
+                 hostname_isequal(alloc_domain, serv->domain))
                {
-                 *up = serv->next;
-                 daemon->servers_tail->next = serv;
-                 daemon->servers_tail = serv;
-                 serv->next = NULL;
+                 /* Need to move down? */
+                 if (serv->next)
+                   {
+                     *up = serv->next;
+                     daemon->servers_tail->next = serv;
+                     daemon->servers_tail = serv;
+                     serv->next = NULL;
+                   }
+                 break;
                }
-             break;
+             else
+               up = &serv->next;
            }
-         else
-           up = &serv->next;
        }
 
       if (serv)


Groeten
Geert Stappers
-- 
Silence is hard to parse

_______________________________________________
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
https://lists.thekelleys.org.uk/cgi-bin/mailman/listinfo/dnsmasq-discuss

Reply via email to