From d65ce73762da889f586918dcf7f2aad8549976af Mon Sep 17 00:00:00 2001
From: Martin Weinelt <martin@darmstadt.freifunk.net>
Date: Sun, 15 Jan 2023 20:46:23 +0100
Subject: [PATCH] Revert "gluon-core: remove DNS cache feature"

This reverts commit 543eb178824e8ed8a6f385fe1ebdf0d7ca709be3.

Restores the dns caching configuration that should be feasible, since we
now require around 8 MB of flash.
---
 docs/features/dns-cache.rst                   | 52 +++++++++++++++++++
 docs/features/dns-forwarder.rst               | 26 ----------
 docs/index.rst                                |  2 +-
 docs/releases/v2017.1.rst                     |  2 +
 package/gluon-core/check_site.lua             |  1 +
 .../luasrc/lib/gluon/upgrade/820-dns-config   |  2 +-
 6 files changed, 57 insertions(+), 28 deletions(-)
 create mode 100644 docs/features/dns-cache.rst
 delete mode 100644 docs/features/dns-forwarder.rst

diff --git a/docs/features/dns-cache.rst b/docs/features/dns-cache.rst
new file mode 100644
index 000000000..0a42e1104
--- /dev/null
+++ b/docs/features/dns-cache.rst
@@ -0,0 +1,52 @@
+DNS caching
+===========
+
+User experience may be greatly improved when dns is accelerated. Also, it
+seems like a good idea to keep the number of packages being exchanged
+between node and gateway as small as possible. In order to do this, a
+DNS cache may be used on a node. The dnsmasq instance listening on port
+53 on the node will be reconfigured to answer requests, use a list of
+upstream servers and a specific cache size if the options listed below are
+added to site.conf. Upstream servers are the DNS servers which are normally
+used by the nodes to resolve hostnames (e.g. gateways/supernodes).
+
+There are the following settings:
+    servers
+    cacheentries
+
+To use the node's DNS server, both options should be set. The node will cache at
+most 'cacheentries' many DNS records in RAM. The 'servers' list will be used to
+resolve the received DNS queries if the request cannot be answered from
+cache. Gateways should announce the "next node" address via DHCP and RDNSS (if
+any). Note that not setting 'servers' here will lead to DNS not working: Once
+the gateways all announce the "next node" address for DNS, there is no way for
+nodes to automatically determine DNS servers. They have to be baked into the
+firmware.
+
+If these settings do not exist, the cache is not initialized and RAM usage will
+not increase.
+
+When next_node.name is set, an A record and an AAAA record for the
+next-node IP address are placed in the dnsmasq configuration. This means that
+the content of next_node.name may be resolved even without upstream connectivity.
+It is suggested to use the same name as the DNS server provides:
+e.g. nextnode.location.community.example.org (This way the name also works if a
+client uses static DNS Servers). Hint: If next_node.name does not contain a dot
+some browsers would open the searchpage instead.
+
+::
+
+  dns = {
+    cacheentries = 5000,
+    servers = { '2001:db8::1', },
+  },
+
+  next_node = {
+    name = { 'nextnode.location.community.example.org', 'nextnode', 'nn' },
+    ip6 = '2001:db8:8::1',
+    ip4 = '198.51.100.1',
+  }
+
+
+The cache will be initialized during startup.
+Each cache entry will occupy about 90 bytes of RAM.
diff --git a/docs/features/dns-forwarder.rst b/docs/features/dns-forwarder.rst
deleted file mode 100644
index d74f9618f..000000000
--- a/docs/features/dns-forwarder.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-DNS forwarder
-=============
-
-A Gluon node can be configured to act as a DNS forwarder. Requests for the
-next-node hostname(s) can be answered locally, without querying the upstream
-resolver.
-
-**Note:** While this reduces answer time and allows to use the next-node
-hostname without upstream connectivity, this feature should not be used for
-next-node hostnames that are FQDN when the zone uses DNSSEC.
-
-One or more upstream resolvers can be configured in the *dns.servers* setting.
-When *next_node.name* is set, A and/or AAAA records for the next-node IP
-addresses are placed in the dnsmasq configuration.
-
-::
-
-  dns = {
-    servers = { '2001:db8::1', },
-  },
-
-  next_node = {
-    name = { 'nextnode.location.community.example.org', 'nextnode', 'nn' },
-    ip6 = '2001:db8:8::1',
-    ip4 = '198.51.100.1',
-  }
diff --git a/docs/index.rst b/docs/index.rst
index c9bcbdb30..99fc8535f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -25,7 +25,7 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
   features/wlan-configuration
   features/private-wlan
   features/wired-mesh
-  features/dns-forwarder
+  features/dns-cache
   features/monitoring
   features/multidomain
   features/authorized-keys
diff --git a/docs/releases/v2017.1.rst b/docs/releases/v2017.1.rst
index 9e8e72c9c..5319aae3c 100644
--- a/docs/releases/v2017.1.rst
+++ b/docs/releases/v2017.1.rst
@@ -88,6 +88,8 @@ New features
 * Add support for making nodes a DNS cache for clients
   (`#1000 <https://github.com/freifunk-gluon/gluon/pull/1000>`_)
 
+  See also: :doc:`../features/dns-cache`
+
 * Add L2TP via tunneldigger as an alternative VPN system
   (`#978 <https://github.com/freifunk-gluon/gluon/pull/978>`_)
 
diff --git a/package/gluon-core/check_site.lua b/package/gluon-core/check_site.lua
index 103cb929d..06b9ac59d 100644
--- a/package/gluon-core/check_site.lua
+++ b/package/gluon-core/check_site.lua
@@ -66,6 +66,7 @@ need_boolean(in_site({'poe_passthrough'}), false)
 
 if need_table({'dns'}, nil, false) then
 	need_string_array_match({'dns', 'servers'}, '^[%x:]+$')
+	need_number({'dns', 'cacheentries'}, false)
 end
 
 need_string_array(in_domain({'next_node', 'name'}), false)
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config b/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config
index f3fdfbff7..0db663013 100755
--- a/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config
@@ -12,7 +12,7 @@ uci:set('dhcp', dnsmasq, 'localise_queries', true)
 uci:set('dhcp', dnsmasq, 'localservice', false)
 
 uci:set('dhcp', dnsmasq, 'server', dns.servers)
-uci:delete('dhcp', dnsmasq, 'cachesize')
+uci:set('dhcp', dnsmasq, 'cachesize', dns.cacheentries)
 
 uci:delete('firewall', 'client_dns')
 if dns.servers then
-- 
GitLab