BUG/MINOR: log: properly format IPv6 address when LOG_OPT_HEXA modifier is used.

In lf_ip(), when LOG_OPT_HEXA modifier is used, there is a code to format the
IP address as a hexadecimal string. This code does not properly handle cases
when the IP address is IPv6. In such case, the code only prints `00000000`.

This patch adds support for IPv6. For legacy IPv4, the format remains
unchanged. If IPv6 socket is used to accept IPv6 connection, the full IPv6
address is returned. For example, IPv6 localhost, ::1, is printed as
00000000000000000000000000000001.

If IPv6 socket accepts IPv4 connection, the IPv4 address is mapped by the
kernel into the IPv4-mapped-IPv6 address space (RFC4291, section 2.5.5.2)
and is formatted as such. For example, 127.0.0.1 becomes ::ffff:127.0.0.1,
which is printed as 00000000000000000000FFFF7F000001.

This should be backported to 1.9.
This commit is contained in:
Radek Zajic 2019-03-22 10:21:54 +00:00 committed by Willy Tarreau
parent bc34cd1de2
commit 594c456d14

View File

@ -1153,8 +1153,21 @@ char *lf_ip(char *dst, const struct sockaddr *sockaddr, size_t size, const struc
char pn[INET6_ADDRSTRLEN];
if (node->options & LOG_OPT_HEXA) {
const unsigned char *addr = (const unsigned char *)&((struct sockaddr_in *)sockaddr)->sin_addr.s_addr;
iret = snprintf(dst, size, "%02X%02X%02X%02X", addr[0], addr[1], addr[2], addr[3]);
unsigned char *addr = NULL;
switch (sockaddr->sa_family) {
case AF_INET:
addr = (unsigned char *)&((struct sockaddr_in *)sockaddr)->sin_addr.s_addr;
iret = snprintf(dst, size, "%02X%02X%02X%02X", addr[0], addr[1], addr[2], addr[3]);
break;
case AF_INET6:
addr = (unsigned char *)&((struct sockaddr_in6 *)sockaddr)->sin6_addr.s6_addr;
iret = snprintf(dst, size, "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], addr[6], addr[7],
addr[8], addr[9], addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]);
break;
default:
return NULL;
}
if (iret < 0 || iret > size)
return NULL;
ret += iret;