mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Added getnameinfo with only name lookup (#172)
Added necessary constants (DNS_TYPE_PTR, NI_NUMERICHOST etc.). Implementation of getnameinfo is similar to getaddrinfo, with internal functions: * ResolveDnsReverse: performs rDNS query and parses the PTR record * ResolveHostsReverse: reads /etc/hosts to map hostname to address Earlier, the HOSTS.txt would only need to be sorted at loading time, because the only kind of lookup was name -> address. Now since address -> name lookups are also possible, so the HostsTxt struct, the sorting method (and the related tests) was changed to reflect this.
This commit is contained in:
parent
05350eca60
commit
248c6d54bb
12 changed files with 334 additions and 10 deletions
|
@ -3,7 +3,9 @@
|
|||
#include "libc/sock/sock.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
#define DNS_TYPE_A 1
|
||||
#define DNS_TYPE_A 0x01
|
||||
#define DNS_TYPE_PTR 0x0c
|
||||
|
||||
#define DNS_CLASS_IN 1
|
||||
|
||||
#define kMinSockaddr4Size \
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||
#define COSMOPOLITAN_LIBC_DNS_DNS_H_
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/sock/sock.h"
|
||||
|
||||
|
@ -56,11 +57,15 @@ struct addrinfo {
|
|||
int getaddrinfo(const char *, const char *, const struct addrinfo *,
|
||||
struct addrinfo **) paramsnonnull((4));
|
||||
int freeaddrinfo(struct addrinfo *);
|
||||
int getnameinfo(const struct sockaddr *, socklen_t, char *, socklen_t, char *,
|
||||
socklen_t, int);
|
||||
const char *gai_strerror(int);
|
||||
int CompareDnsNames(const char *, const char *) paramsnonnull();
|
||||
int PascalifyDnsName(uint8_t *, size_t, const char *) paramsnonnull();
|
||||
int ResolveDns(const struct ResolvConf *, int, const char *, struct sockaddr *,
|
||||
uint32_t) paramsnonnull();
|
||||
int ResolveDnsReverse(const struct ResolvConf *resolvconf, int, const char *,
|
||||
char *, size_t) paramsnonnull();
|
||||
struct addrinfo *newaddrinfo(uint16_t);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
|
@ -61,6 +61,7 @@ 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));
|
||||
|
@ -74,7 +75,7 @@ const struct HostsTxt *GetHostsTxt(void) {
|
|||
/* TODO(jart): Elevate robustness. */
|
||||
}
|
||||
fclose(f);
|
||||
SortHostsTxt(g_hoststxt);
|
||||
SortHostsTxt(g_hoststxt, HOSTSTXT_SORTEDBYNAME);
|
||||
}
|
||||
return g_hoststxt;
|
||||
}
|
||||
|
|
107
libc/dns/getnameinfo.c
Normal file
107
libc/dns/getnameinfo.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dns/consts.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/inaddr.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Resolves name/service for socket address.
|
||||
*
|
||||
* @param addr
|
||||
* @param addrlen
|
||||
* @param name
|
||||
* @param namelen
|
||||
* @param service
|
||||
* @param servicelen
|
||||
* @param flags
|
||||
*
|
||||
* @return 0 on success or EAI_xxx value
|
||||
*/
|
||||
int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, char *name,
|
||||
socklen_t namelen, char *service, socklen_t servicelen,
|
||||
int flags) {
|
||||
char rdomain[1 + sizeof "255.255.255.255.in-addr.arpa"];
|
||||
char info[512];
|
||||
int rc, port;
|
||||
uint8_t *ip;
|
||||
unsigned int valid_flags;
|
||||
|
||||
valid_flags =
|
||||
(NI_NAMEREQD | NI_NUMERICHOST | NI_NUMERICSERV | NI_NOFQDN | NI_DGRAM);
|
||||
|
||||
if (flags & ~(valid_flags)) return EAI_BADFLAGS;
|
||||
if (!name && !service) return EAI_NONAME;
|
||||
if (addr->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
|
||||
return EAI_FAMILY;
|
||||
|
||||
ip = (uint8_t *)&(((struct sockaddr_in *)addr)->sin_addr);
|
||||
sprintf(rdomain, "%d.%d.%d.%d.in-addr.arpa", ip[3], ip[2], ip[1], ip[0]);
|
||||
info[0] = '\0';
|
||||
if (name != NULL && namelen != 0) {
|
||||
if ((flags & NI_NUMERICHOST) && (flags & NI_NAMEREQD)) return EAI_NONAME;
|
||||
|
||||
if ((flags & NI_NUMERICHOST) &&
|
||||
inet_ntop(AF_INET, ip, info, sizeof(info)) == NULL)
|
||||
return EAI_SYSTEM;
|
||||
else if (!info[0] && ResolveHostsReverse(GetHostsTxt(), AF_INET, ip, info,
|
||||
sizeof(info)) < 0)
|
||||
return EAI_SYSTEM;
|
||||
else if (!info[0] && ResolveDnsReverse(GetResolvConf(), AF_INET, rdomain,
|
||||
info, sizeof(info)) < 0)
|
||||
return EAI_SYSTEM;
|
||||
else if (!info[0] && (flags & NI_NAMEREQD))
|
||||
return EAI_NONAME;
|
||||
else if (!info[0] && inet_ntop(AF_INET, ip, info, sizeof(info)) == NULL)
|
||||
return EAI_SYSTEM;
|
||||
|
||||
if (strlen(info) + 1 > namelen) return EAI_OVERFLOW;
|
||||
strcpy(name, info);
|
||||
}
|
||||
|
||||
port = ntohs(((struct sockaddr_in *)addr)->sin_port);
|
||||
info[0] = '\0';
|
||||
if (service != NULL && servicelen != 0) {
|
||||
itoa(port, info, 10);
|
||||
/* TODO: reverse lookup on /etc/services to get name of service */
|
||||
if (strlen(info) + 1 > servicelen) return EAI_OVERFLOW;
|
||||
strcpy(service, info);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -21,7 +21,12 @@ 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;
|
||||
};
|
||||
|
@ -29,10 +34,12 @@ struct HostsTxt {
|
|||
const struct HostsTxt *GetHostsTxt(void) returnsnonnull;
|
||||
void FreeHostsTxt(struct HostsTxt **) paramsnonnull();
|
||||
int ParseHostsTxt(struct HostsTxt *, FILE *) paramsnonnull();
|
||||
void SortHostsTxt(struct HostsTxt *) paramsnonnull();
|
||||
void SortHostsTxt(struct HostsTxt *, int) 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);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
132
libc/dns/resolvednsreverse.c
Normal file
132
libc/dns/resolvednsreverse.c
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dns/consts.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/dnsheader.h"
|
||||
#include "libc/dns/dnsquestion.h"
|
||||
#include "libc/dns/resolvconf.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/af.h"
|
||||
#include "libc/sysv/consts/ipproto.h"
|
||||
#include "libc/sysv/consts/sock.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define kMsgMax 512
|
||||
|
||||
/**
|
||||
* Performs reverse DNS lookup with IP address.
|
||||
*
|
||||
* @param resolvconf can be GetResolvConf()
|
||||
* @param af can be AF_INET, AF_UNSPEC
|
||||
* @param name is a reversed IP address string ending with .in-addr.arpa
|
||||
* @param buf to store the obtained hostname if any
|
||||
* @param bufsize is size of buf
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @error EAFNOSUPPORT, ENETDOWN, ENAMETOOLONG, EBADMSG
|
||||
*/
|
||||
int ResolveDnsReverse(const struct ResolvConf *resolvconf, int af,
|
||||
const char *name, char *buf, size_t bufsize) {
|
||||
int rc, fd, n;
|
||||
struct DnsQuestion q;
|
||||
struct DnsHeader h, h2;
|
||||
uint8_t *p, *pe, msg[512];
|
||||
uint16_t rtype, rclass, rdlength;
|
||||
|
||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||
if (!resolvconf->nameservers.i) return 0;
|
||||
memset(&h, 0, sizeof(h));
|
||||
rc = ebadmsg();
|
||||
h.id = rand32();
|
||||
h.bf1 = 1; /* recursion desired */
|
||||
h.qdcount = 1;
|
||||
q.qname = name;
|
||||
q.qtype = DNS_TYPE_PTR;
|
||||
q.qclass = DNS_CLASS_IN;
|
||||
memset(msg, 0, sizeof(msg));
|
||||
SerializeDnsHeader(msg, &h);
|
||||
|
||||
if ((n = SerializeDnsQuestion(msg + 12, 500, &q)) == -1) return -1;
|
||||
if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) return -1;
|
||||
if (sendto(fd, msg, 12 + n, 0, resolvconf->nameservers.p,
|
||||
sizeof(*resolvconf->nameservers.p)) == 12 + n &&
|
||||
(n = read(fd, msg, 512)) >= 12) {
|
||||
DeserializeDnsHeader(&h2, msg);
|
||||
if (h2.id == h.id) {
|
||||
rc = 0;
|
||||
if (h2.ancount) {
|
||||
p = msg + 12;
|
||||
pe = msg + n;
|
||||
while (p < pe && h2.qdcount) {
|
||||
p += strnlen((char *)p, pe - p) + 1 + 4;
|
||||
h2.qdcount--;
|
||||
}
|
||||
if (p + 1 < pe) {
|
||||
if ((p[0] & 0b11000000) == 0b11000000) { /* name pointer */
|
||||
p += 2;
|
||||
} else {
|
||||
p += strnlen((char *)p, pe - p) + 1;
|
||||
}
|
||||
if (p + 2 + 2 + 4 + 2 < pe) {
|
||||
rtype = READ16BE(p), p += 2;
|
||||
rclass = READ16BE(p), p += 2;
|
||||
/* ttl */ p += 4;
|
||||
rdlength = READ16BE(p), p += 2;
|
||||
|
||||
if (p + rdlength <= pe && rtype == DNS_TYPE_PTR &&
|
||||
rclass == DNS_CLASS_IN) {
|
||||
if (strnlen((char *)p, pe - p) + 1 > bufsize)
|
||||
rc = -1;
|
||||
else {
|
||||
/* domain name starts with a letter */
|
||||
for (; !isalnum((char)(*p)) && p < pe; p++) rdlength--;
|
||||
for (char *tmp = (char *)p; rdlength > 0 && *tmp != '\0';
|
||||
tmp++) {
|
||||
/* each label is alphanumeric or hyphen
|
||||
* any other character is assumed separator */
|
||||
if (!isalnum(*tmp) && *tmp != '-') *tmp = '.';
|
||||
rdlength--;
|
||||
}
|
||||
strcpy(buf, (char *)p);
|
||||
}
|
||||
} else
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
return rc;
|
||||
}
|
44
libc/dns/resolvehostsreverse.c
Normal file
44
libc/dns/resolvehostsreverse.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/dns/consts.h"
|
||||
#include "libc/dns/dns.h"
|
||||
#include "libc/dns/hoststxt.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
#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.
|
||||
*
|
||||
* @param ht can be GetHostsTxt()
|
||||
* @param af can be AF_INET
|
||||
* @param ip is IP address in binary (sin_addr)
|
||||
* @param buf is buffer to store the name
|
||||
* @param bufsize is length of buf
|
||||
*
|
||||
* @return 1 if found, 0 if not found, or -1 w/ errno
|
||||
* @error EAFNOSUPPORT
|
||||
*/
|
||||
int ResolveHostsReverse(const struct HostsTxt *ht, int af, const uint8_t *ip,
|
||||
char *buf, size_t bufsize) {
|
||||
struct HostsTxtEntry *entry;
|
||||
if (af != AF_INET && af != AF_UNSPEC) return eafnosupport();
|
||||
if (!ht->entries.p) return -1;
|
||||
|
||||
if (ht->sorted_by != HOSTSTXT_SORTEDBYADDR)
|
||||
SortHostsTxt(ht, HOSTSTXT_SORTEDBYADDR);
|
||||
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -52,6 +52,8 @@ 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,6 +30,17 @@ 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.
|
||||
*
|
||||
|
@ -41,9 +52,16 @@ static int cmphoststxt(const struct HostsTxtEntry *e1,
|
|||
* possible to efficiently search for subdomains, once the initial sort
|
||||
* is done.
|
||||
*/
|
||||
void SortHostsTxt(struct HostsTxt *ht) {
|
||||
void SortHostsTxt(struct HostsTxt *ht, int sort_by) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,13 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
#define INET_ADDRSTRLEN 22
|
||||
|
||||
#define NI_NUMERICHOST 0x01
|
||||
#define NI_NUMERICSERV 0x02
|
||||
#define NI_NOFQDN 0x04
|
||||
#define NI_NAMEREQD 0x08
|
||||
#define NI_DGRAM 0x10
|
||||
|
||||
#define NI_MAXHOST 0xff
|
||||
#define NI_MAXSERV 0x20
|
||||
|
||||
#define htons(u16) bswap_16(u16)
|
||||
|
|
|
@ -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);
|
||||
SortHostsTxt(ht, HOSTSTXT_SORTEDBYNAME);
|
||||
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);
|
||||
SortHostsTxt(ht, HOSTSTXT_SORTEDBYNAME);
|
||||
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);
|
||||
SortHostsTxt(ht, HOSTSTXT_SORTEDBYNAME);
|
||||
ASSERT_EQ(5, ht->entries.i);
|
||||
EXPECT_STREQ("localhost", EzCanonicalize(ht, "localhost"));
|
||||
EXPECT_STREQ("lol.example.", EzCanonicalize(ht, "lol"));
|
||||
|
|
Loading…
Add table
Reference in a new issue