support_format_addrinfo: Fix flags and canonname formatting
The address family splitting via format_ai_family made unpredictable the place where the canonname field was printed. This commit adjusts the implementation so that the ai_flags is checked for consistency across the list, and ai_canonname must only be present on the first list element. Tests for AI_CANONNAME are added to resolv/tst-resolv-basic.
This commit is contained in:
parent
46ce8881ad
commit
8ec69bb7ec
16
ChangeLog
16
ChangeLog
@ -1,3 +1,19 @@
|
|||||||
|
2017-05-11 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
* support/support_format_addrinfo.c (format_ai_flags_1): Renamed
|
||||||
|
from format_ai_flags.
|
||||||
|
(format_ai_flags): New function. Incorporate flag formatting code
|
||||||
|
from format_ai_one.
|
||||||
|
(format_ai_canonname): New function.
|
||||||
|
(format_ai_one): Remove flags parameter.
|
||||||
|
(format_ai_family): Likewise.
|
||||||
|
(support_format_addrinfo): Call format_ai_flags,
|
||||||
|
format_ai_canonname.
|
||||||
|
* resolv/tst-resolv-basic.c (check_ai_hints): Extracted from
|
||||||
|
check_ai.
|
||||||
|
(check_ai): Call check_ai_hints.
|
||||||
|
(do_test): Add AI_CANONNAME tests.
|
||||||
|
|
||||||
2017-05-11 Florian Weimer <fweimer@redhat.com>
|
2017-05-11 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
* sysdeps/posix/getaddrinfo.c (gethosts): Remove malloc_addrmem.
|
* sysdeps/posix/getaddrinfo.c (gethosts): Remove malloc_addrmem.
|
||||||
|
@ -182,12 +182,12 @@ check_h (const char *name, int family, const char *expected)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_ai (const char *name, const char *service,
|
check_ai_hints (const char *name, const char *service,
|
||||||
int family, const char *expected)
|
struct addrinfo hints, const char *expected)
|
||||||
{
|
{
|
||||||
struct addrinfo hints = {.ai_family = family};
|
|
||||||
struct addrinfo *ai;
|
struct addrinfo *ai;
|
||||||
char *query = xasprintf ("%s:%s [%d]", name, service, family);
|
char *query = xasprintf ("%s:%s [%d]/0x%x", name, service,
|
||||||
|
hints.ai_family, hints.ai_flags);
|
||||||
int ret = getaddrinfo (name, service, &hints, &ai);
|
int ret = getaddrinfo (name, service, &hints, &ai);
|
||||||
check_addrinfo (query, ai, ret, expected);
|
check_addrinfo (query, ai, ret, expected);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
@ -195,6 +195,15 @@ check_ai (const char *name, const char *service,
|
|||||||
free (query);
|
free (query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_ai (const char *name, const char *service,
|
||||||
|
int family, const char *expected)
|
||||||
|
{
|
||||||
|
return check_ai_hints (name, service,
|
||||||
|
(struct addrinfo) { .ai_family = family, },
|
||||||
|
expected);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_test (void)
|
do_test (void)
|
||||||
{
|
{
|
||||||
@ -229,6 +238,17 @@ do_test (void)
|
|||||||
"address: STREAM/TCP 2001:db8::1 80\n"
|
"address: STREAM/TCP 2001:db8::1 80\n"
|
||||||
"address: DGRAM/UDP 2001:db8::1 80\n"
|
"address: DGRAM/UDP 2001:db8::1 80\n"
|
||||||
"address: RAW/IP 2001:db8::1 80\n");
|
"address: RAW/IP 2001:db8::1 80\n");
|
||||||
|
check_ai_hints ("www.example", "80",
|
||||||
|
(struct addrinfo) { .ai_family = AF_UNSPEC,
|
||||||
|
.ai_flags = AI_CANONNAME, },
|
||||||
|
"flags: AI_CANONNAME\n"
|
||||||
|
"canonname: www.example\n"
|
||||||
|
"address: STREAM/TCP 192.0.2.17 80\n"
|
||||||
|
"address: DGRAM/UDP 192.0.2.17 80\n"
|
||||||
|
"address: RAW/IP 192.0.2.17 80\n"
|
||||||
|
"address: STREAM/TCP 2001:db8::1 80\n"
|
||||||
|
"address: DGRAM/UDP 2001:db8::1 80\n"
|
||||||
|
"address: RAW/IP 2001:db8::1 80\n");
|
||||||
check_ai ("alias.example", "80", AF_UNSPEC,
|
check_ai ("alias.example", "80", AF_UNSPEC,
|
||||||
"address: STREAM/TCP 192.0.2.18 80\n"
|
"address: STREAM/TCP 192.0.2.18 80\n"
|
||||||
"address: DGRAM/UDP 192.0.2.18 80\n"
|
"address: DGRAM/UDP 192.0.2.18 80\n"
|
||||||
@ -236,6 +256,17 @@ do_test (void)
|
|||||||
"address: STREAM/TCP 2001:db8::2 80\n"
|
"address: STREAM/TCP 2001:db8::2 80\n"
|
||||||
"address: DGRAM/UDP 2001:db8::2 80\n"
|
"address: DGRAM/UDP 2001:db8::2 80\n"
|
||||||
"address: RAW/IP 2001:db8::2 80\n");
|
"address: RAW/IP 2001:db8::2 80\n");
|
||||||
|
check_ai_hints ("alias.example", "80",
|
||||||
|
(struct addrinfo) { .ai_family = AF_UNSPEC,
|
||||||
|
.ai_flags = AI_CANONNAME, },
|
||||||
|
"flags: AI_CANONNAME\n"
|
||||||
|
"canonname: www.example\n"
|
||||||
|
"address: STREAM/TCP 192.0.2.18 80\n"
|
||||||
|
"address: DGRAM/UDP 192.0.2.18 80\n"
|
||||||
|
"address: RAW/IP 192.0.2.18 80\n"
|
||||||
|
"address: STREAM/TCP 2001:db8::2 80\n"
|
||||||
|
"address: DGRAM/UDP 2001:db8::2 80\n"
|
||||||
|
"address: RAW/IP 2001:db8::2 80\n");
|
||||||
check_ai (LONG_NAME, "80", AF_UNSPEC,
|
check_ai (LONG_NAME, "80", AF_UNSPEC,
|
||||||
"address: STREAM/TCP 192.0.2.20 80\n"
|
"address: STREAM/TCP 192.0.2.20 80\n"
|
||||||
"address: DGRAM/UDP 192.0.2.20 80\n"
|
"address: DGRAM/UDP 192.0.2.20 80\n"
|
||||||
@ -247,10 +278,26 @@ do_test (void)
|
|||||||
"address: STREAM/TCP 192.0.2.17 80\n"
|
"address: STREAM/TCP 192.0.2.17 80\n"
|
||||||
"address: DGRAM/UDP 192.0.2.17 80\n"
|
"address: DGRAM/UDP 192.0.2.17 80\n"
|
||||||
"address: RAW/IP 192.0.2.17 80\n");
|
"address: RAW/IP 192.0.2.17 80\n");
|
||||||
|
check_ai_hints ("www.example", "80",
|
||||||
|
(struct addrinfo) { .ai_family = AF_INET,
|
||||||
|
.ai_flags = AI_CANONNAME, },
|
||||||
|
"flags: AI_CANONNAME\n"
|
||||||
|
"canonname: www.example\n"
|
||||||
|
"address: STREAM/TCP 192.0.2.17 80\n"
|
||||||
|
"address: DGRAM/UDP 192.0.2.17 80\n"
|
||||||
|
"address: RAW/IP 192.0.2.17 80\n");
|
||||||
check_ai ("alias.example", "80", AF_INET,
|
check_ai ("alias.example", "80", AF_INET,
|
||||||
"address: STREAM/TCP 192.0.2.18 80\n"
|
"address: STREAM/TCP 192.0.2.18 80\n"
|
||||||
"address: DGRAM/UDP 192.0.2.18 80\n"
|
"address: DGRAM/UDP 192.0.2.18 80\n"
|
||||||
"address: RAW/IP 192.0.2.18 80\n");
|
"address: RAW/IP 192.0.2.18 80\n");
|
||||||
|
check_ai_hints ("alias.example", "80",
|
||||||
|
(struct addrinfo) { .ai_family = AF_INET,
|
||||||
|
.ai_flags = AI_CANONNAME, },
|
||||||
|
"flags: AI_CANONNAME\n"
|
||||||
|
"canonname: www.example\n"
|
||||||
|
"address: STREAM/TCP 192.0.2.18 80\n"
|
||||||
|
"address: DGRAM/UDP 192.0.2.18 80\n"
|
||||||
|
"address: RAW/IP 192.0.2.18 80\n");
|
||||||
check_ai (LONG_NAME, "80", AF_INET,
|
check_ai (LONG_NAME, "80", AF_INET,
|
||||||
"address: STREAM/TCP 192.0.2.20 80\n"
|
"address: STREAM/TCP 192.0.2.20 80\n"
|
||||||
"address: DGRAM/UDP 192.0.2.20 80\n"
|
"address: DGRAM/UDP 192.0.2.20 80\n"
|
||||||
@ -259,10 +306,26 @@ do_test (void)
|
|||||||
"address: STREAM/TCP 2001:db8::1 80\n"
|
"address: STREAM/TCP 2001:db8::1 80\n"
|
||||||
"address: DGRAM/UDP 2001:db8::1 80\n"
|
"address: DGRAM/UDP 2001:db8::1 80\n"
|
||||||
"address: RAW/IP 2001:db8::1 80\n");
|
"address: RAW/IP 2001:db8::1 80\n");
|
||||||
|
check_ai_hints ("www.example", "80",
|
||||||
|
(struct addrinfo) { .ai_family = AF_INET6,
|
||||||
|
.ai_flags = AI_CANONNAME, },
|
||||||
|
"flags: AI_CANONNAME\n"
|
||||||
|
"canonname: www.example\n"
|
||||||
|
"address: STREAM/TCP 2001:db8::1 80\n"
|
||||||
|
"address: DGRAM/UDP 2001:db8::1 80\n"
|
||||||
|
"address: RAW/IP 2001:db8::1 80\n");
|
||||||
check_ai ("alias.example", "80", AF_INET6,
|
check_ai ("alias.example", "80", AF_INET6,
|
||||||
"address: STREAM/TCP 2001:db8::2 80\n"
|
"address: STREAM/TCP 2001:db8::2 80\n"
|
||||||
"address: DGRAM/UDP 2001:db8::2 80\n"
|
"address: DGRAM/UDP 2001:db8::2 80\n"
|
||||||
"address: RAW/IP 2001:db8::2 80\n");
|
"address: RAW/IP 2001:db8::2 80\n");
|
||||||
|
check_ai_hints ("alias.example", "80",
|
||||||
|
(struct addrinfo) { .ai_family = AF_INET6,
|
||||||
|
.ai_flags = AI_CANONNAME, },
|
||||||
|
"flags: AI_CANONNAME\n"
|
||||||
|
"canonname: www.example\n"
|
||||||
|
"address: STREAM/TCP 2001:db8::2 80\n"
|
||||||
|
"address: DGRAM/UDP 2001:db8::2 80\n"
|
||||||
|
"address: RAW/IP 2001:db8::2 80\n");
|
||||||
check_ai (LONG_NAME, "80", AF_INET6,
|
check_ai (LONG_NAME, "80", AF_INET6,
|
||||||
"address: STREAM/TCP 2001:db8::4 80\n"
|
"address: STREAM/TCP 2001:db8::4 80\n"
|
||||||
"address: DGRAM/UDP 2001:db8::4 80\n"
|
"address: DGRAM/UDP 2001:db8::4 80\n"
|
||||||
|
@ -39,8 +39,8 @@ socket_address_length (int family)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
format_ai_flags (FILE *out, struct addrinfo *ai, int flag, const char *name,
|
format_ai_flags_1 (FILE *out, struct addrinfo *ai, int flag, const char *name,
|
||||||
int * flags_printed)
|
int * flags_printed)
|
||||||
{
|
{
|
||||||
if ((ai->ai_flags & flag) != 0)
|
if ((ai->ai_flags & flag) != 0)
|
||||||
fprintf (out, " %s", name);
|
fprintf (out, " %s", name);
|
||||||
@ -48,14 +48,16 @@ format_ai_flags (FILE *out, struct addrinfo *ai, int flag, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
format_ai_one (FILE *out, struct addrinfo *ai, int *flags)
|
format_ai_flags (FILE *out, struct addrinfo *ai)
|
||||||
{
|
{
|
||||||
/* ai_flags */
|
if (ai == NULL)
|
||||||
if (ai->ai_flags != *flags)
|
return;
|
||||||
|
|
||||||
|
if (ai->ai_flags != 0)
|
||||||
{
|
{
|
||||||
fprintf (out, "flags:");
|
fprintf (out, "flags:");
|
||||||
int flags_printed = 0;
|
int flags_printed = 0;
|
||||||
#define FLAG(flag) format_ai_flags (out, ai, flag, #flag, &flags_printed)
|
#define FLAG(flag) format_ai_flags_1 (out, ai, flag, #flag, &flags_printed)
|
||||||
FLAG (AI_PASSIVE);
|
FLAG (AI_PASSIVE);
|
||||||
FLAG (AI_CANONNAME);
|
FLAG (AI_CANONNAME);
|
||||||
FLAG (AI_NUMERICHOST);
|
FLAG (AI_NUMERICHOST);
|
||||||
@ -72,9 +74,47 @@ format_ai_one (FILE *out, struct addrinfo *ai, int *flags)
|
|||||||
if (remaining != 0)
|
if (remaining != 0)
|
||||||
fprintf (out, " %08x", remaining);
|
fprintf (out, " %08x", remaining);
|
||||||
fprintf (out, "\n");
|
fprintf (out, "\n");
|
||||||
*flags = ai->ai_flags;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Report flag mismatches within the list. */
|
||||||
|
int flags = ai->ai_flags;
|
||||||
|
int index = 1;
|
||||||
|
ai = ai->ai_next;
|
||||||
|
while (ai != NULL)
|
||||||
|
{
|
||||||
|
if (ai->ai_flags != flags)
|
||||||
|
fprintf (out, "error: flags at %d: 0x%x expected, 0x%x actual\n",
|
||||||
|
index, flags, ai->ai_flags);
|
||||||
|
ai = ai->ai_next;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
format_ai_canonname (FILE *out, struct addrinfo *ai)
|
||||||
|
{
|
||||||
|
if (ai == NULL)
|
||||||
|
return;
|
||||||
|
if (ai->ai_canonname != NULL)
|
||||||
|
fprintf (out, "canonname: %s\n", ai->ai_canonname);
|
||||||
|
|
||||||
|
/* Report incorrectly set ai_canonname fields on subsequent list
|
||||||
|
entries. */
|
||||||
|
int index = 1;
|
||||||
|
ai = ai->ai_next;
|
||||||
|
while (ai != NULL)
|
||||||
|
{
|
||||||
|
if (ai->ai_canonname != NULL)
|
||||||
|
fprintf (out, "error: canonname set at %d: %s\n",
|
||||||
|
index, ai->ai_canonname);
|
||||||
|
ai = ai->ai_next;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
format_ai_one (FILE *out, struct addrinfo *ai)
|
||||||
|
{
|
||||||
{
|
{
|
||||||
char type_buf[32];
|
char type_buf[32];
|
||||||
const char *type_str;
|
const char *type_str;
|
||||||
@ -156,20 +196,16 @@ format_ai_one (FILE *out, struct addrinfo *ai, int *flags)
|
|||||||
else
|
else
|
||||||
fprintf (out, " %s %u\n", buf, ntohs (port));
|
fprintf (out, " %s %u\n", buf, ntohs (port));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ai_canonname */
|
|
||||||
if (ai->ai_canonname != NULL)
|
|
||||||
fprintf (out, "canonname: %s\n", ai->ai_canonname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Format all the addresses in one address family. */
|
/* Format all the addresses in one address family. */
|
||||||
static void
|
static void
|
||||||
format_ai_family (FILE *out, struct addrinfo *ai, int family, int *flags)
|
format_ai_family (FILE *out, struct addrinfo *ai, int family)
|
||||||
{
|
{
|
||||||
while (ai)
|
while (ai)
|
||||||
{
|
{
|
||||||
if (ai->ai_family == family)
|
if (ai->ai_family == family)
|
||||||
format_ai_one (out, ai, flags);
|
format_ai_one (out, ai);
|
||||||
ai = ai->ai_next;
|
ai = ai->ai_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,9 +228,10 @@ support_format_addrinfo (struct addrinfo *ai, int ret)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int flags = 0;
|
format_ai_flags (mem.out, ai);
|
||||||
format_ai_family (mem.out, ai, AF_INET, &flags);
|
format_ai_canonname (mem.out, ai);
|
||||||
format_ai_family (mem.out, ai, AF_INET6, &flags);
|
format_ai_family (mem.out, ai, AF_INET);
|
||||||
|
format_ai_family (mem.out, ai, AF_INET6);
|
||||||
}
|
}
|
||||||
|
|
||||||
xfclose_memstream (&mem);
|
xfclose_memstream (&mem);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user