From: Daniel Salzman Date: Wed, 24 Sep 2025 14:28:18 +0000 (+0200) Subject: redis: add support for hostname listen specification X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b7ab32fcae5559ed889e344dd825e8e4cb0da9be;p=thirdparty%2Fknot-dns.git redis: add support for hostname listen specification --- diff --git a/doc/reference.rst b/doc/reference.rst index 4a1c05c17b..f0e918f260 100644 --- a/doc/reference.rst +++ b/doc/reference.rst @@ -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 diff --git a/src/knot/common/hiredis.c b/src/knot/common/hiredis.c index 0590687b4b..c25c108711 100644 --- a/src/knot/common/hiredis.c +++ b/src/knot/common/hiredis.c @@ -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);