From 8ec69bb7ecf3ca5edde5b7d9d7d5d3a5f8b6c405 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Thu, 11 May 2017 11:32:16 +0200 Subject: 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. --- ChangeLog | 16 +++++++++ resolv/tst-resolv-basic.c | 71 ++++++++++++++++++++++++++++++++++++--- support/support_format_addrinfo.c | 69 ++++++++++++++++++++++++++++--------- 3 files changed, 136 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4231a68..d3137e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,21 @@ 2017-05-11 Florian Weimer + * 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 + * sysdeps/posix/getaddrinfo.c (gethosts): Remove malloc_addrmem. (gaih_inet): Likewise. diff --git a/resolv/tst-resolv-basic.c b/resolv/tst-resolv-basic.c index f2b1fc7..92f912b 100644 --- a/resolv/tst-resolv-basic.c +++ b/resolv/tst-resolv-basic.c @@ -182,12 +182,12 @@ check_h (const char *name, int family, const char *expected) } static void -check_ai (const char *name, const char *service, - int family, const char *expected) +check_ai_hints (const char *name, const char *service, + struct addrinfo hints, const char *expected) { - struct addrinfo hints = {.ai_family = family}; 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); check_addrinfo (query, ai, ret, expected); if (ret == 0) @@ -195,6 +195,15 @@ check_ai (const char *name, const char *service, 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 do_test (void) { @@ -229,6 +238,17 @@ do_test (void) "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_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, "address: STREAM/TCP 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: DGRAM/UDP 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, "address: STREAM/TCP 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: DGRAM/UDP 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, "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_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, "address: STREAM/TCP 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: DGRAM/UDP 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, "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_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, "address: STREAM/TCP 2001:db8::4 80\n" "address: DGRAM/UDP 2001:db8::4 80\n" diff --git a/support/support_format_addrinfo.c b/support/support_format_addrinfo.c index 262e0df..eedb030 100644 --- a/support/support_format_addrinfo.c +++ b/support/support_format_addrinfo.c @@ -39,8 +39,8 @@ socket_address_length (int family) } static void -format_ai_flags (FILE *out, struct addrinfo *ai, int flag, const char *name, - int * flags_printed) +format_ai_flags_1 (FILE *out, struct addrinfo *ai, int flag, const char *name, + int * flags_printed) { if ((ai->ai_flags & flag) != 0) fprintf (out, " %s", name); @@ -48,14 +48,16 @@ format_ai_flags (FILE *out, struct addrinfo *ai, int flag, const char *name, } static void -format_ai_one (FILE *out, struct addrinfo *ai, int *flags) +format_ai_flags (FILE *out, struct addrinfo *ai) { - /* ai_flags */ - if (ai->ai_flags != *flags) + if (ai == NULL) + return; + + if (ai->ai_flags != 0) { fprintf (out, "flags:"); 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_CANONNAME); FLAG (AI_NUMERICHOST); @@ -72,9 +74,47 @@ format_ai_one (FILE *out, struct addrinfo *ai, int *flags) if (remaining != 0) fprintf (out, " %08x", remaining); 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]; const char *type_str; @@ -156,20 +196,16 @@ format_ai_one (FILE *out, struct addrinfo *ai, int *flags) else 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. */ 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) { if (ai->ai_family == family) - format_ai_one (out, ai, flags); + format_ai_one (out, ai); ai = ai->ai_next; } } @@ -192,9 +228,10 @@ support_format_addrinfo (struct addrinfo *ai, int ret) } else { - int flags = 0; - format_ai_family (mem.out, ai, AF_INET, &flags); - format_ai_family (mem.out, ai, AF_INET6, &flags); + format_ai_flags (mem.out, ai); + format_ai_canonname (mem.out, ai); + format_ai_family (mem.out, ai, AF_INET); + format_ai_family (mem.out, ai, AF_INET6); } xfclose_memstream (&mem); -- cgit v1.1