redis: add support for hostname listen specification

This commit is contained in:
Daniel Salzman 2025-09-24 16:28:18 +02:00
parent c038963d50
commit b7ab32fcae
2 changed files with 35 additions and 10 deletions

View 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

View 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);