summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-11-16 04:07:16 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-11-16 04:07:16 +0000
commit1a82a7130a61eb7c072217447a20d9a65c4b308b (patch)
tree3b84742b1b577e5101366d1e9b54e6bb81f95a09
parentade760af3cb1bd8f3e1f6ac1b1fdc936d667c2a1 (diff)
resolver: make getaddrinfo actually respect _res.nsaddr_list;
add largish comment explaining what we are doing, and why; fixes to make IPv6-only resolver possible
-rw-r--r--libc/inet/Makefile.in4
-rw-r--r--libc/inet/resolv.c537
2 files changed, 337 insertions, 204 deletions
diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in
index f905c8e35..f6ee48f9d 100644
--- a/libc/inet/Makefile.in
+++ b/libc/inet/Makefile.in
@@ -43,8 +43,8 @@ resolv_CSRC += encodeh.c decodeh.c encoded.c decoded.c lengthd.c encodeq.c \
ifneq ($(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6),)
CSRC += $(resolv_CSRC)
-# unused ATM
-CSRC += encodep.c decodep.c formquery.c
+## # unused ATM
+## CSRC += encodep.c decodep.c formquery.c
endif
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index a84c6af1f..defd4d77c 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -183,6 +183,7 @@ libc_hidden_proto(fopen)
libc_hidden_proto(fclose)
libc_hidden_proto(random)
libc_hidden_proto(getservbyport)
+libc_hidden_proto(gethostname)
libc_hidden_proto(uname)
libc_hidden_proto(inet_addr)
libc_hidden_proto(inet_aton)
@@ -298,8 +299,10 @@ typedef union sockaddr46_t {
__UCLIBC_MUTEX_EXTERN(__resolv_lock);
/* Protected by __resolv_lock */
-extern int __nameservers attribute_hidden;
-extern int __searchdomains attribute_hidden;
+extern void (*__res_sync)(void) attribute_hidden;
+//extern uint32_t __resolv_opts attribute_hidden;
+extern unsigned __nameservers attribute_hidden;
+extern unsigned __searchdomains attribute_hidden;
extern sockaddr46_t *__nameserver attribute_hidden;
extern char **__searchdomain attribute_hidden;
/* Arbitrary */
@@ -348,6 +351,90 @@ extern void __close_nameservers(void) attribute_hidden;
extern int __dn_expand(const u_char *, const u_char *, const u_char *,
char *, int);
+/*
+ * Theory of operation.
+ *
+ * gethostbyname, getaddrinfo and friends end up here, and they sometimes
+ * need to talk to DNS servers. In order to do this, we need to read /etc/resolv.conf
+ * and determine servers' addresses and the like. resolv.conf format:
+ *
+ * nameserver <IP[v6]>
+ * Address of DNS server. Cumulative.
+ * If not specified, assumed to be on localhost.
+ * search <domain1>[ <domain2>]...
+ * Append these domains to unqualified names.
+ * See ndots:n option.
+ * $LOCALDOMAIN (space-separated list) overrides this.
+ * domain <domain>
+ * Effectively same as "search" with one domain.
+ * If no "domain" line is present, the domain is determined
+ * from the local host name returned by gethostname();
+ * the domain part is taken to be everything after the first dot.
+ * If there are no dots, there will be no "domain".
+ * The domain and search keywords are mutually exclusive.
+ * If more than one instance of these keywords is present,
+ * the last instance wins.
+ * sortlist 130.155.160.0[/255.255.240.0] 130.155.0.0
+ * Allows addresses returned by gethostbyname to be sorted.
+ * Not supported.
+ * options option[ option]...
+ * (so far we support none)
+ * $RES_OPTIONS (space-separated list) is to be added to "options"
+ * debug sets RES_DEBUG in _res.options
+ * ndots:n how many dots there should be so that name will be tried
+ * first as an absolute name before any search list elements
+ * are appended to it. Default 1
+ * timeout:n how long to wait for response. Default 5
+ * (sun seems to have retrans:n synonym)
+ * attempts:n number of rounds to do before giving up and returning
+ * an error. Default 2
+ * (sun seems to have retry:n synonym)
+ * rotate sets RES_ROTATE in _res.options, round robin
+ * selection of nameservers. Otherwise try
+ * the first listed server first every time
+ * no-check-names
+ * sets RES_NOCHECKNAME in _res.options, which disables
+ * checking of incoming host names for invalid characters
+ * such as underscore (_), non-ASCII, or control characters
+ * inet6 sets RES_USE_INET6 in _res.options. Try a AAAA query
+ * before an A query inside the gethostbyname(), and map
+ * IPv4 responses in IPv6 "tunnelled form" if no AAAA records
+ * are found but an A record set exists
+ * no_tld_query (FreeBSDism?)
+ * do not attempt to resolve names without dots
+ *
+ * We will read and analyze /etc/resolv.conf as needed before
+ * we do a DNS request. This happens in __dns_lookup.
+ * (TODO: also re-parse it after a timeout, it might get updated).
+ *
+ * BSD has res_init routine which is used to initialize resolver state
+ * which is held in global structure _res.
+ * Generally, programs call res_init, then fiddle with _res.XXX
+ * (_res.options and _res.nscount, _res.nsaddr_list[N]
+ * are popular targets of fiddling) and expect subsequent calls
+ * to gethostbyname, getaddrinfo, etc to use modified information.
+ *
+ * However, historical _res structure is quite awkward.
+ * Using it for storing /etc/resolv.conf info is not desirable,
+ * and __dns_lookup does not use it.
+ *
+ * We would like to avoid using it unless absolutely necessary.
+ * If user doesn't use res_init, we should arrange it so that
+ * _res structure doesn't even *get linked in* into user's application
+ * (imagine static uclibc build here).
+ *
+ * The solution is a __res_sync function pointer, which is normally NULL.
+ * But if res_init is called, it gets set and any subsequent gethostbyname
+ * et al "syncronizes" our internal structures with potentially
+ * modified _res.XXX stuff by calling __res_sync.
+ * The trick here is that if res_init is not used and not linked in,
+ * gethostbyname itself won't reference _res and _res won't be linked in
+ * either. Other possible methods like
+ * if (__res_sync_just_an_int_flag)
+ * __sync_me_with_res()
+ * would pull in __sync_me_with_res, which pulls in _res. Bad.
+ */
+
#ifdef L_encodeh
@@ -584,7 +671,9 @@ int attribute_hidden __length_question(const unsigned char * const message, int
}
#endif
+
#ifdef L_encodea
+
int attribute_hidden __encode_answer(struct resolv_answer *a, unsigned char *dest, int maxlen)
{
int i;
@@ -659,6 +748,7 @@ int attribute_hidden __decode_answer(const unsigned char *message, int offset,
#endif
+#ifdef CURRENTLY_UNUSED
#ifdef L_encodep
int __encode_packet(struct resolv_header *h,
@@ -763,6 +853,192 @@ int __form_query(int id, const char *name, int type, unsigned char *packet,
return i + j;
}
#endif
+#endif /* CURRENTLY_UNUSED */
+
+
+#ifdef L_opennameservers
+
+__UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER);
+
+/* Protected by __resolv_lock */
+void (*__res_sync)(void);
+//uint32_t __resolv_opts;
+unsigned __nameservers;
+unsigned __searchdomains;
+sockaddr46_t *__nameserver;
+char **__searchdomain;
+
+/* Helpers. Both stop on EOL, if it's '\n', it is converted to NUL first */
+static char *skip_nospace(char *p)
+{
+ while (*p != '\0' && !isspace(*p)) {
+ if (*p == '\n') {
+ *p = '\0';
+ break;
+ }
+ p++;
+ }
+ return p;
+}
+static char *skip_and_NUL_space(char *p)
+{
+ /* NB: '\n' is not isspace! */
+ while (1) {
+ char c = *p;
+ if (c == '\0' || !isspace(c))
+ break;
+ *p = '\0';
+ if (c == '\n' || c == '#')
+ break;
+ p++;
+ }
+ return p;
+}
+
+/* Must be called under __resolv_lock. */
+void attribute_hidden __open_nameservers(void)
+{
+ char szBuffer[MAXLEN_searchdomain];
+ FILE *fp;
+ int i;
+ sockaddr46_t sa;
+
+ //if (!__res_sync && last_time_was_long_ago)
+ // __close_nameservers(); /* force config reread */
+
+ if (__nameservers)
+ goto sync;
+
+ fp = fopen("/etc/resolv.conf", "r");
+ if (!fp) {
+// TODO: why? google says nothing about this...
+ fp = fopen("/etc/config/resolv.conf", "r");
+ }
+
+ if (fp) {
+ while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
+ void *ptr;
+ char *keyword, *p;
+
+ keyword = p = skip_and_NUL_space(szBuffer);
+ /* skip keyword */
+ p = skip_nospace(p);
+ /* find next word */
+ p = skip_and_NUL_space(p);
+
+ if (strcmp(keyword, "nameserver") == 0) {
+ /* terminate IP addr */
+ *skip_nospace(p) = '\0';
+ memset(&sa, 0, sizeof(sa));
+ if (0) /* nothing */;
+#ifdef __UCLIBC_HAS_IPV6__
+ else if (inet_pton(AF_INET6, p, &sa.sa6.sin6_addr) > 0) {
+ sa.sa6.sin6_family = AF_INET6;
+ sa.sa6.sin6_port = htons(NAMESERVER_PORT);
+ }
+#endif
+#ifdef __UCLIBC_HAS_IPV4__
+ else if (inet_pton(AF_INET, p, &sa.sa4.sin_addr) > 0) {
+ sa.sa4.sin_family = AF_INET;
+ sa.sa4.sin_port = htons(NAMESERVER_PORT);
+ }
+#endif
+ else
+ continue; /* garbage on this line */
+ ptr = realloc(__nameserver, (__nameservers + 1) * sizeof(__nameserver[0]));
+ if (!ptr)
+ continue;
+ __nameserver = ptr;
+ __nameserver[__nameservers++] = sa; /* struct copy */
+ continue;
+ }
+ if (strcmp(keyword, "domain") == 0 || strcmp(keyword, "search") == 0) {
+ char *p1;
+//TODO: delete old domains...
+ next_word:
+ /* terminate current word */
+ p1 = skip_nospace(p);
+ /* find next word (maybe) */
+ p1 = skip_and_NUL_space(p1);
+ /* paranoia - done by having szBuffer[MAXLEN_searchdomain] */
+ /*if (strlen(p) > MAXLEN_searchdomain)*/
+ /* goto skip;*/
+ /* do we have this domain already? */
+ for (i = 0; i < __searchdomains; i++)
+ if (strcmp(p, __searchdomain[i]) == 0)
+ goto skip;
+ /* add it */
+ ptr = realloc(__searchdomain, (__searchdomains + 1) * sizeof(__searchdomain[0]));
+ if (!ptr)
+ continue;
+ __searchdomain = ptr;
+ ptr = strdup(p);
+ if (!ptr)
+ continue;
+ DPRINTF("adding search %s\n", (char*)ptr);
+ __searchdomain[__searchdomains++] = (char*)ptr;
+ skip:
+ p = p1;
+ if (*p)
+ goto next_word;
+ continue;
+ }
+ /* if (strcmp(keyword, "sortlist") == 0)... */
+ /* if (strcmp(keyword, "options") == 0)... */
+ }
+ fclose(fp);
+ }
+ if (__nameservers == 0) {
+ __nameserver = malloc(sizeof(__nameserver[0]));
+//TODO: error check?
+ memset(&__nameserver[0], 0, sizeof(__nameserver[0]));
+#ifdef __UCLIBC_HAS_IPV4__
+ __nameserver[0].sa4.sin_family = AF_INET;
+ /*__nameserver[0].sa4.sin_addr = INADDR_ANY; - done by memset */
+ __nameserver[0].sa4.sin_port = htons(NAMESERVER_PORT);
+#else
+ __nameserver[0].sa6.sin6_family = AF_INET6;
+ __nameserver[0].sa6.sin6_port = htons(NAMESERVER_PORT);
+#endif
+ __nameservers++;
+ }
+ if (__searchdomains == 0) {
+ char buf[256];
+ char *p;
+ i = gethostname(buf, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ if (i == 0 && (p = strchr(buf, '.')) != NULL && p[1]) {
+ p = strdup(p + 1);
+ __searchdomain = malloc(sizeof(__searchdomain[0]));
+//TODO: error check?
+ __searchdomain[0] = p;
+ __searchdomains++;
+ }
+ }
+ DPRINTF("nameservers = %d\n", __nameservers);
+
+ sync:
+ if (__res_sync)
+ __res_sync();
+}
+#endif
+
+
+#ifdef L_closenameservers
+
+/* Must be called under __resolv_lock. */
+void attribute_hidden __close_nameservers(void)
+{
+ free(__nameserver);
+ __nameserver = NULL;
+ __nameservers = 0;
+ while (__searchdomains)
+ free(__searchdomain[--__searchdomains]);
+ free(__searchdomain);
+ __searchdomain = NULL;
+ /*__searchdomains = 0; - already is */
+}
+#endif
#ifdef L_dnslookup
@@ -859,43 +1135,23 @@ int attribute_hidden __dns_lookup(const char *name, int type,
// local_ns_num = 0;
// if (_res.options & RES_ROTATE)
local_ns_num = last_ns_num;
- if (local_ns_num >= __nameservers)
- local_ns_num = 0;
}
- /* __nameservers == 0 case: act as if
- * we have one DNS server configured - on 127.0.0.1 */
- {
- int my_nameservers = __nameservers;
- if (my_nameservers == 0)
- my_nameservers++;
- if (local_ns_num >= my_nameservers) {
- local_ns_num = 0;
- retries++;
- /* break if retries >= MAX_RETRIES - *after unlock*! */
- }
+ if (local_ns_num >= __nameservers) {
+ local_ns_num = 0;
+//TODO: wrong method of retries++!
+// Should be if (local_ns_num == starting_ns_num) retries++;
+ retries++;
+ /* break if retries >= MAX_RETRIES - *after unlock*! */
}
local_id++;
local_id &= 0xffff;
/* write new values back while still under lock */
last_id = local_id;
last_ns_num = local_ns_num;
- if (__nameservers != 0) {
- /* struct copy */
- /* can't just take a pointer, __nameserver[]
- * is not safe to use outside of locks */
- sa = __nameserver[local_ns_num];
- } else {
- /* __nameservers == 0 */
- memset(&sa, 0, sizeof(sa));
-#ifdef __UCLIBC_HAS_IPV4__
- sa.sa4.sin_family = AF_INET;
- /*sa.sa4.sin_addr = INADDR_ANY; - done by memset */
- sa.sa4.sin_port = htons(NAMESERVER_PORT);
-#else
- sa.sa6.sin_family = AF_INET6;
- sa.sa6.sin6_port = htons(NAMESERVER_PORT);
-#endif
- }
+ /* struct copy */
+ /* can't just take a pointer, __nameserver[x]
+ * is not safe to use outside of locks */
+ sa = __nameserver[local_ns_num];
__UCLIBC_MUTEX_UNLOCK(__resolv_lock);
if (retries >= MAX_RETRIES)
break;
@@ -964,8 +1220,7 @@ int attribute_hidden __dns_lookup(const char *name, int type,
goto try_next_server;
}
#endif
-//TODO: MSG_DONTWAIT?
- len = recv(fd, packet, PACKETSZ, 0);
+ len = recv(fd, packet, PACKETSZ, MSG_DONTWAIT);
if (len < HFIXEDSZ) {
/* too short! */
//TODO: why next sdomain? it's just a bogus packet from somewhere,
@@ -1104,155 +1359,6 @@ int attribute_hidden __dns_lookup(const char *name, int type,
}
#endif
-#ifdef L_opennameservers
-
-__UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER);
-
-/* Protected by __resolv_lock */
-int __nameservers;
-int __searchdomains;
-sockaddr46_t *__nameserver;
-char **__searchdomain;
-
-/* Helpers. Both stop on EOL, if it's '\n', it is converted to NUL first */
-static char *skip_nospace(char *p)
-{
- while (*p != '\0' && !isspace(*p)) {
- if (*p == '\n') {
- *p = '\0';
- break;
- }
- p++;
- }
- return p;
-}
-static char *skip_and_NUL_space(char *p)
-{
- /* NB: '\n' is not isspace! */
- while (1) {
- char c = *p;
- if (c == '\0' || !isspace(c))
- break;
- *p = '\0';
- if (c == '\n' || c == '#')
- break;
- p++;
- }
- return p;
-}
-
-/* Must be called under __resolv_lock. */
-void attribute_hidden __open_nameservers(void)
-{
- char szBuffer[MAXLEN_searchdomain];
- FILE *fp;
- int i;
- sockaddr46_t sa;
-
- if (__nameservers > 0)
- return;
-
- fp = fopen("/etc/resolv.conf", "r");
- if (!fp) {
- fp = fopen("/etc/config/resolv.conf", "r");
- if (!fp) {
- DPRINTF("failed to open %s\n", "resolv.conf");
- h_errno = NO_RECOVERY;
- return;
- }
- }
-
- while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
- void *ptr;
- char *keyword, *p;
-
- keyword = p = skip_and_NUL_space(szBuffer);
- /* skip keyword */
- p = skip_nospace(p);
- /* find next word */
- p = skip_and_NUL_space(p);
-
- if (strcmp(keyword, "nameserver") == 0) {
- /* terminate IP addr */
- *skip_nospace(p) = '\0';
- memset(&sa, 0, sizeof(sa));
- if (0) /* nothing */;
-#ifdef __UCLIBC_HAS_IPV6__
- else if (inet_pton(AF_INET6, p, &sa.sa6.sin6_addr) > 0) {
- sa.sa6.sin6_family = AF_INET6;
- sa.sa6.sin6_port = htons(NAMESERVER_PORT);
- }
-#endif
-#ifdef __UCLIBC_HAS_IPV4__
- else if (inet_pton(AF_INET, p, &sa.sa4.sin_addr) > 0) {
- sa.sa4.sin_family = AF_INET;
- sa.sa4.sin_port = htons(NAMESERVER_PORT);
- }
-#endif
- else
- continue; /* garbage on this line */
- ptr = realloc(__nameserver, (__nameservers + 1) * sizeof(__nameserver[0]));
- if (!ptr)
- continue;
- __nameserver = ptr;
- __nameserver[__nameservers++] = sa; /* struct copy */
- continue;
- }
- if (strcmp(keyword, "domain") == 0 || strcmp(keyword, "search") == 0) {
- char *p1;
- next_word:
- /* terminate current word */
- p1 = skip_nospace(p);
- /* find next word (maybe) */
- p1 = skip_and_NUL_space(p1);
- /* paranoia - done by having szBuffer[MAXLEN_searchdomain] */
- /*if (strlen(p) > MAXLEN_searchdomain)*/
- /* goto skip;*/
- /* do we have this domain already? */
- for (i = 0; i < __searchdomains; i++)
- if (strcmp(p, __searchdomain[i]) == 0)
- goto skip;
- /* add it */
- ptr = realloc(__searchdomain, (__searchdomains + 1) * sizeof(__searchdomain[0]));
- if (!ptr)
- continue;
- __searchdomain = ptr;
- ptr = strdup(p);
- if (!ptr)
- continue;
- DPRINTF("adding search %s\n", (char*)ptr);
- __searchdomain[__searchdomains++] = (char*)ptr;
- skip:
- p = p1;
- if (*p)
- goto next_word;
- continue;
- }
- /* if (strcmp(keyword, "sortlist") == 0)... */
- /* if (strcmp(keyword, "options") == 0)... */
- }
- fclose(fp);
- DPRINTF("nameservers = %d\n", __nameservers);
-}
-#endif
-
-
-#ifdef L_closenameservers
-
-/* Must be called under __resolv_lock. */
-void attribute_hidden __close_nameservers(void)
-{
- free(__nameserver);
- __nameserver = NULL;
- __nameservers = 0;
- while (__searchdomains)
- free(__searchdomain[--__searchdomains]);
- free(__searchdomain);
- __searchdomain = NULL;
- /*__searchdomains = 0; - already is */
-}
-#endif
-
#ifdef L_gethostbyname
@@ -1298,6 +1404,38 @@ struct hostent *gethostbyname2(const char *name, int family)
/* Protected by __resolv_lock */
struct __res_state _res;
+#undef ARRAY_SIZE
+#define ARRAY_SIZE(v) (sizeof(v) / sizeof((v)[0]))
+
+/* Will be called under __resolv_lock. */
+static void res_sync_func(void)
+{
+ struct __res_state *rp = &(_res);
+
+ /* Track .nscount and .nsaddr_list
+ * (busybox's nslookup uses it).
+ */
+ if (__nameservers > rp->nscount)
+ __nameservers = rp->nscount;
+ /* TODO:
+ * if (__nameservers < rp->nscount) - try to grow __nameserver[]?
+ */
+#ifdef __UCLIBC_HAS_IPV4__
+ {
+ int n = __nameservers;
+ while (--n >= 0) {
+ __nameserver[n].sa.sa_family = AF_INET;
+ __nameserver[n].sa4 = rp->nsaddr_list[n]; /* struct copy */
+ }
+ }
+#endif
+ /* Extend and comment what program is known
+ * to use which _res.XXX member(s).
+ */
+ // __resolv_opts = rp->options;
+ // ...
+}
+
/* Our res_init never fails (always returns 0) */
int res_init(void)
{
@@ -1308,6 +1446,8 @@ int res_init(void)
__close_nameservers();
__open_nameservers();
+ __res_sync = res_sync_func;
+
memset(rp, 0, sizeof(*rp));
rp->options = RES_INIT;
#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
@@ -1315,27 +1455,17 @@ int res_init(void)
rp->retry = 4;
rp->id = random();
#endif
- /* man resolv.conf says:
- * "On a normally configured system this file should not be necessary.
- * The only name server to be queried will be on the local machine;
- * the domain name is determined from the host name
- * and the domain search path is constructed from the domain name" */
- rp->nscount = 1;
- rp->nsaddr_list[0].sin_addr.s_addr = INADDR_ANY;
- rp->nsaddr_list[0].sin_family = AF_INET;
- rp->nsaddr_list[0].sin_port = htons(NAMESERVER_PORT);
rp->ndots = 1;
#ifdef __UCLIBC_HAS_EXTRA_COMPAT_RES_STATE__
rp->_vcsock = -1;
#endif
-#undef ARRAY_SIZE
-#define ARRAY_SIZE(v) (sizeof(v) / sizeof((v)[0]))
n = __searchdomains;
if (n > ARRAY_SIZE(rp->dnsrch))
n = ARRAY_SIZE(rp->dnsrch);
for (i = 0; i < n; i++)
rp->dnsrch[i] = __searchdomain[i];
+#ifdef __UCLIBC_HAS_IPV4__
i = 0;
n = 0;
while (n < ARRAY_SIZE(rp->nsaddr_list) && i < __nameservers) {
@@ -1346,13 +1476,12 @@ int res_init(void)
next_i:
i++;
}
- if (n)
- rp->nscount = n;
- /* else rp->nscount stays 1 */
-#undef ARRAY_SIZE
+ rp->nscount = n;
+#endif
__UCLIBC_MUTEX_UNLOCK(__resolv_lock);
return 0;
}
+#undef ARRAY_SIZE
libc_hidden_def(res_init)
#ifdef __UCLIBC_HAS_BSD_RES_CLOSE__
@@ -1360,6 +1489,7 @@ void res_close(void)
{
__UCLIBC_MUTEX_LOCK(__resolv_lock);
__close_nameservers();
+ __res_sync = NULL;
memset(&_res, 0, sizeof(_res));
__UCLIBC_MUTEX_UNLOCK(__resolv_lock);
}
@@ -1367,6 +1497,7 @@ void res_close(void)
#endif /* L_res_init */
+
#ifdef L_res_query
int res_query(const char *dname, int class, int type,
@@ -1617,15 +1748,16 @@ int res_querydomain(const char *name, const char *domain, int class, int type,
return res_query(longname, class, type, answer, anslen);
}
libc_hidden_def(res_querydomain)
-
/* res_mkquery */
/* res_send */
/* dn_comp */
/* dn_expand */
#endif
+
#ifdef L_gethostbyaddr
-struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type)
+
+struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type)
{
static struct hostent h;
static char buf[
@@ -2023,7 +2155,7 @@ BAD_FAM:
}
if (!ok) {
- const char *c;
+ const char *c = NULL;
if (flags & NI_NAMEREQD) {
errno = serrno;
@@ -2035,7 +2167,8 @@ BAD_FAM:
sin6p = (const struct sockaddr_in6 *) sa;
c = inet_ntop(AF_INET6,
- (const void *) &sin6p->sin6_addr, host, hostlen);
+ (const void *) &sin6p->sin6_addr,
+ host, hostlen);
#if 0
/* Does scope id need to be supported? */
uint32_t scopeid;