From 4389dbc602b4f8fb8b691cf6eb7828caab32e344 Mon Sep 17 00:00:00 2001 From: ahgamut <41098605+ahgamut@users.noreply.github.com> Date: Mon, 21 Jun 2021 21:16:33 +0530 Subject: [PATCH] make getnameinfo simpler The getnameinfo implementation requires an address -> name lookup on the hosts file (ie struct HostsTxt) and the previous implementation used flags to check whether HostsTxt was sorted according to address or name, and then re-sorted it if necessary. Now getnameinfo lookup does not require sorting, it does a simple linear lookup, and so the related code was simplified See #172 for discussion. --- libc/dns/gethoststxt.c | 3 +-- libc/dns/hoststxt.h | 9 ++------- libc/dns/resolvehostsreverse.c | 23 ++++++++++++----------- libc/dns/resolvehoststxt.c | 2 -- libc/dns/sorthoststxt.c | 24 +++--------------------- test/libc/dns/parsehoststxt_test.c | 2 +- test/libc/dns/resolvehoststxt_test.c | 4 ++-- 7 files changed, 21 insertions(+), 46 deletions(-) diff --git a/libc/dns/gethoststxt.c b/libc/dns/gethoststxt.c index 9e45abc02..ab6a5cb04 100644 --- a/libc/dns/gethoststxt.c +++ b/libc/dns/gethoststxt.c @@ -61,7 +61,6 @@ const struct HostsTxt *GetHostsTxt(void) { init = &g_hoststxt_init; if (!g_hoststxt) { g_hoststxt = &init->ht; - init->ht.sorted_by = HOSTSTXT_NOT_SORTED; init->ht.entries.n = pushpop(ARRAYLEN(init->entries)); init->ht.entries.p = init->entries; init->ht.strings.n = pushpop(ARRAYLEN(init->strings)); @@ -75,7 +74,7 @@ const struct HostsTxt *GetHostsTxt(void) { /* TODO(jart): Elevate robustness. */ } fclose(f); - SortHostsTxt(g_hoststxt, HOSTSTXT_SORTEDBYNAME); + SortHostsTxt(g_hoststxt); } return g_hoststxt; } diff --git a/libc/dns/hoststxt.h b/libc/dns/hoststxt.h index 5f702ccc5..70cbab571 100644 --- a/libc/dns/hoststxt.h +++ b/libc/dns/hoststxt.h @@ -21,12 +21,7 @@ struct HostsTxtStrings { char *p; }; -#define HOSTSTXT_NOT_SORTED 0 -#define HOSTSTXT_SORTEDBYNAME 1 -#define HOSTSTXT_SORTEDBYADDR 2 - struct HostsTxt { - int sorted_by; struct HostsTxtEntries entries; struct HostsTxtStrings strings; }; @@ -34,12 +29,12 @@ struct HostsTxt { const struct HostsTxt *GetHostsTxt(void) returnsnonnull; void FreeHostsTxt(struct HostsTxt **) paramsnonnull(); int ParseHostsTxt(struct HostsTxt *, FILE *) paramsnonnull(); -void SortHostsTxt(struct HostsTxt *, int) paramsnonnull(); +void SortHostsTxt(struct HostsTxt *) paramsnonnull(); int ResolveHostsTxt(const struct HostsTxt *, int, const char *, struct sockaddr *, uint32_t, const char **) paramsnonnull((1, 3)); int ResolveHostsReverse(const struct HostsTxt *, int, const uint8_t *, char *, - size_t); + size_t) paramsnonnull((1, 3)); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/dns/resolvehostsreverse.c b/libc/dns/resolvehostsreverse.c index 14eb21bb3..78f320294 100644 --- a/libc/dns/resolvehostsreverse.c +++ b/libc/dns/resolvehostsreverse.c @@ -8,11 +8,6 @@ #include "libc/sysv/consts/af.h" #include "libc/sysv/errfuns.h" -static int hoststxtcmpaddr(const uint8_t *ip1, const struct HostsTxtEntry *he2) { - uint32_t v1 = *((uint32_t *)ip1), v2 = *((uint32_t *)he2->ip); - return (v1 == v2 ? 0 : (v1 > v2 ? 1 : -1)); -} - /** * Finds name associated with address in HOSTS.TXT table. * @@ -27,15 +22,21 @@ static int hoststxtcmpaddr(const uint8_t *ip1, const struct HostsTxtEntry *he2) */ int ResolveHostsReverse(const struct HostsTxt *ht, int af, const uint8_t *ip, char *buf, size_t bufsize) { - struct HostsTxtEntry *entry; + struct HostsTxtEntry *entry = NULL; + uint32_t v1, v2; + if (af != AF_INET && af != AF_UNSPEC) return eafnosupport(); - if (!ht->entries.p) return -1; + if (!ht->entries.p || !buf || bufsize == 0) return -1; - if (ht->sorted_by != HOSTSTXT_SORTEDBYADDR) - SortHostsTxt(ht, HOSTSTXT_SORTEDBYADDR); + v1 = *((uint32_t *)ip); + for (size_t j = 0; j < ht->entries.i; j++) { + v2 = *((uint32_t *)ht->entries.p[j].ip); + if (v1 == v2) { + entry = &(ht->entries.p[j]); + break; + } + } - entry = bsearch(ip, ht->entries.p, ht->entries.i, - sizeof(struct HostsTxtEntry), (void *)hoststxtcmpaddr); if (entry) { strncpy(buf, &ht->strings.p[entry->name], bufsize); return 1; diff --git a/libc/dns/resolvehoststxt.c b/libc/dns/resolvehoststxt.c index 9fe7082c9..f5858b2f3 100644 --- a/libc/dns/resolvehoststxt.c +++ b/libc/dns/resolvehoststxt.c @@ -52,8 +52,6 @@ int ResolveHostsTxt(const struct HostsTxt *ht, int af, const char *name, struct sockaddr_in *addr4; struct HostsTxtEntry *entry; if (af != AF_INET && af != AF_UNSPEC) return eafnosupport(); - if (ht->sorted_by != HOSTSTXT_SORTEDBYNAME) - SortHostsTxt(ht, HOSTSTXT_SORTEDBYNAME); if ((entry = bsearch_r(name, ht->entries.p, ht->entries.i, sizeof(struct HostsTxtEntry), (void *)hoststxtgetcmp, ht->strings.p))) { diff --git a/libc/dns/sorthoststxt.c b/libc/dns/sorthoststxt.c index d4345df41..e32cc452c 100644 --- a/libc/dns/sorthoststxt.c +++ b/libc/dns/sorthoststxt.c @@ -30,17 +30,6 @@ static int cmphoststxt(const struct HostsTxtEntry *e1, return CompareDnsNames(&strings[e1->name], &strings[e2->name]); } -/** - * Compares addresses in HOSTS.TXT table. - * @see ResolveHostsReverse() - */ -static int cmphostsaddr(const struct HostsTxtEntry *e1, - const struct HostsTxtEntry *e2) { - if (e1 == e2) return 0; - uint32_t v1 = *((uint32_t *)e1->ip), v2 = *((uint32_t *)e2->ip); - return (v1 == v2 ? 0 : (v1 > v2 ? 1 : -1)); -} - /** * Sorts entries in HOSTS.TXT table. * @@ -52,16 +41,9 @@ static int cmphostsaddr(const struct HostsTxtEntry *e1, * possible to efficiently search for subdomains, once the initial sort * is done. */ -void SortHostsTxt(struct HostsTxt *ht, int sort_by) { +void SortHostsTxt(struct HostsTxt *ht) { if (ht->entries.p) { - if (sort_by == HOSTSTXT_SORTEDBYNAME) { - qsort_r(ht->entries.p, ht->entries.i, sizeof(*ht->entries.p), - (void *)cmphoststxt, ht->strings.p); - ht->sorted_by = HOSTSTXT_SORTEDBYNAME; - } else { - qsort(ht->entries.p, ht->entries.i, sizeof(*ht->entries.p), - (void *)cmphostsaddr); - ht->sorted_by = HOSTSTXT_SORTEDBYADDR; - } + qsort_r(ht->entries.p, ht->entries.i, sizeof(*ht->entries.p), + (void *)cmphoststxt, ht->strings.p); } } diff --git a/test/libc/dns/parsehoststxt_test.c b/test/libc/dns/parsehoststxt_test.c index e60367e9c..8d8adb9b9 100644 --- a/test/libc/dns/parsehoststxt_test.c +++ b/test/libc/dns/parsehoststxt_test.c @@ -48,7 +48,7 @@ TEST(ParseHostsTxt, testCorrectlyTokenizesAndSorts) { ASSERT_EQ(1, fwrite(kInput, strlen(kInput), 1, f)); rewind(f); ASSERT_EQ(0, ParseHostsTxt(ht, f)); - SortHostsTxt(ht, HOSTSTXT_SORTEDBYNAME); + SortHostsTxt(ht); ASSERT_EQ(4, ht->entries.i); EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].name]); EXPECT_STREQ("cat.example.", &ht->strings.p[ht->entries.p[0].canon]); diff --git a/test/libc/dns/resolvehoststxt_test.c b/test/libc/dns/resolvehoststxt_test.c index f073edb73..758ee4970 100644 --- a/test/libc/dns/resolvehoststxt_test.c +++ b/test/libc/dns/resolvehoststxt_test.c @@ -49,7 +49,7 @@ TEST(ResolveHostsTxt, testBasicLookups) { struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt)); FILE *f = fmemopen(kInput, strlen(kInput), "r+"); ASSERT_EQ(0, ParseHostsTxt(ht, f)); - SortHostsTxt(ht, HOSTSTXT_SORTEDBYNAME); + SortHostsTxt(ht); ASSERT_EQ(5, ht->entries.i); EXPECT_STREQ("127.0.0.1", EzIp4Lookup(ht, "localhost")); EXPECT_STREQ("203.0.113.1", EzIp4Lookup(ht, "lol")); @@ -66,7 +66,7 @@ TEST(ResolveHostsTxt, testCanonicalize) { struct HostsTxt *ht = calloc(1, sizeof(struct HostsTxt)); FILE *f = fmemopen(kInput, strlen(kInput), "r+"); ASSERT_EQ(0, ParseHostsTxt(ht, f)); - SortHostsTxt(ht, HOSTSTXT_SORTEDBYNAME); + SortHostsTxt(ht); ASSERT_EQ(5, ht->entries.i); EXPECT_STREQ("localhost", EzCanonicalize(ht, "localhost")); EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol"));