Revert "dns cache per interface iteration 2"
This reverts commit f1464ff956
Change-Id: I3496b9a8cb54614fe3eea016d1391c8a89f3db38
This commit is contained in:

committed by
Android (Google) Code Review

parent
f1464ff956
commit
b002a2ff77
@@ -43,7 +43,6 @@
|
||||
#include <arpa/inet.h>
|
||||
#include "resolv_private.h"
|
||||
#include "resolv_iface.h"
|
||||
#include "res_private.h"
|
||||
|
||||
/* This code implements a small and *simple* DNS resolver cache.
|
||||
*
|
||||
@@ -1250,16 +1249,9 @@ typedef struct resolv_cache_info {
|
||||
struct resolv_cache_info* next;
|
||||
char* nameservers[MAXNS +1];
|
||||
struct addrinfo* nsaddrinfo[MAXNS + 1];
|
||||
char defdname[256];
|
||||
int dnsrch_offset[MAXDNSRCH+1]; // offsets into defdname
|
||||
char* domains;
|
||||
} CacheInfo;
|
||||
|
||||
typedef struct resolv_pidiface_info {
|
||||
int pid;
|
||||
char ifname[IF_NAMESIZE + 1];
|
||||
struct resolv_pidiface_info* next;
|
||||
} PidIfaceInfo;
|
||||
|
||||
#define HTABLE_VALID(x) ((x) != NULL && (x) != HTABLE_DELETED)
|
||||
|
||||
static void
|
||||
@@ -1312,7 +1304,6 @@ _cache_check_pending_request_locked( struct resolv_cache* cache, Entry* key )
|
||||
}
|
||||
} else {
|
||||
struct timespec ts = {0,0};
|
||||
XLOG("Waiting for previous request");
|
||||
ts.tv_sec = _time_now() + PENDING_REQUEST_TIMEOUT;
|
||||
pthread_cond_timedwait(&ri->cond, &cache->lock, &ts);
|
||||
}
|
||||
@@ -1408,8 +1399,9 @@ _res_cache_get_max_entries( void )
|
||||
if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
|
||||
// Don't use the cache in local mode. This is used by the
|
||||
// proxy itself.
|
||||
XLOG("setup cache for non-cache process. size=0, %s", cache_mode);
|
||||
return 0;
|
||||
// TODO - change this to 0 when all dns stuff uses proxy (5918973)
|
||||
XLOG("setup cache for non-cache process. size=1");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (__system_property_get(DNS_CACHE_SIZE_PROP_NAME, cache_size) > 0) {
|
||||
@@ -1548,7 +1540,7 @@ _cache_lookup_p( Cache* cache,
|
||||
|
||||
pnode = &node->hlink;
|
||||
}
|
||||
return pnode;
|
||||
return pnode;
|
||||
}
|
||||
|
||||
/* Add a new entry to the hash table. 'lookup' must be the
|
||||
@@ -1789,28 +1781,20 @@ Exit:
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
|
||||
static pthread_once_t _res_cache_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_once_t _res_cache_once;
|
||||
|
||||
// Head of the list of caches. Protected by _res_cache_list_lock.
|
||||
static struct resolv_cache_info _res_cache_list;
|
||||
|
||||
// List of pid iface pairs
|
||||
static struct resolv_pidiface_info _res_pidiface_list;
|
||||
|
||||
// name of the current default inteface
|
||||
static char _res_default_ifname[IF_NAMESIZE + 1];
|
||||
|
||||
// lock protecting everything in the _resolve_cache_info structs (next ptr, etc)
|
||||
static pthread_mutex_t _res_cache_list_lock;
|
||||
|
||||
// lock protecting the _res_pid_iface_list
|
||||
static pthread_mutex_t _res_pidiface_list_lock;
|
||||
|
||||
/* lookup the default interface name */
|
||||
static char *_get_default_iface_locked();
|
||||
/* find the first cache that has an associated interface and return the name of the interface */
|
||||
static char* _find_any_iface_name_locked( void );
|
||||
|
||||
/* insert resolv_cache_info into the list of resolv_cache_infos */
|
||||
static void _insert_cache_info_locked(struct resolv_cache_info* cache_info);
|
||||
/* creates a resolv_cache_info */
|
||||
@@ -1831,14 +1815,8 @@ static int _get_nameserver_locked(const char* ifname, int n, char* addr, int add
|
||||
static struct addrinfo* _get_nameserver_addr_locked(const char* ifname, int n);
|
||||
/* lookup the inteface's address */
|
||||
static struct in_addr* _get_addr_locked(const char * ifname);
|
||||
/* return 1 if the provided list of name servers differs from the list of name servers
|
||||
* currently attached to the provided cache_info */
|
||||
static int _resolv_is_nameservers_equal_locked(struct resolv_cache_info* cache_info,
|
||||
char** servers, int numservers);
|
||||
/* remove a resolv_pidiface_info structure from _res_pidiface_list */
|
||||
static void _remove_pidiface_info_locked(int pid);
|
||||
/* get a resolv_pidiface_info structure from _res_pidiface_list with a certain pid */
|
||||
static struct resolv_pidiface_info* _get_pid_iface_info_locked(int pid);
|
||||
|
||||
|
||||
|
||||
static void
|
||||
_res_cache_init(void)
|
||||
@@ -1852,36 +1830,37 @@ _res_cache_init(void)
|
||||
|
||||
memset(&_res_default_ifname, 0, sizeof(_res_default_ifname));
|
||||
memset(&_res_cache_list, 0, sizeof(_res_cache_list));
|
||||
memset(&_res_pidiface_list, 0, sizeof(_res_pidiface_list));
|
||||
pthread_mutex_init(&_res_cache_list_lock, NULL);
|
||||
pthread_mutex_init(&_res_pidiface_list_lock, NULL);
|
||||
}
|
||||
|
||||
struct resolv_cache*
|
||||
__get_res_cache(const char* ifname)
|
||||
__get_res_cache(void)
|
||||
{
|
||||
struct resolv_cache *cache;
|
||||
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
char* iface;
|
||||
if (ifname == NULL || ifname[0] == '\0') {
|
||||
iface = _get_default_iface_locked();
|
||||
if (iface[0] == '\0') {
|
||||
char* tmp = _find_any_iface_name_locked();
|
||||
if (tmp) {
|
||||
iface = tmp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iface = (char *) ifname;
|
||||
}
|
||||
char* ifname = _get_default_iface_locked();
|
||||
|
||||
cache = _get_res_cache_for_iface_locked(iface);
|
||||
// if default interface not set then use the first cache
|
||||
// associated with an interface as the default one.
|
||||
if (ifname[0] == '\0') {
|
||||
struct resolv_cache_info* cache_info = _res_cache_list.next;
|
||||
while (cache_info) {
|
||||
if (cache_info->ifname[0] != '\0') {
|
||||
ifname = cache_info->ifname;
|
||||
break;
|
||||
}
|
||||
|
||||
cache_info = cache_info->next;
|
||||
}
|
||||
}
|
||||
cache = _get_res_cache_for_iface_locked(ifname);
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
XLOG("_get_res_cache: iface = %s, cache=%p\n", iface, cache);
|
||||
XLOG("_get_res_cache. default_ifname = %s\n", ifname);
|
||||
return cache;
|
||||
}
|
||||
|
||||
@@ -2037,29 +2016,11 @@ _find_cache_info_locked(const char* ifname)
|
||||
static char*
|
||||
_get_default_iface_locked(void)
|
||||
{
|
||||
|
||||
char* iface = _res_default_ifname;
|
||||
|
||||
return iface;
|
||||
}
|
||||
|
||||
static char*
|
||||
_find_any_iface_name_locked( void ) {
|
||||
char* ifname = NULL;
|
||||
|
||||
struct resolv_cache_info* cache_info = _res_cache_list.next;
|
||||
while (cache_info) {
|
||||
if (cache_info->ifname[0] != '\0') {
|
||||
ifname = cache_info->ifname;
|
||||
break;
|
||||
}
|
||||
|
||||
cache_info = cache_info->next;
|
||||
}
|
||||
|
||||
return ifname;
|
||||
}
|
||||
|
||||
void
|
||||
_resolv_set_default_iface(const char* ifname)
|
||||
{
|
||||
@@ -2083,19 +2044,16 @@ _resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numser
|
||||
int i, rt, index;
|
||||
struct addrinfo hints;
|
||||
char sbuf[NI_MAXSERV];
|
||||
register char *cp;
|
||||
int *offset;
|
||||
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
// creates the cache if not created
|
||||
_get_res_cache_for_iface_locked(ifname);
|
||||
|
||||
struct resolv_cache_info* cache_info = _find_cache_info_locked(ifname);
|
||||
|
||||
if (cache_info != NULL &&
|
||||
!_resolv_is_nameservers_equal_locked(cache_info, servers, numservers)) {
|
||||
if (cache_info != NULL) {
|
||||
// free current before adding new
|
||||
_free_nameservers_locked(cache_info);
|
||||
|
||||
@@ -2111,68 +2069,15 @@ _resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numser
|
||||
if (rt == 0) {
|
||||
cache_info->nameservers[index] = strdup(servers[i]);
|
||||
index++;
|
||||
XLOG("_resolv_set_nameservers_for_iface: iface = %s, addr = %s\n",
|
||||
ifname, servers[i]);
|
||||
} else {
|
||||
cache_info->nsaddrinfo[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// code moved from res_init.c, load_domain_search_list
|
||||
strlcpy(cache_info->defdname, domains, sizeof(cache_info->defdname));
|
||||
if ((cp = strchr(cache_info->defdname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
cp = cache_info->defdname;
|
||||
offset = cache_info->dnsrch_offset;
|
||||
while (offset < cache_info->dnsrch_offset + MAXDNSRCH) {
|
||||
while (*cp == ' ' || *cp == '\t') /* skip leading white space */
|
||||
cp++;
|
||||
if (*cp == '\0') /* stop if nothing more to do */
|
||||
break;
|
||||
*offset++ = cp - cache_info->defdname; /* record this search domain */
|
||||
while (*cp) { /* zero-terminate it */
|
||||
if (*cp == ' '|| *cp == '\t') {
|
||||
*cp++ = '\0';
|
||||
break;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
*offset = -1; /* cache_info->dnsrch_offset has MAXDNSRCH+1 items */
|
||||
|
||||
// flush cache since new settings
|
||||
_flush_cache_for_iface_locked(ifname);
|
||||
|
||||
cache_info->domains = strdup(domains);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
_resolv_is_nameservers_equal_locked(struct resolv_cache_info* cache_info,
|
||||
char** servers, int numservers)
|
||||
{
|
||||
int i;
|
||||
char** ns;
|
||||
int equal = 1;
|
||||
|
||||
// compare each name server against current name servers
|
||||
if (numservers > MAXNS) numservers = MAXNS;
|
||||
for (i = 0; i < numservers && equal; i++) {
|
||||
ns = cache_info->nameservers;
|
||||
equal = 0;
|
||||
while(*ns) {
|
||||
if (strcmp(*ns, servers[i]) == 0) {
|
||||
equal = 1;
|
||||
break;
|
||||
}
|
||||
ns++;
|
||||
}
|
||||
}
|
||||
|
||||
return equal;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_nameservers_locked(struct resolv_cache_info* cache_info)
|
||||
{
|
||||
@@ -2315,192 +2220,3 @@ _get_addr_locked(const char * ifname)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_remove_pidiface_info_locked(int pid) {
|
||||
struct resolv_pidiface_info* result = &_res_pidiface_list;
|
||||
struct resolv_pidiface_info* prev = NULL;
|
||||
|
||||
while (result != NULL && result->pid != pid) {
|
||||
prev = result;
|
||||
result = result->next;
|
||||
}
|
||||
if (prev != NULL && result != NULL) {
|
||||
prev->next = result->next;
|
||||
free(result);
|
||||
}
|
||||
}
|
||||
|
||||
static struct resolv_pidiface_info*
|
||||
_get_pid_iface_info_locked(int pid)
|
||||
{
|
||||
struct resolv_pidiface_info* result = &_res_pidiface_list;
|
||||
while (result != NULL && result->pid != pid) {
|
||||
result = result->next;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
_resolv_set_iface_for_pid(const char* ifname, int pid)
|
||||
{
|
||||
// make sure the pid iface list is created
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_pidiface_list_lock);
|
||||
|
||||
struct resolv_pidiface_info* pidiface_info = _get_pid_iface_info_locked(pid);
|
||||
if (!pidiface_info) {
|
||||
pidiface_info = calloc(sizeof(*pidiface_info), 1);
|
||||
if (pidiface_info) {
|
||||
pidiface_info->pid = pid;
|
||||
int len = sizeof(pidiface_info->ifname);
|
||||
strncpy(pidiface_info->ifname, ifname, len - 1);
|
||||
pidiface_info->ifname[len - 1] = '\0';
|
||||
|
||||
pidiface_info->next = _res_pidiface_list.next;
|
||||
_res_pidiface_list.next = pidiface_info;
|
||||
|
||||
XLOG("_resolv_set_iface_for_pid: pid %d , iface %s\n", pid, ifname);
|
||||
} else {
|
||||
XLOG("_resolv_set_iface_for_pid failing calloc");
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_res_pidiface_list_lock);
|
||||
}
|
||||
|
||||
void
|
||||
_resolv_clear_iface_for_pid(int pid)
|
||||
{
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_pidiface_list_lock);
|
||||
|
||||
_remove_pidiface_info_locked(pid);
|
||||
|
||||
XLOG("_resolv_clear_iface_for_pid: pid %d\n", pid);
|
||||
|
||||
pthread_mutex_unlock(&_res_pidiface_list_lock);
|
||||
}
|
||||
|
||||
int
|
||||
_resolv_get_pids_associated_interface(int pid, char* buff, int buffLen)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
if (!buff) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_pidiface_list_lock);
|
||||
|
||||
struct resolv_pidiface_info* pidiface_info = _get_pid_iface_info_locked(pid);
|
||||
buff[0] = '\0';
|
||||
if (pidiface_info) {
|
||||
len = strlen(pidiface_info->ifname);
|
||||
if (len < buffLen) {
|
||||
strncpy(buff, pidiface_info->ifname, len);
|
||||
buff[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
XLOG("_resolv_get_pids_associated_interface buff: %s\n", buff);
|
||||
|
||||
pthread_mutex_unlock(&_res_pidiface_list_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
_resolv_get_default_iface(char* buff, int buffLen)
|
||||
{
|
||||
char* ifname;
|
||||
int len = 0;
|
||||
|
||||
if (!buff || buffLen == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
|
||||
ifname = _get_default_iface_locked();
|
||||
|
||||
// if default interface not set. Get first cache with an interface
|
||||
if (ifname[0] == '\0') {
|
||||
ifname = _find_any_iface_name_locked();
|
||||
}
|
||||
|
||||
if (ifname) {
|
||||
len = strlen(ifname);
|
||||
if (len < buffLen) {
|
||||
strncpy(buff, ifname, len);
|
||||
buff[len] = '\0';
|
||||
}
|
||||
} else {
|
||||
buff[0] = '\0';
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
_resolv_populate_res_for_iface(res_state statp)
|
||||
{
|
||||
int nserv;
|
||||
struct resolv_cache_info* info = NULL;
|
||||
|
||||
if (statp) {
|
||||
struct addrinfo* ai;
|
||||
|
||||
if (statp->iface[0] == '\0') { // no interface set assign default
|
||||
_resolv_get_default_iface(statp->iface, sizeof(statp->iface));
|
||||
}
|
||||
|
||||
pthread_once(&_res_cache_once, _res_cache_init);
|
||||
pthread_mutex_lock(&_res_cache_list_lock);
|
||||
info = _find_cache_info_locked(statp->iface);
|
||||
|
||||
if (info == NULL) return 0;
|
||||
|
||||
XLOG("_resolv_populate_res_for_iface: %s\n", statp->iface);
|
||||
for (nserv = 0; nserv < MAXNS; nserv++) {
|
||||
ai = info->nsaddrinfo[nserv];
|
||||
if (ai == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((size_t) ai->ai_addrlen <= sizeof(statp->_u._ext.ext->nsaddrs[0])) {
|
||||
if (statp->_u._ext.ext != NULL) {
|
||||
memcpy(&statp->_u._ext.ext->nsaddrs[nserv], ai->ai_addr, ai->ai_addrlen);
|
||||
statp->nsaddr_list[nserv].sin_family = AF_UNSPEC;
|
||||
} else {
|
||||
if ((size_t) ai->ai_addrlen
|
||||
<= sizeof(statp->nsaddr_list[0])) {
|
||||
memcpy(&statp->nsaddr_list[nserv], ai->ai_addr,
|
||||
ai->ai_addrlen);
|
||||
} else {
|
||||
statp->nsaddr_list[nserv].sin_family = AF_UNSPEC;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
XLOG("_resolv_populate_res_for_iface found too long addrlen");
|
||||
}
|
||||
}
|
||||
statp->nscount = nserv;
|
||||
// now do search domains. Note that we cache the offsets as this code runs alot
|
||||
// but the setting/offset-computer only runs when set/changed
|
||||
strlcpy(statp->defdname, info->defdname, sizeof(statp->defdname));
|
||||
register char **pp = statp->dnsrch;
|
||||
register int *p = info->dnsrch_offset;
|
||||
while (pp < statp->dnsrch + MAXDNSRCH && *p != -1) {
|
||||
*pp++ = &statp->defdname + *p++;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&_res_cache_list_lock);
|
||||
}
|
||||
return nserv;
|
||||
}
|
||||
|
@@ -82,7 +82,13 @@ extern struct __res_state _nres;
|
||||
|
||||
int res_ourserver_p(const res_state, const struct sockaddr *);
|
||||
|
||||
#ifdef ANDROID_CHANGES
|
||||
static int res_need_init() {
|
||||
return ((_nres.options & RES_INIT) == 0U) || res_get_dns_changed();
|
||||
}
|
||||
#else
|
||||
#define res_need_init() ((_nres.options & RES_INIT) == 0U)
|
||||
#endif
|
||||
|
||||
int
|
||||
res_init(void) {
|
||||
|
@@ -111,6 +111,13 @@ __RCSID("$NetBSD: res_init.c,v 1.8 2006/03/19 03:10:08 christos Exp $");
|
||||
/* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
|
||||
#ifdef ANDROID_CHANGES
|
||||
#include "resolv_private.h"
|
||||
#define MAX_DNS_PROPERTIES 8
|
||||
#define DNS_PROP_NAME_PREFIX "net.dns"
|
||||
#define DNS_CHANGE_PROP_NAME "net.dnschange"
|
||||
#define DNS_SEARCH_PROP_NAME "net.dns.search"
|
||||
static const prop_info *dns_change_prop;
|
||||
static int dns_last_change_counter;
|
||||
static int _get_dns_change_count();
|
||||
#else
|
||||
#include <resolv.h>
|
||||
#endif
|
||||
@@ -164,6 +171,41 @@ res_ninit(res_state statp) {
|
||||
return (__res_vinit(statp, 0));
|
||||
}
|
||||
|
||||
#ifdef ANDROID_CHANGES
|
||||
static int load_domain_search_list(res_state statp) {
|
||||
char propvalue[PROP_VALUE_MAX];
|
||||
register char *cp, **pp;
|
||||
|
||||
if(__system_property_get(DNS_SEARCH_PROP_NAME, propvalue) >= 1) {
|
||||
strlcpy(statp->defdname, propvalue, sizeof(statp->defdname));
|
||||
if ((cp = strchr(statp->defdname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
cp = statp->defdname;
|
||||
pp = statp->dnsrch;
|
||||
while ( pp < statp->dnsrch + MAXDNSRCH ) {
|
||||
while (*cp == ' ' || *cp == '\t') /* skip leading white space */
|
||||
cp++;
|
||||
if (*cp == '\0') /* stop if nothing more */
|
||||
break;
|
||||
*pp++ = cp; /* record this search domain */
|
||||
while (*cp) { /* zero-terminate it */
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
*cp++ = '\0';
|
||||
break;
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
*pp = NULL; /* statp->dnsrch has MAXDNSRCH+1 items */
|
||||
if (pp > statp->dnsrch)
|
||||
return 1;
|
||||
}
|
||||
statp->defdname[0] = '\0'; /* no default domain name on Android */
|
||||
statp->dnsrch[0] = NULL;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This function has to be reachable by res_data.c but not publicly. */
|
||||
int
|
||||
__res_vinit(res_state statp, int preinit) {
|
||||
@@ -178,6 +220,12 @@ __res_vinit(res_state statp, int preinit) {
|
||||
char *net;
|
||||
int dots;
|
||||
union res_sockaddr_union u[2];
|
||||
#ifdef ANDROID_CHANGES
|
||||
pid_t mypid = getpid();
|
||||
int use_proc_props = 0;
|
||||
int found_prop;
|
||||
char dnsProperty[PROP_VALUE_MAX];
|
||||
#endif
|
||||
|
||||
if ((statp->options & RES_INIT) != 0U)
|
||||
res_ndestroy(statp);
|
||||
@@ -270,8 +318,74 @@ __res_vinit(res_state statp, int preinit) {
|
||||
if (nserv > 0)
|
||||
statp->nscount = nserv;
|
||||
#endif
|
||||
#ifdef ANDROID_CHANGES /* READ FROM SYSTEM PROPERTIES */
|
||||
dns_last_change_counter = _get_dns_change_count();
|
||||
|
||||
#ifndef ANDROID_CHANGES /* !ANDROID_CHANGES - IGNORE resolv.conf in Android */
|
||||
nserv = 0;
|
||||
for(n = 1; n <= MAX_DNS_PROPERTIES && nserv < MAXNS; n++) {
|
||||
char propname[PROP_NAME_MAX];
|
||||
char propvalue[PROP_VALUE_MAX];
|
||||
|
||||
struct addrinfo hints, *ai;
|
||||
char sbuf[NI_MAXSERV];
|
||||
const size_t minsiz = sizeof(statp->_u._ext.ext->nsaddrs[0]);
|
||||
|
||||
/*
|
||||
* Check first for process-specific properties, and if those don't
|
||||
* exist, try the generic properties.
|
||||
*/
|
||||
found_prop = 0;
|
||||
if (n == 1 || use_proc_props) {
|
||||
snprintf(propname, sizeof(propname), "%s%d.%d", DNS_PROP_NAME_PREFIX, n, mypid);
|
||||
if(__system_property_get(propname, propvalue) < 1) {
|
||||
if (use_proc_props) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
found_prop = 1;
|
||||
use_proc_props = 1;
|
||||
}
|
||||
}
|
||||
if (!found_prop) {
|
||||
snprintf(propname, sizeof(propname), "%s%d", DNS_PROP_NAME_PREFIX, n);
|
||||
if(__system_property_get(propname, propvalue) < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cp = propvalue;
|
||||
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
cp[strcspn(cp, ";# \t\n")] = '\0';
|
||||
if ((*cp != '\0') && (*cp != '\n')) {
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
sprintf(sbuf, "%u", NAMESERVER_PORT);
|
||||
if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
|
||||
(size_t)ai->ai_addrlen <= minsiz) {
|
||||
if (statp->_u._ext.ext != NULL) {
|
||||
memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
|
||||
ai->ai_addr, ai->ai_addrlen);
|
||||
}
|
||||
if ((size_t)ai->ai_addrlen <=
|
||||
sizeof(statp->nsaddr_list[nserv])) {
|
||||
memcpy(&statp->nsaddr_list[nserv],
|
||||
ai->ai_addr, ai->ai_addrlen);
|
||||
} else {
|
||||
statp->nsaddr_list[nserv].sin_family = 0;
|
||||
}
|
||||
freeaddrinfo(ai);
|
||||
nserv++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the domain search list */
|
||||
havesearch = load_domain_search_list(statp);
|
||||
#else /* !ANDROID_CHANGES - IGNORE resolv.conf in Android */
|
||||
#define MATCH(line, name) \
|
||||
(!strncmp(line, name, sizeof(name) - 1) && \
|
||||
(line[sizeof(name) - 1] == ' ' || \
|
||||
@@ -793,17 +907,32 @@ res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) {
|
||||
}
|
||||
|
||||
#ifdef ANDROID_CHANGES
|
||||
void res_setiface(res_state statp, const char* iface)
|
||||
static int _get_dns_change_count()
|
||||
{
|
||||
if (statp != NULL) {
|
||||
// set interface
|
||||
if (iface && iface[0] != '\0') {
|
||||
int len = sizeof(statp->iface);
|
||||
strncpy(statp->iface, iface, len - 1);
|
||||
statp->iface[len - 1] = '\0';
|
||||
} else {
|
||||
statp->iface[0] = '\0';
|
||||
if (dns_change_prop == NULL) {
|
||||
dns_change_prop = __system_property_find(DNS_CHANGE_PROP_NAME);
|
||||
}
|
||||
if (dns_change_prop != NULL) {
|
||||
char propvalue[PROP_VALUE_MAX];
|
||||
if (__system_property_read(dns_change_prop, NULL, propvalue) >= 1) {
|
||||
return atoi(propvalue);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int res_get_dns_changed()
|
||||
{
|
||||
int change_count;
|
||||
|
||||
change_count = _get_dns_change_count();
|
||||
if (change_count != dns_last_change_counter) {
|
||||
if (change_count != -1) {
|
||||
dns_last_change_counter = change_count;
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif /* ANDROID_CHANGES */
|
||||
|
@@ -370,13 +370,10 @@ res_nsend(res_state statp,
|
||||
ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
|
||||
#endif
|
||||
|
||||
#if !USE_RESOLV_CACHE
|
||||
if (statp->nscount == 0) {
|
||||
errno = ESRCH;
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (anssiz < HFIXEDSZ) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
@@ -388,8 +385,7 @@ res_nsend(res_state statp,
|
||||
terrno = ETIMEDOUT;
|
||||
|
||||
#if USE_RESOLV_CACHE
|
||||
// get the cache associated with the interface
|
||||
cache = __get_res_cache(statp->iface);
|
||||
cache = __get_res_cache();
|
||||
if (cache != NULL) {
|
||||
int anslen = 0;
|
||||
cache_status = _resolv_cache_lookup(
|
||||
@@ -398,17 +394,8 @@ res_nsend(res_state statp,
|
||||
|
||||
if (cache_status == RESOLV_CACHE_FOUND) {
|
||||
return anslen;
|
||||
} else {
|
||||
// had a cache miss for a known interface, so populate the thread private
|
||||
// data so the normal resolve path can do its thing
|
||||
_resolv_populate_res_for_iface(statp);
|
||||
}
|
||||
}
|
||||
|
||||
if (statp->nscount == 0) {
|
||||
errno = ESRCH;
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@@ -50,7 +50,7 @@
|
||||
#endif
|
||||
|
||||
static pthread_key_t _res_key;
|
||||
static pthread_once_t _res_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_once_t _res_once;
|
||||
|
||||
typedef struct {
|
||||
int _h_errno;
|
||||
|
Reference in New Issue
Block a user