BUG/MINOR: log: fix logging to both FD and IP
PiBa-NL reported an issue affecting logs when stdout is enabled at the same time as an IP address. It does not affect FD and UNIX, but does still affect multiple FDs. What happens is that the condition to detect that the initialization was not made relies on the FD being -1, and in this case the FD points to the *unique* FD used for AF_INET sockets, so the configured socket used for outgoing logs over UDP gets overwritten by the last configured FD. This is not appropriate, so instead we rely on the sin_port part of the IPv4-mapped address to store the initialization state for each FD. This part deserves being significantly revamped, as IPv6 is still not possible due to the way the FDs are managed, and inherited FDs are a bit hackish. Note that this patch relies on "MINOR: tools: preset the port of fd-based "sockets" to zero" in order to operate properly. No backport is needed.
This commit is contained in:
parent
0205a4e0b5
commit
204e3f1fab
26
src/log.c
26
src/log.c
|
@ -1355,8 +1355,7 @@ void __send_log(struct proxy *p, int level, char *message, size_t size, char *sd
|
|||
nblogger = 0;
|
||||
list_for_each_entry(tmp, logsrvs, list) {
|
||||
const struct logsrv *logsrv = tmp;
|
||||
int *plogfd = logsrv->addr.ss_family == AF_UNIX ?
|
||||
&logfdunix : &logfdinet;
|
||||
int *plogfd;
|
||||
char *pid_sep1 = "", *pid_sep2 = "";
|
||||
char logheader_short[3];
|
||||
int sent;
|
||||
|
@ -1375,15 +1374,24 @@ void __send_log(struct proxy *p, int level, char *message, size_t size, char *sd
|
|||
if (level > logsrv->level)
|
||||
continue;
|
||||
|
||||
if (logsrv->addr.ss_family == AF_UNSPEC) {
|
||||
/* the socket's address is a file descriptor */
|
||||
plogfd = (int *)&((struct sockaddr_in *)&logsrv->addr)->sin_addr.s_addr;
|
||||
if (unlikely(!((struct sockaddr_in *)&logsrv->addr)->sin_port)) {
|
||||
/* FD not yet initialized to non-blocking mode */
|
||||
fcntl(*plogfd, F_SETFL, O_NONBLOCK);
|
||||
((struct sockaddr_in *)&logsrv->addr)->sin_port = 1;
|
||||
}
|
||||
}
|
||||
else if (logsrv->addr.ss_family == AF_UNIX)
|
||||
plogfd = &logfdunix;
|
||||
else
|
||||
plogfd = &logfdinet;
|
||||
|
||||
if (unlikely(*plogfd < 0)) {
|
||||
/* socket not successfully initialized yet */
|
||||
if (logsrv->addr.ss_family == AF_UNSPEC) {
|
||||
/* the socket's address is a file descriptor */
|
||||
*plogfd = ((struct sockaddr_in *)&logsrv->addr)->sin_addr.s_addr;
|
||||
fcntl(*plogfd, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
else if ((*plogfd = socket(logsrv->addr.ss_family, SOCK_DGRAM,
|
||||
(logsrv->addr.ss_family == AF_UNIX) ? 0 : IPPROTO_UDP)) < 0) {
|
||||
if ((*plogfd = socket(logsrv->addr.ss_family, SOCK_DGRAM,
|
||||
(logsrv->addr.ss_family == AF_UNIX) ? 0 : IPPROTO_UDP)) < 0) {
|
||||
static char once;
|
||||
|
||||
if (!once) {
|
||||
|
|
Loading…
Reference in New Issue