Use libresolv to initialize cares on iPhone targets
On iPhone targets like iOS, watchOS or tvOS the file /etc/resolv.conf cannot be used to configure cares. Instead the resolver library is queried for configuration values. CC: Yury Kirpichev <ykirpichev@yandex-team.ru>
This commit is contained in:
committed by
David Drysdale
parent
f945a0cfe3
commit
affc63cba8
+70
-5
@@ -49,6 +49,10 @@
|
||||
#define MAX_DNS_PROPERTIES 8
|
||||
#endif
|
||||
|
||||
#if defined(CARES_USE_LIBRESOLV)
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
|
||||
#include "ares.h"
|
||||
#include "ares_inet_net_pton.h"
|
||||
#include "ares_library_init.h"
|
||||
@@ -77,7 +81,7 @@ static const char *try_option(const char *p, const char *q, const char *opt);
|
||||
static int init_id_key(rc4_key* key,int key_data_len);
|
||||
|
||||
#if !defined(WIN32) && !defined(WATT32) && \
|
||||
!defined(ANDROID) && !defined(__ANDROID__)
|
||||
!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
|
||||
static int sortlist_alloc(struct apattern **sortlist, int *nsort,
|
||||
struct apattern *pat);
|
||||
static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
|
||||
@@ -1067,7 +1071,8 @@ static int get_DNS_Windows(char **outptr)
|
||||
|
||||
static int init_by_resolv_conf(ares_channel channel)
|
||||
{
|
||||
#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32)
|
||||
#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
|
||||
!defined(CARES_USE_LIBRESOLV)
|
||||
char *line = NULL;
|
||||
#endif
|
||||
int status = -1, nservers = 0, nsort = 0;
|
||||
@@ -1159,6 +1164,65 @@ static int init_by_resolv_conf(ares_channel channel)
|
||||
break;
|
||||
status = ARES_EOF;
|
||||
}
|
||||
#elif defined(CARES_USE_LIBRESOLV)
|
||||
struct __res_state res;
|
||||
memset(&res, 0, sizeof(res));
|
||||
int result = res_ninit(&res);
|
||||
if (result == 0 && (res.options & RES_INIT)) {
|
||||
status = ARES_EOF;
|
||||
|
||||
if (channel->nservers == -1) {
|
||||
union res_sockaddr_union addr[MAXNS];
|
||||
int nscount = res_getservers(&res, addr, MAXNS);
|
||||
for (int i = 0; i < nscount; ++i) {
|
||||
char str[INET6_ADDRSTRLEN];
|
||||
int config_status;
|
||||
sa_family_t family = addr[i].sin.sin_family;
|
||||
if (family == AF_INET) {
|
||||
ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str));
|
||||
} else if (family == AF_INET6) {
|
||||
ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str));
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
config_status = config_nameserver(&servers, &nservers, str);
|
||||
if (config_status != ARES_SUCCESS) {
|
||||
status = config_status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channel->ndomains == -1) {
|
||||
int entries = 0;
|
||||
while ((entries < MAXDNSRCH) && res.dnsrch[entries])
|
||||
entries++;
|
||||
|
||||
channel->domains = malloc(entries * sizeof(char *));
|
||||
if (!channel->domains) {
|
||||
status = ARES_ENOMEM;
|
||||
} else {
|
||||
channel->ndomains = entries;
|
||||
for (int i = 0; i < channel->ndomains; ++i) {
|
||||
channel->domains[i] = strdup(res.dnsrch[i]);
|
||||
if (!channel->domains[i]) {
|
||||
status = ARES_ENOMEM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (channel->ndots == -1)
|
||||
channel->ndots = res.ndots;
|
||||
if (channel->tries == -1)
|
||||
channel->tries = res.retry;
|
||||
if (channel->rotate == -1)
|
||||
channel->rotate = res.options & RES_ROTATE;
|
||||
if (channel->timeout == -1)
|
||||
channel->timeout = res.retrans * 1000;
|
||||
|
||||
res_ndestroy(&res);
|
||||
}
|
||||
#else
|
||||
{
|
||||
char *p;
|
||||
@@ -1479,7 +1543,7 @@ static int init_by_defaults(ares_channel channel)
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && !defined(WATT32) && \
|
||||
!defined(ANDROID) && !defined(__ANDROID__)
|
||||
!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
|
||||
static int config_domain(ares_channel channel, char *str)
|
||||
{
|
||||
char *q;
|
||||
@@ -1592,7 +1656,8 @@ static int config_nameserver(struct server_state **servers, int *nservers,
|
||||
return ARES_SUCCESS;
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__)
|
||||
#if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__) && \
|
||||
!defined(CARES_USE_LIBRESOLV)
|
||||
static int config_sortlist(struct apattern **sortlist, int *nsort,
|
||||
const char *str)
|
||||
{
|
||||
@@ -1773,7 +1838,7 @@ static const char *try_option(const char *p, const char *q, const char *opt)
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && !defined(WATT32) && \
|
||||
!defined(ANDROID) && !defined(__ANDROID__)
|
||||
!defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
|
||||
static char *try_config(char *s, const char *opt, char scc)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
@@ -346,6 +346,30 @@ if test "$HAVE_GETHOSTBYNAME" != "1"; then
|
||||
AC_MSG_ERROR([couldn't find libraries for gethostbyname()])
|
||||
fi
|
||||
|
||||
dnl resolv lib for iPhone
|
||||
AS_IF([test "x$host_vendor" = "xapple"], [
|
||||
AC_MSG_CHECKING([for iPhone target])
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([[
|
||||
#include "TargetConditionals.h"
|
||||
]], [[
|
||||
#if TARGET_OS_IPHONE == 0
|
||||
#error Not an iPhone target
|
||||
#endif
|
||||
return 0;
|
||||
]])
|
||||
],[
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_SEARCH_LIBS([res_servicename], [resolv], [
|
||||
AC_DEFINE([CARES_USE_LIBRESOLV], [1], [Use resolver library to configure cares])
|
||||
], [
|
||||
AC_MSG_ERROR([Unable to find libresolv which is required for iPhone targets])
|
||||
])
|
||||
],[
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
])
|
||||
|
||||
dnl resolve lib?
|
||||
AC_CHECK_FUNC(strcasecmp, , [ AC_CHECK_LIB(resolve, strcasecmp) ])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user