MEDIUM: log/balance: support FQDN for UDP log servers

In previous log backend implementation, we created a pseudo log target
for each declared log server, and we made the log target's address point
to the actual server address to save some time and prevent unecessary
copies.

But this was done without knowing that when FQDN is involved (more broadly
when dns/resolution is involved), the "port" part of server addr should
not be relied upon, and we should explicitly use ->svc_port for that
purpose.

With that in mind and thanks to the previous commit, some changes were
required: we allocate a dedicated addr within the log target when target
is in DGRAM mode. The addr is first initialized with known values and it
is then updated automatically by _srv_set_inetaddr() during runtime.
(the change is atomic so readers don't need to worry about it)

addr from server "log target" (INET/DGRAM mode) is made of the combination
of server's address (lacking the port part) and server's svc_port.
This commit is contained in:
Aurelien DARRAGON 2023-11-09 16:57:01 +01:00 committed by Christopher Faulet
parent cd994407a9
commit 2f2cb6d082
3 changed files with 34 additions and 14 deletions

View File

@ -91,6 +91,7 @@ int postresolve_logger_list(struct list *loggers, const char *section, const cha
struct logger *dup_logger(struct logger *def);
void free_logger(struct logger *logger);
void deinit_log_target(struct log_target *target);
/* Parse "log" keyword and update the linked list. */
int parse_logger(char **args, struct list *loggers, int do_del, const char *file, int linenum, char **err);

View File

@ -745,7 +745,7 @@ static inline void init_log_target(struct log_target *target)
target->resolv_name = NULL;
}
static void deinit_log_target(struct log_target *target)
void deinit_log_target(struct log_target *target)
{
ha_free(&target->addr);
if (!(target->flags & LOG_TARGET_FL_RESOLVED))
@ -1054,15 +1054,33 @@ static int postcheck_log_backend(struct proxy *be)
err_code |= ERR_ALERT | ERR_FATAL;
goto end;
}
srv->log_target->addr = &srv->addr;
if (srv->addr_type.proto_type == PROTO_TYPE_DGRAM)
init_log_target(srv->log_target);
if (srv->addr_type.proto_type == PROTO_TYPE_DGRAM) {
srv->log_target->type = LOG_TARGET_DGRAM;
/* Try to allocate log target addr (only used in DGRAM mode) */
srv->log_target->addr = calloc(1, sizeof(*srv->log_target->addr));
if (!srv->log_target->addr) {
memprintf(&msg, "memory error when allocating log server '%s'\n", srv->id);
err_code |= ERR_ALERT | ERR_FATAL;
goto end;
}
/* We must initialize it with known addr:svc_port, it will then
* be updated automatically by the server API for runtime changes
*/
ipcpy(&srv->addr, srv->log_target->addr);
set_host_port(srv->log_target->addr, srv->svc_port);
}
else {
/* for now BUFFER type only supports TCP server to it's almost
* explicit. This will require ring buffer creation during log
* postresolving step.
* explicit
*/
srv->log_target->type = LOG_TARGET_BUFFER;
srv->log_target->sink = sink_new_from_srv(srv, "log backend");
if (!srv->log_target->sink) {
memprintf(&msg, "error when creating sink from '%s' log server", srv->id);
err_code |= ERR_ALERT | ERR_FATAL;
goto end;
}
}
if (target_type == -1)
@ -1073,14 +1091,7 @@ static int postcheck_log_backend(struct proxy *be)
err_code |= ERR_ALERT | ERR_FATAL;
goto end;
}
if (target_type == LOG_TARGET_BUFFER) {
srv->log_target->sink = sink_new_from_srv(srv, "log backend");
if (!srv->log_target->sink) {
memprintf(&msg, "error when creating sink from '%s' log server", srv->id);
err_code |= ERR_ALERT | ERR_FATAL;
goto end;
}
}
srv->log_target->flags |= LOG_TARGET_FL_RESOLVED;
srv->cur_eweight = 1; /* ignore weights, all servers have the same weight */
_log_backend_srv_queue(srv);
srv = srv->next;

View File

@ -177,6 +177,11 @@ void _srv_set_inetaddr(struct server *srv, const struct sockaddr_storage *addr,
{
ipcpy(addr, &srv->addr);
srv->svc_port = svc_port;
if (srv->log_target && srv->log_target->type == LOG_TARGET_DGRAM) {
/* server is used as a log target, manually update log target addr for DGRAM */
ipcpy(addr, srv->log_target->addr);
set_host_port(srv->log_target->addr, svc_port);
}
}
/*
@ -2819,7 +2824,10 @@ void srv_free_params(struct server *srv)
free(srv->resolvers_id);
free(srv->addr_node.key);
free(srv->lb_nodes);
free(srv->log_target);
if (srv->log_target) {
deinit_log_target(srv->log_target);
free(srv->log_target);
}
if (xprt_get(XPRT_SSL) && xprt_get(XPRT_SSL)->destroy_srv)
xprt_get(XPRT_SSL)->destroy_srv(srv);