mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Simplify getnameinfo (#196)
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.
This commit is contained in:
parent
1f87640d17
commit
98c53ae526
7 changed files with 21 additions and 46 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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"));
|
||||
|
|
Loading…
Reference in a new issue