]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
redis: add support for hostname listen specification
authorDaniel Salzman <daniel.salzman@nic.cz>
Wed, 24 Sep 2025 14:28:18 +0000 (16:28 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Wed, 15 Oct 2025 11:50:01 +0000 (13:50 +0200)
doc/reference.rst
src/knot/common/hiredis.c

index 4a1c05c17bd5d48017afb3b6748d17d96f8a88b6..f0e918f260341568064198ef774a1ea2e67db5e4 100644 (file)
@@ -1214,7 +1214,7 @@ Configuration of databases for zone contents, DNSSEC metadata, or event timers.
      timer-db-max-size: SIZE
      catalog-db: str
      catalog-db-max-size: SIZE
-     zone-db-listen: ADDR[@INT] | STR
+     zone-db-listen: ADDR[@INT] | STR[@INT]
      zone-db-tls: BOOL
      zone-db-cert-key: BASE64 ...
      zone-db-cert-hostname: STR ...
@@ -1348,9 +1348,10 @@ The hard limit for the catalog database maximum size.
 zone-db-listen
 --------------
 
-An IP address (and optionally a port) or a UNIX socket path of a running
-instance of a Redis (or compatible) database to be used for reading and/or
-writing zone contents. See :ref:`zone_zone-db-input` and :ref:`zone_zone-db-output`.
+An IP address or a hostname and optionally a port (default is 6379) or an
+absolute UNIX socket path (starting with ``/``) of a running instance of
+a Redis (or compatible) database to be used for reading and/or writing zone
+contents. See :ref:`zone_zone-db-input` and :ref:`zone_zone-db-output`.
 
 *Default:* not set
 
index 0590687b4ba0625cb69632d6d8bcadd1e7f662be..c25c108711499d8d5f94c14cb317c4a9119f6042 100644 (file)
@@ -5,7 +5,9 @@
 
 #include "knot/common/hiredis.h"
 #include "contrib/conn_pool.h"
+#include "contrib/openbsd/strlcpy.h"
 #include "contrib/sockaddr.h"
+#include "contrib/strtonum.h"
 #include "knot/common/log.h"
 #include "libknot/errcode.h"
 
@@ -139,17 +141,39 @@ redisContext *rdb_connect(conf_t *conf)
                return rdb;
        }
 
-       int port = sockaddr_port(&addr);
-       sockaddr_port_set(&addr, 0);
-
+       int port = 0;
        char addr_str[SOCKADDR_STRLEN];
-       if (sockaddr_tostr(addr_str, sizeof(addr_str), &addr) <= 0) {
-               return NULL;
+
+       if (addr.ss_family == AF_UNIX) {
+               const char *path = ((struct sockaddr_un *)&addr)->sun_path;
+               if (path[0] != '/') { // hostname
+                       strlcpy(addr_str, path, sizeof(addr_str));
+
+                       char *port_sep = strchr(addr_str, '@');
+                       if (port_sep != NULL) {
+                               *port_sep = '\0';
+                               uint16_t num;
+                               int ret = str_to_u16(port_sep + 1, &num);
+                               if (ret != KNOT_EOK || num == 0) {
+                                       return NULL;
+                               }
+                               port = num;
+                       } else {
+                               port = CONF_REDIS_PORT;
+                       }
+               }
+       } else {
+               port = sockaddr_port(&addr);
+               sockaddr_port_set(&addr, 0);
+
+               if (sockaddr_tostr(addr_str, sizeof(addr_str), &addr) <= 0) {
+                       return NULL;
+               }
        }
 
        const struct timeval timeout = { 10, 0 };
 
-       if (addr.ss_family == AF_UNIX) {
+       if (port == 0) {
                rdb = redisConnectUnixWithTimeout(addr_str, timeout);
        } else {
                rdb = redisConnectWithTimeout(addr_str, port, timeout);