Skip to content

Instantly share code, notes, and snippets.

@jarcode-foss
Created December 30, 2016 20:03
Show Gist options
  • Save jarcode-foss/2168add42e72589ae6e09a72e709b0a0 to your computer and use it in GitHub Desktop.
Save jarcode-foss/2168add42e72589ae6e09a72e709b0a0 to your computer and use it in GitHub Desktop.
Fix for name resolution in belle-sip
From 7b92f57a4eec5fe2d01ee620f1213c238d128b86 Mon Sep 17 00:00:00 2001
From: BuildTools <[email protected]>
Date: Fri, 30 Dec 2016 11:43:57 -0800
Subject: [PATCH] Update dns.c and usage
---
src/belle_sip_resolver.c | 2 +-
src/dns.c | 690 ++++++++++++++++++++---------------------------
src/dns.h | 37 +--
3 files changed, 296 insertions(+), 433 deletions(-)
diff --git a/src/belle_sip_resolver.c b/src/belle_sip_resolver.c
index a1969d5..4206723 100644
--- a/src/belle_sip_resolver.c
+++ b/src/belle_sip_resolver.c
@@ -488,7 +488,7 @@ static int resolver_process_data(belle_sip_simple_resolver_context_t *ctx, unsig
belle_sip_resolver_context_notify(BELLE_SIP_RESOLVER_CONTEXT(ctx));
return BELLE_SIP_STOP;
}
- dns_res_enable_search(ctx->R, search_enabled);
+ /*dns_res_enable_search(ctx->R, search_enabled);*/
/*belle_sip_message("resolver_process_data(): revents=%i",revents);*/
error = dns_res_check(ctx->R);
if (!error) {
diff --git a/src/dns.c b/src/dns.c
index 8d22f88..15ff335 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -28,9 +28,6 @@
#define _XOPEN_SOURCE 600
#endif
-#undef _DEFAULT_SOURCE
-#define _DEFAULT_SOURCE
-
#undef _BSD_SOURCE
#define _BSD_SOURCE
@@ -41,26 +38,17 @@
#define _NETBSD_SOURCE
#endif
-#ifdef _MSC_VER
-#define DNS_INLINE __inline
-#else
-#define DNS_INLINE inline
-#endif
-
#include <limits.h> /* INT_MAX */
#include <stddef.h> /* offsetof() */
-/*#ifdef _WIN32
-#define uint16_t unsigned short
+#ifdef _WIN32
#define uint32_t unsigned int
-#else*/
+#else
#include <stdint.h> /* uint32_t */
-//#endif
+#endif
#include <stdlib.h> /* malloc(3) realloc(3) free(3) rand(3) random(3) arc4random(3) */
#include <stdio.h> /* FILE fopen(3) fclose(3) getc(3) rewind(3) */
#include <string.h> /* memcpy(3) strlen(3) memmove(3) memchr(3) memcmp(3) strchr(3) strsep(3) strcspn(3) */
-#ifndef _WIN32
#include <strings.h> /* strcasecmp(3) strncasecmp(3) */
-#endif
#include <ctype.h> /* isspace(3) isdigit(3) */
#include <time.h> /* time_t time(2) difftime(3) */
#include <signal.h> /* SIGPIPE sigemptyset(3) sigaddset(3) sigpending(2) sigprocmask(2) pthread_sigmask(3) sigtimedwait(2) */
@@ -70,27 +58,10 @@
#if _WIN32
#ifndef FD_SETSIZE
-#define FD_SETSIZE 2048
+#define FD_SETSIZE 256
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
-#ifndef USE_FIXED_NAMESERVERS
-#include <IPHlpApi.h>
-#pragma comment(lib, "IPHLPAPI.lib")
-#endif
-
-#if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP)
-#define BELLE_SIP_WINDOWS_DESKTOP 1
-#elif defined(WINAPI_FAMILY_PARTITION)
-#if defined(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-#define BELLE_SIP_WINDOWS_DESKTOP 1
-#elif defined(WINAPI_PARTITION_PHONE_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
-#define BELLE_SIP_WINDOWS_PHONE 1
-#elif defined(WINAPI_PARTITION_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
-#define BELLE_SIP_WINDOWS_UNIVERSAL 1
-#endif
-#endif
-
#else
#include <sys/types.h> /* FD_SETSIZE socklen_t */
#include <sys/select.h> /* FD_ZERO FD_SET fd_set select(2) */
@@ -108,15 +79,6 @@
#include "dns.h"
-#if defined(HAVE_RESINIT) || defined(USE_STRUCT_RES_STATE_NAMESERVERS)
-#include <resolv.h>
-#endif
-
-#ifdef ANDROID
-#include <sys/system_properties.h>
-#endif
-
-#include <bctoolbox/port.h>
/*
* C O M P I L E R V E R S I O N & F E A T U R E D E T E C T I O N
@@ -190,12 +152,13 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#if HAVE___BUILTIN_TYPES_COMPATIBLE_P
-#define dns_same_type(a, b, def) __builtin_types_compatible_p(typeof (a), typeof (b))
+#define dns_same_type(a, b, def) __builtin_types_compatible_p(__typeof__ (a), __typeof__ (b))
#else
#define dns_same_type(a, b, def) (def)
#endif
#define dns_isarray(a) (!dns_same_type((a), (&(a)[0]), 0))
-#define dns_inline_assert(cond) ((void)(sizeof (struct { int:-!(cond); })))
+/* NB: "_" field silences Sun Studio "zero-sized struct/union" error diagnostic */
+#define dns_inline_assert(cond) ((void)(sizeof (struct { int:-!(cond); int _; })))
#if HAVE___ASSUME
#define dns_assume(cond) __assume(cond)
@@ -269,13 +232,16 @@ int *dns_debug_p(void) {
#if DNS_DEBUG
+#undef DNS_DEBUG
+#define DNS_DEBUG dns_debug
+
#define DNS_SAY_(fmt, ...) \
do { if (DNS_DEBUG > 0) fprintf(stderr, fmt "%.1s", __func__, __LINE__, __VA_ARGS__); } while (0)
#define DNS_SAY(...) DNS_SAY_("@@ (%s:%d) " __VA_ARGS__, "\n")
#define DNS_HAI DNS_SAY("HAI")
#define DNS_SHOW_(P, fmt, ...) do { \
- if (DNS_DEBUG >= 1) { \
+ if (DNS_DEBUG > 1) { \
fprintf(stderr, "@@ BEGIN * * * * * * * * * * * *\n"); \
fprintf(stderr, "@@ " fmt "%.0s\n", __VA_ARGS__); \
dns_p_dump((P), stderr); \
@@ -338,9 +304,6 @@ int dns_v_api(void) {
#define DNS_EALREADY WSAEALREADY
#define DNS_EAGAIN EAGAIN
#define DNS_ETIMEDOUT WSAETIMEDOUT
-#define DNS_ECONNREFUSED WSAECONNREFUSED
-#define DNS_ENETUNREACH WSAENETUNREACH
-#define DNS_EHOSTUNREACH WSAEHOSTUNREACH
#define dns_syerr() ((int)GetLastError())
#define dns_soerr() ((int)WSAGetLastError())
@@ -354,9 +317,6 @@ int dns_v_api(void) {
#define DNS_EALREADY EALREADY
#define DNS_EAGAIN EAGAIN
#define DNS_ETIMEDOUT ETIMEDOUT
-#define DNS_ECONNREFUSED ECONNREFUSED
-#define DNS_ENETUNREACH ENETUNREACH
-#define DNS_EHOSTUNREACH EHOSTUNREACH
#define dns_syerr() errno
#define dns_soerr() errno
@@ -437,12 +397,12 @@ const char *dns_strerror(int error) {
#endif
#endif
-static DNS_INLINE unsigned dns_atomic_fetch_add(dns_atomic_t *i) {
+static inline unsigned dns_atomic_fetch_add(dns_atomic_t *i) {
return DNS_ATOMIC_FETCH_ADD(i);
} /* dns_atomic_fetch_add() */
-static DNS_INLINE unsigned dns_atomic_fetch_sub(dns_atomic_t *i) {
+static inline unsigned dns_atomic_fetch_sub(dns_atomic_t *i) {
return DNS_ATOMIC_FETCH_SUB(i);
} /* dns_atomic_fetch_sub() */
@@ -571,7 +531,7 @@ struct dns_k_permutor {
}; /* struct dns_k_permutor */
-static DNS_INLINE unsigned dns_k_permutor_powof(unsigned n) {
+static inline unsigned dns_k_permutor_powof(unsigned n) {
unsigned m, i = 0;
for (m = 1; m < n; m <<= 1, i++)
@@ -730,6 +690,40 @@ static unsigned short dns_k_shuffle16(unsigned short n, unsigned s) {
return ((0xff00 & (a << 8)) | (0x00ff & (b << 0)));
} /* dns_k_shuffle16() */
+/*
+ * S T A T E M A C H I N E R O U T I N E S
+ *
+ * Application code should define DNS_SM_RESTORE and DNS_SM_SAVE, and the
+ * local variable pc.
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define DNS_SM_ENTER \
+ do { \
+ static const int pc0 = __LINE__; \
+ DNS_SM_RESTORE; \
+ switch (pc0 + pc) { \
+ case __LINE__: (void)0
+
+#define DNS_SM_SAVE_AND_DO(do_statement) \
+ do { \
+ pc = __LINE__ - pc0; \
+ DNS_SM_SAVE; \
+ do_statement; \
+ case __LINE__: (void)0; \
+ } while (0)
+
+#define DNS_SM_YIELD(rv) \
+ DNS_SM_SAVE_AND_DO(return (rv))
+
+#define DNS_SM_EXIT \
+ do { goto leave; } while (0)
+
+#define DNS_SM_LEAVE \
+ leave: (void)0; \
+ DNS_SM_SAVE_AND_DO(break); \
+ } \
+ } while (0)
/*
* U T I L I T Y R O U T I N E S
@@ -799,7 +793,7 @@ static size_t dns_af_len(int af) {
return table[af];
} /* dns_af_len() */
-#define dns_sa_family(sa) (((struct sockaddr_storage *)(sa))->ss_family)
+#define dns_sa_family(sa) (((struct sockaddr *)(sa))->sa_family)
#define dns_sa_len(sa) dns_af_len(dns_sa_family(sa))
@@ -1069,37 +1063,29 @@ static char *dns_strsep(char **sp, const char *delim) {
#if _WIN32
-#ifndef strcasecmp
#define strcasecmp(...) _stricmp(__VA_ARGS__)
-#endif
-#ifndef strncasecmp
#define strncasecmp(...) _strnicmp(__VA_ARGS__)
#endif
-#endif
-static DNS_INLINE _Bool dns_isalpha(unsigned char c) {
+static inline _Bool dns_isalpha(unsigned char c) {
return isalpha(c);
} /* dns_isalpha() */
-static DNS_INLINE _Bool dns_isdigit(unsigned char c) {
+static inline _Bool dns_isdigit(unsigned char c) {
return isdigit(c);
} /* dns_isdigit() */
-static DNS_INLINE _Bool dns_isalnum(unsigned char c) {
+static inline _Bool dns_isalnum(unsigned char c) {
return isalnum(c);
} /* dns_isalnum() */
-static DNS_INLINE _Bool dns_isspace(unsigned char c) {
+static inline _Bool dns_isspace(unsigned char c) {
return isspace(c);
} /* dns_isspace() */
static int dns_poll(int fd, short events, int timeout) {
-/* For our usage in belle sip, we are called by the main loop when something is to read on the dns socket.
- * As a result there is no need to perform a blocking select.
-**/
-#if 0
fd_set rset, wset;
if (!events)
@@ -1118,7 +1104,6 @@ static int dns_poll(int fd, short events, int timeout) {
select(fd + 1, &rset, &wset, 0, (timeout >= 0)? &(struct timeval){ timeout, 0 } : NULL);
-#endif
return 0;
} /* dns_poll() */
@@ -1273,13 +1258,13 @@ struct dns_buf {
size_t overflow;
}; /* struct dns_buf */
-static DNS_INLINE size_t
+static inline size_t
dns_b_tell(struct dns_buf *b)
{
return b->p - b->base;
}
-static DNS_INLINE dns_error_t
+static inline dns_error_t
dns_b_setoverflow(struct dns_buf *b, size_t n, dns_error_t error)
{
b->overflow += n;
@@ -1317,13 +1302,13 @@ dns_b_pputc(struct dns_buf *b, unsigned char uc, size_t p)
return 0;
}
-static DNS_INLINE dns_error_t
+static inline dns_error_t
dns_b_put16(struct dns_buf *b, uint16_t u)
{
return dns_b_putc(b, u >> 8), dns_b_putc(b, u >> 0);
}
-static DNS_INLINE dns_error_t
+static inline dns_error_t
dns_b_pput16(struct dns_buf *b, uint16_t u, size_t p)
{
if (dns_b_pputc(b, u >> 8, p) || dns_b_pputc(b, u >> 0, p + 1))
@@ -1332,7 +1317,7 @@ dns_b_pput16(struct dns_buf *b, uint16_t u, size_t p)
return 0;
}
-DNS_NOTUSED static DNS_INLINE dns_error_t
+DNS_NOTUSED static inline dns_error_t
dns_b_put32(struct dns_buf *b, uint32_t u)
{
return dns_b_putc(b, u >> 24), dns_b_putc(b, u >> 16),
@@ -1359,7 +1344,7 @@ dns_b_puts(struct dns_buf *b, const void *src)
return dns_b_put(b, src, strlen(src));
}
-DNS_NOTUSED static DNS_INLINE dns_error_t
+DNS_NOTUSED static inline dns_error_t
dns_b_fmtju(struct dns_buf *b, const uintmax_t u, const unsigned width)
{
size_t digits, padding, overflow;
@@ -1408,7 +1393,7 @@ dns_b_popc(struct dns_buf *b)
b->p--;
}
-static DNS_INLINE const char *
+static inline const char *
dns_b_tolstring(struct dns_buf *b, size_t *n)
{
if (b->p < b->pe) {
@@ -1431,14 +1416,14 @@ dns_b_tolstring(struct dns_buf *b, size_t *n)
}
}
-static DNS_INLINE const char *
+static inline const char *
dns_b_tostring(struct dns_buf *b)
{
size_t n;
return dns_b_tolstring(b, &n);
}
-static DNS_INLINE size_t
+static inline size_t
dns_b_strlen(struct dns_buf *b)
{
size_t n;
@@ -1446,7 +1431,7 @@ dns_b_strlen(struct dns_buf *b)
return n;
}
-static DNS_INLINE size_t
+static inline size_t
dns_b_strllen(struct dns_buf *b)
{
size_t n = dns_b_strlen(b);
@@ -1461,7 +1446,7 @@ dns_b_from(const struct dns_buf *b, const void *src, size_t n)
return b;
}
-static DNS_INLINE int
+static inline int
dns_b_getc(const struct dns_buf *_b, const int eof)
{
struct dns_buf *b = (struct dns_buf *)_b;
@@ -1472,7 +1457,7 @@ dns_b_getc(const struct dns_buf *_b, const int eof)
return *b->p++;
}
-static DNS_INLINE intmax_t
+static inline intmax_t
dns_b_get16(const struct dns_buf *b, const intmax_t eof)
{
intmax_t n;
@@ -1483,7 +1468,7 @@ dns_b_get16(const struct dns_buf *b, const intmax_t eof)
return (!b->overflow)? n : eof;
}
-DNS_NOTUSED static DNS_INLINE intmax_t
+DNS_NOTUSED static inline intmax_t
dns_b_get32(const struct dns_buf *b, const intmax_t eof)
{
intmax_t n;
@@ -1494,7 +1479,7 @@ dns_b_get32(const struct dns_buf *b, const intmax_t eof)
return (!b->overflow)? n : eof;
}
-static DNS_INLINE dns_error_t
+static inline dns_error_t
dns_b_move(struct dns_buf *dst, const struct dns_buf *_src, size_t n)
{
struct dns_buf *src = (struct dns_buf *)_src;
@@ -2132,6 +2117,25 @@ invalid:
} /* dns_l_skip() */
+static _Bool dns_d_isanchored(const void *_src, size_t len) {
+ const unsigned char *src = _src;
+ return len > 0 && src[len - 1] == '.';
+} /* dns_d_isanchored() */
+
+
+static size_t dns_d_ndots(const void *_src, size_t len) {
+ const unsigned char *p = _src, *pe = p + len;
+ size_t ndots = 0;
+
+ while ((p = memchr(p, '.', pe - p))) {
+ ndots++;
+ p++;
+ }
+
+ return ndots;
+} /* dns_d_ndots() */
+
+
static size_t dns_d_trim(void *dst_, size_t lim, const void *src_, size_t len, int flags) {
unsigned char *dst = dst_;
const unsigned char *src = src_;
@@ -3691,8 +3695,11 @@ size_t dns_ptr_qname(void *dst, size_t lim, int af, void *addr) {
return dns_aaaa_arpa(dst, lim, addr);
case AF_INET:
return dns_a_arpa(dst, lim, addr);
- default:
- return dns_a_arpa(dst, lim, &(struct dns_a){ { INADDR_NONE } });
+ default: {
+ struct dns_a a;
+ a.addr.s_addr = INADDR_NONE;
+ return dns_a_arpa(dst, lim, &a);
+ }
}
} /* dns_ptr_qname() */
@@ -4161,22 +4168,6 @@ struct dns_hosts *dns_hosts_mortal(struct dns_hosts *hosts) {
return hosts;
} /* dns_hosts_mortal() */
-#if defined(BELLE_SIP_WINDOWS_PHONE) || defined(BELLE_SIP_WINDOWS_UNIVERSAL)
-static int dns_hosts_add_localhost(struct dns_hosts *hosts) {
- struct dns_hosts_entry ent;
- memset(&ent, '\0', sizeof(ent));
- ent.af = AF_INET;
- dns_inet_pton(ent.af, "127.0.0.1", &ent.addr);
- dns_d_anchor(ent.host, sizeof(ent.host), "localhost", 9);
- dns_hosts_insert(hosts, ent.af, &ent.addr, ent.host, 0);
- memset(&ent, '\0', sizeof(ent));
- ent.af = AF_INET6;
- dns_inet_pton(ent.af, "::1", &ent.addr);
- dns_d_anchor(ent.host, sizeof(ent.host), "localhost", 9);
- dns_hosts_insert(hosts, ent.af, &ent.addr, ent.host, 1);
- return 0;
-}
-#endif
struct dns_hosts *dns_hosts_local(int *error_) {
struct dns_hosts *hosts;
@@ -4185,15 +4176,7 @@ struct dns_hosts *dns_hosts_local(int *error_) {
if (!(hosts = dns_hosts_open(&error)))
goto error;
-#ifdef _WIN32
-#if defined(BELLE_SIP_WINDOWS_PHONE) || defined(BELLE_SIP_WINDOWS_UNIVERSAL)
- if ((error = dns_hosts_add_localhost(hosts)))
-#else
- if ((error = dns_hosts_loadpath(hosts, "C:/Windows/System32/drivers/etc/hosts")))
-#endif
-#else
if ((error = dns_hosts_loadpath(hosts, "/etc/hosts")))
-#endif
goto error;
return hosts;
@@ -4250,21 +4233,6 @@ int dns_hosts_loadfile(struct dns_hosts *hosts, FILE *fp) {
break;
case 1:
ent.af = (strchr(word, ':'))? AF_INET6 : AF_INET;
- // Normalize some strange IPv4 addresses, eg. 127.1 --> 127.0.0.1
- if (ent.af == AF_INET) {
- int nbdots = 0;
- char *p = word;
- while ((p = strchr(p, '.')) != NULL) {
- nbdots++;
- p++;
- }
- if (nbdots == 1) {
- p = strchr(word, '.');
- p++;
- memmove(p + 4, p, strlen(p));
- memcpy(p, "0.0.", 4);
- }
- }
skip = (1 != dns_inet_pton(ent.af, word, &ent.addr));
break;
@@ -4444,7 +4412,7 @@ error:
struct dns_resolv_conf *dns_resconf_open(int *error) {
static const struct dns_resolv_conf resconf_initializer = {
- .lookup = "fb",
+ .lookup = "bf",
.family = { AF_INET, AF_INET6 },
.options = { .ndots = 1, .timeout = 5, .attempts = 2, .tcp = DNS_RESCONF_TCP_ENABLE, },
.iface = { .ss_family = AF_INET },
@@ -4644,8 +4612,7 @@ static enum dns_resconf_keyword dns_resconf_keyword(const char *word) {
int dns_resconf_pton(struct sockaddr_storage *ss, const char *src) {
struct { char buf[128], *p; } addr = { "", addr.buf };
unsigned short port = 0;
- struct addrinfo *ai;
- int ch, af = AF_INET;
+ int ch, af = AF_INET, error;
while ((ch = *src++)) {
switch (ch) {
@@ -4677,11 +4644,13 @@ int dns_resconf_pton(struct sockaddr_storage *ss, const char *src) {
} /* while() */
inet:
+ if ((error = dns_pton(af, addr.buf, dns_sa_addr(af, ss, NULL))))
+ return error;
+
port = (!port)? 53 : port;
- ai = bctbx_ip_address_to_addrinfo(af, SOCK_DGRAM, addr.buf, port);
- if (ai == NULL) return dns_soerr();
- memcpy(ss, ai->ai_addr, ai->ai_addrlen);
- bctbx_freeaddrinfo(ai);
+ *dns_sa_port(af, ss) = htons(port);
+ dns_sa_family(ss) = af;
+
return 0;
} /* dns_resconf_pton() */
@@ -4896,120 +4865,6 @@ int dns_resconf_loadpath(struct dns_resolv_conf *resconf, const char *path) {
return error;
} /* dns_resconf_loadpath() */
-#ifdef USE_FIXED_NAMESERVERS
-int dns_resconf_load_fixed_nameservers(struct dns_resolv_conf *resconf) {
- const char * const nameservers[] = {
- "8.8.8.8",
- "8.8.4.4"
- };
- int i;
- int error = 0;
-
- for (i = 0; !error && (i < lengthof(nameservers)); i++) {
- error = dns_resconf_pton(&resconf->nameserver[i], nameservers[i]);
- }
-
- return error;
-}
-#endif /* USE_FIXED_NAMESERVERS */
-
-#ifdef USE_STRUCT_RES_STATE_NAMESERVERS
-int dns_resconf_load_struct_res_state_nameservers(struct dns_resolv_conf *resconf) {
- int i;
- struct __res_state *rs = __res_get_state();
-
- for (i = 0; i < rs->nscount; i++) {
- memcpy(&resconf->nameserver[i], (struct sockaddr_storage *)&rs->nsaddr_list[i], sizeof(struct sockaddr_in));
- }
-
- return 0;
-}
-#endif /* USE_STRUCT_RES_STATE_NAMESERVERS */
-
-#if defined(_WIN32) && !defined(USE_FIXED_NAMESERVERS)
-int dns_resconf_loadwin(struct dns_resolv_conf *resconf) {
- FIXED_INFO *pFixedInfo;
- ULONG ulOutBufLen;
- DWORD dwRetVal;
- IP_ADDR_STRING *pIPAddr;
- unsigned sa_count = 0;
- int error;
-
- pFixedInfo = (FIXED_INFO *) malloc(sizeof(FIXED_INFO));
- if (pFixedInfo == NULL) {
- return -1;
- }
- ulOutBufLen = sizeof(FIXED_INFO);
- if (GetNetworkParams(pFixedInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
- free(pFixedInfo);
- pFixedInfo = (FIXED_INFO *) malloc(ulOutBufLen);
- if (pFixedInfo == NULL) {
- return -1;
- }
- }
-
- if ((dwRetVal = GetNetworkParams(pFixedInfo, &ulOutBufLen)) == NO_ERROR) {
- memset(resconf->search, '\0', sizeof resconf->search);
- memcpy(resconf->search[0], pFixedInfo->DomainName, sizeof pFixedInfo->DomainName);
- pIPAddr = &pFixedInfo->DnsServerList;
- do {
- error = dns_resconf_pton(&resconf->nameserver[sa_count], pIPAddr->IpAddress.String);
- pIPAddr = pIPAddr->Next;
- sa_count++;
- } while (!error && pIPAddr && (sa_count < lengthof(resconf->nameserver)));
- }
- free(pFixedInfo);
- return 0;
-}
-#endif /* dns_resconf_loadwin() */
-
-#ifdef ANDROID
-int dns_resconf_loadandroid(struct dns_resolv_conf *resconf) {
- char dns[PROP_VALUE_MAX];
- char prop_name[PROP_NAME_MAX];
- unsigned int sa_count = 0;
- int error = 0;
- int i;
-
- for (i = 1; !error && (i <= lengthof(resconf->nameserver)); i++) {
- snprintf(prop_name, sizeof(prop_name), "net.dns%d", i);
- if (__system_property_get(prop_name, dns) > 0) {
- if (dns_resconf_pton(&resconf->nameserver[sa_count], dns) == 0){
- sa_count++;
- }
- }
- }
-
- if (sa_count == 0) {
- /* No net.dnsX property found, return an error. */
- error = -1;
- }
-
- return error;
-} /* dns_resconf_loadandroid */
-#endif
-
-#ifdef HAVE_RESINIT
-int dns_resconf_loadfromresolv(struct dns_resolv_conf *resconf) {
- struct __res_state res;
- union res_sockaddr_union addresses[3];
- int i,error;
-
- if ((error = res_ninit(&res))) {
- return error;
- }
-
- error=res_getservers(&res,addresses,3);
- if (error>0){
- for (i = 0; i<error ; i++ ) {
- memcpy(&resconf->nameserver[i],&addresses[i],sizeof(union res_sockaddr_union));
- }
- error=0;
- }else error=-1;
- res_ndestroy(&res);
- return error;
-}
-#endif /*HAVE_RESINIT*/
struct dns_anyconf {
char *token[16];
@@ -5306,7 +5161,7 @@ int dns_nssconf_loadfile(struct dns_resolv_conf *resconf, FILE *fp) {
dns_anyconf_skip(" \t", fp);
if ('[' == dns_anyconf_peek(fp)) {
- dns_anyconf_skip("[ \t", fp);
+ dns_anyconf_skip("[! \t", fp);
while (dns_anyconf_scan(&cf, "%w_", fp, &error)) {
dns_anyconf_skip("= \t", fp);
@@ -5400,7 +5255,7 @@ struct dns_nssconf_source {
typedef unsigned dns_nssconf_i;
-static DNS_INLINE int dns_nssconf_peek(const struct dns_resolv_conf *resconf, dns_nssconf_i state) {
+static inline int dns_nssconf_peek(const struct dns_resolv_conf *resconf, dns_nssconf_i state) {
return (state < lengthof(resconf->lookup) && resconf->lookup[state])? resconf->lookup[state] : 0;
} /* dns_nssconf_peek() */
@@ -5531,66 +5386,65 @@ int dns_resconf_setiface(struct dns_resolv_conf *resconf, const char *addr, unsi
} /* dns_resconf_setiface() */
-size_t dns_resconf_search(void *dst, size_t lim, const void *qname, size_t qlen, struct dns_resolv_conf *resconf, dns_resconf_i_t *state) {
- unsigned srchi = 0xff & (*state >> 8);
- unsigned ndots = 0xff & (*state >> 16);
- unsigned len = 0;
- const char *qp, *qe;
-
- switch (0xff & *state) {
- case 0:
- qp = qname;
- qe = qp + qlen;
+#define DNS_SM_RESTORE \
+ do { \
+ pc = 0xff & (*state >> 0); \
+ srchi = 0xff & (*state >> 8); \
+ ndots = 0xff & (*state >> 16); \
+ } while (0)
- while ((qp = memchr(qp, '.', qe - qp)))
- { ndots++; qp++; }
+#define DNS_SM_SAVE \
+ do { \
+ *state = ((0xff & pc) << 0) \
+ | ((0xff & srchi) << 8) \
+ | ((0xff & ndots) << 16); \
+ } while (0)
- ++*state;
-
- if (ndots >= resconf->options.ndots) {
- len = dns_d_anchor(dst, lim, qname, qlen);
-
- break;
- }
-
- /* FALL THROUGH */
- case 1:
- if (srchi < lengthof(resconf->search) && resconf->search[srchi][0] && strcmp(resconf->search[srchi], ".")) {
- len = dns_d_anchor(dst, lim, qname, qlen);
- len += dns_strlcpy((char *)dst + DNS_PP_MIN(len, lim), resconf->search[srchi], lim - DNS_PP_MIN(len, lim));
-
- srchi++;
+size_t dns_resconf_search(void *dst, size_t lim, const void *qname, size_t qlen, struct dns_resolv_conf *resconf, dns_resconf_i_t *state) {
+ unsigned pc, srchi, ndots, len;
- break;
- }
+ DNS_SM_ENTER;
- ++*state;
+ /* if FQDN then return as-is and finish */
+ if (dns_d_isanchored(qname, qlen)) {
+ len = dns_d_anchor(dst, lim, qname, qlen);
+ DNS_SM_YIELD(len);
+ DNS_SM_EXIT;
+ }
- /* FALL THROUGH */
- case 2:
- ++*state;
+ ndots = dns_d_ndots(qname, qlen);
- if (ndots < resconf->options.ndots) {
- len = dns_d_anchor(dst, lim, qname, qlen);
+ if (ndots >= resconf->options.ndots) {
+ len = dns_d_anchor(dst, lim, qname, qlen);
+ DNS_SM_YIELD(len);
+ }
- break;
- }
+ while (srchi < lengthof(resconf->search) && resconf->search[srchi][0]) {
+ struct dns_buf buf = DNS_B_INTO(dst, lim);
+ const char *dn = resconf->search[srchi++];
- /* FALL THROUGH */
- default:
- break;
- } /* switch() */
+ dns_b_put(&buf, qname, qlen);
+ dns_b_putc(&buf, '.');
+ dns_b_puts(&buf, dn);
+ if (!dns_d_isanchored(dn, strlen(dn)))
+ dns_b_putc(&buf, '.');
+ len = dns_b_strllen(&buf);
+ DNS_SM_YIELD(len);
+ }
- *state = ((0xff & *state) << 0)
- | ((0xff & srchi) << 8)
- | ((0xff & ndots) << 16);
+ if (ndots < resconf->options.ndots) {
+ len = dns_d_anchor(dst, lim, qname, qlen);
+ DNS_SM_YIELD(len);
+ }
- if (lim > 0)
- ((char *)dst)[DNS_PP_MIN(lim - 1, len)] = '\0';
+ DNS_SM_LEAVE;
- return len;
+ return dns_strlcpy(dst, "", lim);
} /* dns_resconf_search() */
+#undef DNS_SM_SAVE
+#undef DNS_SM_RESTORE
+
int dns_resconf_dump(struct dns_resolv_conf *resconf, FILE *fp) {
unsigned i;
@@ -6090,11 +5944,12 @@ error:
} /* dns_hints_query() */
-/**
- * Fill a whole sockaddr from the the nameservers' sockaddr contained in the hints. This is needed for scope link IPv6 nameservers.
-**/
-static void dns_fill_sockaddr_from_hints(struct dns_hints *hints, int af, struct sockaddr *addr) {
+/** ugly hack to support specifying ports other than 53 in resolv.conf. */
+static unsigned short dns_hints_port(struct dns_hints *hints, int af, void *addr) {
struct dns_hints_soa *soa;
+ void *addrsoa;
+ socklen_t addrlen;
+ unsigned short port;
unsigned i;
for (soa = hints->head; soa; soa = soa->next) {
@@ -6102,19 +5957,20 @@ static void dns_fill_sockaddr_from_hints(struct dns_hints *hints, int af, struct
if (af != soa->addrs[i].ss.ss_family)
continue;
- if ((af == AF_INET)
- && (memcmp(&((struct sockaddr_in *)&soa->addrs[i].ss)->sin_addr, &((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr))))
+ if (!(addrsoa = dns_sa_addr(af, &soa->addrs[i].ss, &addrlen)))
continue;
- if ((af == AF_INET6)
- && (memcmp(&((struct sockaddr_in6 *)&soa->addrs[i].ss)->sin6_addr, &((struct sockaddr_in6 *)addr)->sin6_addr, sizeof(struct in6_addr))))
+ if (memcmp(addr, addrsoa, addrlen))
continue;
- memcpy(addr, &soa->addrs[i].ss, dns_af_len(af));
- return;
+ port = *dns_sa_port(af, &soa->addrs[i].ss);
+
+ return (port)? port : htons(53);
}
}
-}
+
+ return htons(53);
+} /* dns_hints_port() */
int dns_hints_dump(struct dns_hints *hints, FILE *fp) {
@@ -6283,11 +6139,6 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) {
#endif
if (-1 == (fd = socket(local->sa_family, type|flags, 0)))
goto soerr;
-
- if (local->sa_family == AF_INET6){
- int value=0;
- setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&value, sizeof(value));
- }
#if defined F_SETFD && !HAVE_SOCK_CLOEXEC
if (-1 == fcntl(fd, F_SETFD, 1))
@@ -6327,8 +6178,20 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) {
* TODO: Optionally rely on the kernel to select a random port.
*/
if (*dns_sa_port(local->sa_family, local) == 0) {
- /*bellesip: let the system find a random port*/
- return fd;
+ struct sockaddr_storage tmp;
+ unsigned i, port;
+
+ memcpy(&tmp, local, dns_sa_len(local));
+
+ for (i = 0; i < DNS_SO_MAXTRY; i++) {
+ port = 1025 + (dns_random() % 64510);
+
+ *dns_sa_port(tmp.ss_family, &tmp) = htons(port);
+
+ if (0 == bind(fd, (struct sockaddr *)&tmp, dns_sa_len(&tmp)))
+ return fd;
+ }
+
/* NB: continue to next bind statement */
}
@@ -6578,17 +6441,7 @@ int dns_so_submit(struct dns_socket *so, struct dns_packet *Q, struct sockaddr *
if ((error = dns_so_newanswer(so, (Q->memo.opt.maxudp)? Q->memo.opt.maxudp : DNS_SO_MINBUF)))
goto syerr;
- if (so->local.ss_family==AF_INET6 && host->sa_family==AF_INET){
- socklen_t addrlen = sizeof(so->remote);
- uint32_t *addr=(uint32_t*)dns_sa_addr(AF_INET6,&so->remote, &addrlen);
- /* add v4mapping*/
- so->remote.ss_family=AF_INET6;
- addr[0]=0;
- addr[1]=0;
- addr[2]=ntohl(0xffff);
- addr[3]=((struct sockaddr_in*)host)->sin_addr.s_addr;
- *dns_sa_port(AF_INET6,&so->remote)=((struct sockaddr_in*)host)->sin_port;
- }else memcpy(&so->remote, host, dns_sa_len(host));
+ memcpy(&so->remote, host, dns_sa_len(host));
so->query = Q;
so->qout = 0;
@@ -6735,7 +6588,6 @@ static int dns_so_tcp_recv(struct dns_socket *so) {
int dns_so_check(struct dns_socket *so) {
- struct sockaddr_storage reset_ss;
int error;
long n;
@@ -6744,8 +6596,6 @@ retry:
case DNS_SO_UDP_INIT:
so->state++;
case DNS_SO_UDP_CONN:
- memset(&reset_ss, 0, sizeof(reset_ss));
- connect(so->udp, (struct sockaddr *)&reset_ss, sizeof(reset_ss)); // Reset the previous connection
if (0 != connect(so->udp, (struct sockaddr *)&so->remote, dns_sa_len(&so->remote)))
goto soerr;
@@ -7055,8 +6905,6 @@ struct dns_resolver {
struct dns_rr_i hints_i, hints_j;
struct dns_rr hints_ns, ans_cname;
} stack[DNS_R_MAXDEPTH];
-
- unsigned char search_enabled;
}; /* struct dns_resolver */
@@ -7096,8 +6944,11 @@ struct dns_resolver *dns_res_open(struct dns_resolv_conf *resconf, struct dns_ho
* error from, say, dns_resconf_root(), and loading
* dns_resconf_local() by default would create undesirable surpises.
*/
- if (!resconf || !hosts || !hints)
+ if (!resconf || !hosts || !hints) {
+ if (!*_error)
+ *_error = EINVAL;
goto _error;
+ }
if (!(R = malloc(sizeof *R)))
goto syerr;
@@ -7169,10 +7020,16 @@ static void dns_res_frame_destroy(struct dns_resolver *R, struct dns_res_frame *
static void dns_res_frame_init(struct dns_resolver *R, struct dns_res_frame *frame) {
memset(frame, '\0', sizeof *frame);
- if (!R->resconf->options.recurse)
- frame->qflags |= DNS_Q_RD;
- if (R->resconf->options.edns0)
- frame->qflags |= DNS_Q_EDNS0;
+ /*
+ * NB: Can be invoked from dns_res_open, before R->resconf has been
+ * initialized.
+ */
+ if (R->resconf) {
+ if (!R->resconf->options.recurse)
+ frame->qflags |= DNS_Q_RD;
+ if (R->resconf->options.edns0)
+ frame->qflags |= DNS_Q_EDNS0;
+ }
} /* dns_res_frame_init() */
@@ -7632,8 +7489,8 @@ exec:
dgoto(R->sp, DNS_R_FOREACH_NS);
case DNS_R_FOREACH_A: {
- struct sockaddr_storage saddr={0};
- socklen_t saddr_len = sizeof(saddr);
+ struct dns_a a;
+ struct sockaddr_in sin;
/*
* NOTE: Iterator initialized in DNS_R_FOREACH_NS because
@@ -7644,7 +7501,7 @@ exec:
goto error;
F->hints_j.name = u.ns.host;
- F->hints_j.type = DNS_T_ALL;
+ F->hints_j.type = DNS_T_A;
F->hints_j.section = DNS_S_ALL & ~DNS_S_QD;
if (!dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) {
@@ -7654,28 +7511,24 @@ exec:
dgoto(R->sp, DNS_R_FOREACH_NS);
}
- saddr.ss_family = rr.type==DNS_T_AAAA ? AF_INET6 : AF_INET;
- if (saddr.ss_family==AF_INET){
- if ((error = dns_a_parse((struct dns_a *)dns_sa_addr(saddr.ss_family, &saddr, &saddr_len), &rr, F->hints)))
- goto error;
- }else{
- if ((error = dns_aaaa_parse((struct dns_aaaa *)dns_sa_addr(saddr.ss_family, &saddr, &saddr_len), &rr, F->hints)))
- goto error;
- }
+ if ((error = dns_a_parse(&a, &rr, F->hints)))
+ goto error;
- if (R->sp == 0) dns_fill_sockaddr_from_hints(R->hints, saddr.ss_family, (struct sockaddr *)&saddr);
- else *dns_sa_port(saddr.ss_family, &saddr) = htons(53);
+ sin.sin_family = AF_INET;
+ sin.sin_addr = a.addr;
+ if (R->sp == 0)
+ sin.sin_port = dns_hints_port(R->hints, AF_INET, &sin.sin_addr);
+ else
+ sin.sin_port = htons(53);
if (DNS_DEBUG) {
char addr[INET_ADDRSTRLEN + 1];
- if (saddr.ss_family==AF_INET)
- dns_a_print(addr, sizeof addr, (struct dns_a *)dns_sa_addr(saddr.ss_family, &saddr, &saddr_len));
- else dns_aaaa_print(addr, sizeof addr, (struct dns_aaaa *)dns_sa_addr(saddr.ss_family, &saddr, &saddr_len));
+ dns_a_print(addr, sizeof addr, &a);
dns_header(F->query)->qid = dns_so_mkqid(&R->so);
DNS_SHOW(F->query, "ASKING: %s/%s @ DEPTH: %u)", u.ns.host, addr, R->sp);
}
- if ((error = dns_so_submit(&R->so, F->query, (struct sockaddr *)&saddr)))
+ if ((error = dns_so_submit(&R->so, F->query, (struct sockaddr *)&sin)))
goto error;
F->state++;
@@ -7684,14 +7537,9 @@ exec:
if (dns_so_elapsed(&R->so) >= dns_resconf_timeout(R->resconf))
dgoto(R->sp, DNS_R_FOREACH_A);
- if ((error = dns_so_check(&R->so)) != 0){
- if (error == DNS_ENETUNREACH
- || error == DNS_ECONNREFUSED
- || error == EINVAL
- || error == DNS_EHOSTUNREACH) { /* maybe even more case*/
- dgoto(R->sp, DNS_R_FOREACH_A);
- }else goto error;
- }
+ if ((error = dns_so_check(&R->so)))
+ goto error;
+
if (!dns_p_setptr(&F->answer, dns_so_fetch(&R->so, &error)))
goto error;
@@ -7740,10 +7588,7 @@ exec:
if (!R->nodata)
dns_p_movptr(&R->nodata, &F->answer);
- if (R->search_enabled)
- dgoto(R->sp, DNS_R_SEARCH);
- else
- dgoto(R->sp, DNS_R_FINISH);
+ dgoto(R->sp, DNS_R_SEARCH);
}
dns_rr_foreach(&rr, F->answer, .section = DNS_S_NS, .type = DNS_T_NS) {
@@ -8044,15 +7889,11 @@ int dns_res_check(struct dns_resolver *R) {
struct dns_packet *dns_res_fetch(struct dns_resolver *R, int *error) {
struct dns_packet *P = NULL;
- if (R->stack[0].state != DNS_R_DONE) {
- *error = DNS_EUNKNOWN;
- return NULL;
- }
+ if (R->stack[0].state != DNS_R_DONE)
+ return *error = DNS_EUNKNOWN, (void *)0;
- if (!dns_p_movptr(&P, &R->stack[0].answer)) {
- *error = DNS_EFETCHED;
- return NULL;
- }
+ if (!dns_p_movptr(&P, &R->stack[0].answer))
+ return *error = DNS_EFETCHED, (void *)0;
return P;
} /* dns_res_fetch() */
@@ -8113,10 +7954,6 @@ void dns_res_sethints(struct dns_resolver *res, struct dns_hints *hints) {
res->hints = hints;
} /* dns_res_sethints() */
-void dns_res_enable_search(struct dns_resolver *res, unsigned char enable) {
- res->search_enabled = enable;
-}
-
/*
* A D D R I N F O R O U T I N E S
@@ -8133,6 +7970,7 @@ struct dns_addrinfo {
struct {
unsigned long todo;
+ int state;
int atype;
enum dns_type qtype;
} af;
@@ -8146,6 +7984,8 @@ struct dns_addrinfo {
char cname[DNS_D_MAXNAME + 1];
char i_cname[DNS_D_MAXNAME + 1], g_cname[DNS_D_MAXNAME + 1];
+ int g_depth;
+
int state;
int found;
@@ -8156,46 +7996,78 @@ struct dns_addrinfo {
#define DNS_AI_AFMAX 32
#define DNS_AI_AF2INDEX(af) (1UL << ((af) - 1))
+static inline unsigned long dns_ai_af2index(int af) {
+ dns_static_assert(dns_same_type(unsigned long, DNS_AI_AF2INDEX(1), 1), "internal type mismatch");
+ dns_static_assert(dns_same_type(unsigned long, ((struct dns_addrinfo *)0)->af.todo, 1), "internal type mismatch");
+
+ return (af > 0 && af <= DNS_AI_AFMAX)? DNS_AI_AF2INDEX(af) : 0;
+}
+
+static int dns_ai_setaf(struct dns_addrinfo *ai, int af, int qtype) {
+ ai->af.atype = af;
+ ai->af.qtype = qtype;
+
+ ai->af.todo &= ~dns_ai_af2index(af);
+
+ return af;
+} /* dns_ai_setaf() */
+
+#define DNS_SM_RESTORE \
+ do { pc = 0xff & (ai->af.state >> 0); i = 0xff & (ai->af.state >> 8); } while (0)
+#define DNS_SM_SAVE \
+ do { ai->af.state = ((0xff & pc) << 0) | ((0xff & i) << 8); } while (0)
+
static int dns_ai_nextaf(struct dns_addrinfo *ai) {
- int qtype = 0, atype = 0;
- unsigned i;
+ int i, pc;
dns_static_assert(AF_UNSPEC == 0, "AF_UNSPEC constant not 0");
dns_static_assert(AF_INET <= DNS_AI_AFMAX, "AF_INET constant too large");
dns_static_assert(AF_INET6 <= DNS_AI_AFMAX, "AF_INET6 constant too large");
- for (i = 0; i < lengthof(ai->res->resconf->family); i++) {
- int af = ai->res->resconf->family[i];
+ DNS_SM_ENTER;
- if (af == AF_UNSPEC)
- break;
- if (af < 0 || af > DNS_AI_AFMAX)
- continue;
- if (!(DNS_AI_AF2INDEX(af) & ai->af.todo))
- continue;
+ if (ai->res) {
+ /*
+ * NB: On OpenBSD, at least, the types of entries resolved
+ * is the intersection of the /etc/resolv.conf families and
+ * the families permitted by the .ai_type hint. So if
+ * /etc/resolv.conf has "family inet4" and .ai_type
+ * is AF_INET6, then the address ::1 will return 0 entries
+ * even if AI_NUMERICHOST is specified in .ai_flags.
+ */
+ while (i < (int)lengthof(ai->res->resconf->family)) {
+ int af = ai->res->resconf->family[i++];
- switch (af) {
- case AF_INET:
- atype = AF_INET;
- qtype = DNS_T_A;
- goto update;
- case AF_INET6:
- atype = AF_INET6;
- qtype = DNS_T_AAAA;
- goto update;
+ if (af == AF_UNSPEC) {
+ DNS_SM_EXIT;
+ } else if (af < 0 || af > DNS_AI_AFMAX) {
+ continue;
+ } else if (!(DNS_AI_AF2INDEX(af) & ai->af.todo)) {
+ continue;
+ } else if (af == AF_INET) {
+ DNS_SM_YIELD(dns_ai_setaf(ai, AF_INET, DNS_T_A));
+ } else if (af == AF_INET6) {
+ DNS_SM_YIELD(dns_ai_setaf(ai, AF_INET6, DNS_T_AAAA));
+ }
}
+ } else {
+ /*
+ * NB: If we get here than AI_NUMERICFLAGS should be set and
+ * order shouldn't matter.
+ */
+ if (DNS_AI_AF2INDEX(AF_INET) & ai->af.todo)
+ DNS_SM_YIELD(dns_ai_setaf(ai, AF_INET, DNS_T_A));
+ if (DNS_AI_AF2INDEX(AF_INET6) & ai->af.todo)
+ DNS_SM_YIELD(dns_ai_setaf(ai, AF_INET6, DNS_T_AAAA));
}
-update:
- ai->af.atype = atype;
- ai->af.qtype = qtype;
-
- if (atype)
- ai->af.todo &= ~DNS_AI_AF2INDEX(atype);
+ DNS_SM_LEAVE;
- return atype;
+ return dns_ai_setaf(ai, AF_UNSPEC, 0);
} /* dns_ai_nextaf() */
+#undef DNS_SM_RESTORE
+#undef DNS_SM_SAVE
static enum dns_type dns_ai_qtype(struct dns_addrinfo *ai) {
return (ai->qtype)? ai->qtype : ai->af.qtype;
@@ -8229,7 +8101,7 @@ static dns_error_t dns_ai_parseport(unsigned short *port, const char *serv, cons
} /* dns_ai_parseport() */
-struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_type qtype, const struct addrinfo *hints, struct dns_resolver *res, int *error_) {
+struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_type qtype, const struct addrinfo *hints, struct dns_resolver *res, int *_error) {
static const struct dns_addrinfo ai_initializer;
struct dns_addrinfo *ai;
int error;
@@ -8242,6 +8114,8 @@ struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_ty
* API function call, such as dns_res_stub(). Should change
* this semantic, but it's applied elsewhere, too.
*/
+ if (!*_error)
+ *_error = EINVAL;
return NULL;
}
@@ -8264,6 +8138,12 @@ struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_ty
goto error;
ai->port = ai->qport;
+ /*
+ * FIXME: If an explicit A or AAAA record type conflicts with
+ * .ai_family or with resconf.family (i.e. AAAA specified but
+ * AF_INET6 not in interection of .ai_family and resconf.family),
+ * then what?
+ */
switch (ai->qtype) {
case DNS_T_A:
ai->af.todo = DNS_AI_AF2INDEX(AF_INET);
@@ -8291,7 +8171,7 @@ struct dns_addrinfo *dns_ai_open(const char *host, const char *serv, enum dns_ty
syerr:
error = dns_syerr();
error:
- *error_ = error;
+ *_error = error;
dns_ai_close(ai);
dns_res_close(res);
@@ -8381,6 +8261,7 @@ enum dns_ai_state {
DNS_AI_S_CHECK,
DNS_AI_S_FETCH,
DNS_AI_S_FOREACH_I,
+ DNS_AI_S_INIT_G,
DNS_AI_S_ITERATE_G,
DNS_AI_S_FOREACH_G,
DNS_AI_S_SUBMIT_G,
@@ -8503,6 +8384,10 @@ exec:
} /* switch() */
ai->state++;
+ case DNS_AI_S_INIT_G:
+ ai->g_depth = 0;
+
+ ai->state++;
case DNS_AI_S_ITERATE_G:
dns_strlcpy(ai->g_cname, ai->cname, sizeof ai->g_cname);
dns_rr_i_init(&ai->g, ai->glue);
@@ -8527,6 +8412,9 @@ exec:
/* skip if already queried */
if (dns_rr_grep(&rr, 1, dns_rr_i_new(ai->glue, .section = DNS_S_QD, .name = ai->g.name, .type = ai->g.type), ai->glue, &error))
dns_ai_goto(DNS_AI_S_FOREACH_I);
+ /* skip if we recursed (CNAME chains should have been handled in the resolver) */
+ if (++ai->g_depth > 1)
+ dns_ai_goto(DNS_AI_S_FOREACH_I);
if ((error = dns_res_submit(ai->res, ai->g.name, ai->g.type, DNS_C_IN)))
return error;
diff --git a/src/dns.h b/src/dns.h
index d4b1dca..78d6402 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -25,9 +25,7 @@
*/
#ifndef DNS_H
#define DNS_H
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+
#include <stddef.h> /* size_t offsetof() */
#include <stdio.h> /* FILE */
@@ -77,7 +75,7 @@
#define DNS_VENDOR "[email protected]"
-#define DNS_V_REL 0x20160608
+#define DNS_V_REL 0x20161214
#define DNS_V_ABI 0x20160608
#define DNS_V_API 0x20160608
@@ -537,7 +535,7 @@ struct dns_rr_i {
int follow;
- int (*sort)(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *);
+ int (*sort)();
unsigned args[2];
struct {
@@ -563,9 +561,11 @@ DNS_PUBLIC struct dns_rr_i *dns_rr_i_init(struct dns_rr_i *, struct dns_packet *
DNS_PUBLIC unsigned dns_rr_grep(struct dns_rr *, unsigned, struct dns_rr_i *, struct dns_packet *, int *);
-#define dns_rr_foreach(rr, P, ...) \
+#define dns_rr_foreach_(rr, P, ...) \
for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = *dns_rr_i_new((P), __VA_ARGS__); dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), &(int){ 0 }); )
+#define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__)
+
/*
* A R E S O U R C E R E C O R D
@@ -948,39 +948,16 @@ DNS_PUBLIC int dns_resconf_loadfile(struct dns_resolv_conf *, FILE *);
DNS_PUBLIC int dns_resconf_loadpath(struct dns_resolv_conf *, const char *);
-#ifdef USE_FIXED_NAMESERVERS
-int dns_resconf_load_fixed_nameservers(struct dns_resolv_conf *resconf);
-#endif /* USE_FIXED_NAMESERVERS */
-
-#ifdef USE_STRUCT_RES_STATE_NAMESERVERS
-int dns_resconf_load_struct_res_state_nameservers(struct dns_resolv_conf *resconf);
-#endif /* USE_STRUCT_RES_STATE_NAMESERVERS */
-
-#ifdef _WIN32
-DNS_PUBLIC int dns_resconf_loadwin(struct dns_resolv_conf *);
-#endif
-
-#ifdef ANDROID
-DNS_PUBLIC int dns_resconf_loadandroid(struct dns_resolv_conf *resconf);
-#endif
-
-#ifdef HAVE_RESINIT
-DNS_PUBLIC int dns_resconf_loadfromresolv(struct dns_resolv_conf *resconf);
-#endif /*HAVE_RESINIT*/
-
DNS_PUBLIC int dns_nssconf_loadfile(struct dns_resolv_conf *, FILE *);
DNS_PUBLIC int dns_nssconf_loadpath(struct dns_resolv_conf *, const char *);
-DNS_PUBLIC int dns_resconf_pton(struct sockaddr_storage *ss, const char *src);
-
DNS_PUBLIC int dns_resconf_dump(struct dns_resolv_conf *, FILE *);
DNS_PUBLIC int dns_nssconf_dump(struct dns_resolv_conf *, FILE *);
DNS_PUBLIC int dns_resconf_setiface(struct dns_resolv_conf *, const char *, unsigned short);
-
typedef unsigned long dns_resconf_i_t;
DNS_PUBLIC size_t dns_resconf_search(void *, size_t, const void *, size_t, struct dns_resolv_conf *, dns_resconf_i_t *);
@@ -1200,8 +1177,6 @@ DNS_PUBLIC const struct dns_stat *dns_res_stat(struct dns_resolver *);
DNS_PUBLIC void dns_res_sethints(struct dns_resolver *, struct dns_hints *);
-DNS_PUBLIC void dns_res_enable_search(struct dns_resolver *, unsigned char enable);
-
/*
* A D D R I N F O I N T E R F A C E
--
2.11.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment