summaryrefslogtreecommitdiffstats
path: root/libc/netbsd
diff options
context:
space:
mode:
Diffstat (limited to 'libc/netbsd')
-rw-r--r--libc/netbsd/net/getaddrinfo.c39
-rw-r--r--libc/netbsd/net/getnameinfo.c36
-rw-r--r--libc/netbsd/resolv/res_cache.c25
3 files changed, 78 insertions, 22 deletions
diff --git a/libc/netbsd/net/getaddrinfo.c b/libc/netbsd/net/getaddrinfo.c
index ace8c1a..326b09c 100644
--- a/libc/netbsd/net/getaddrinfo.c
+++ b/libc/netbsd/net/getaddrinfo.c
@@ -130,6 +130,9 @@ static const char in6_loopback[] = {
};
#endif
+// This should be synchronized to ResponseCode.h
+static const int DnsProxyQueryResult = 222;
+
static const struct afd {
int a_af;
int a_addrlen;
@@ -476,12 +479,15 @@ android_getaddrinfo_proxy(
goto exit;
}
- int remote_rv;
- if (fread(&remote_rv, sizeof(int), 1, proxy) != 1) {
+ char buf[4];
+ // read result code for gethostbyaddr
+ if (fread(buf, 1, sizeof(buf), proxy) != sizeof(buf)) {
goto exit;
}
- if (remote_rv != 0) {
+ int result_code = (int)strtol(buf, NULL, 10);
+ // verify the code itself
+ if (result_code != DnsProxyQueryResult ) {
goto exit;
}
@@ -1867,6 +1873,19 @@ error:
free(elems);
}
+static int _using_alt_dns()
+{
+ char propname[PROP_NAME_MAX];
+ char propvalue[PROP_VALUE_MAX];
+
+ propvalue[0] = 0;
+ snprintf(propname, sizeof(propname), "net.dns1.%d", getpid());
+ if (__system_property_get(propname, propvalue) > 0 ) {
+ return 1;
+ }
+ return 0;
+}
+
/*ARGSUSED*/
static int
_dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
@@ -1909,14 +1928,12 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
q.anslen = sizeof(buf->buf);
int query_ipv6 = 1, query_ipv4 = 1;
if (pai->ai_flags & AI_ADDRCONFIG) {
- query_ipv6 = _have_ipv6();
- query_ipv4 = _have_ipv4();
- if (query_ipv6 == 0 && query_ipv4 == 0) {
- // Both our IPv4 and IPv6 connectivity probes failed, which indicates
- // that we have neither an IPv4 or an IPv6 default route (and thus no
- // global IPv4 or IPv6 connectivity). We might be in a walled garden.
- // Throw up our arms and ask for both A and AAAA.
- query_ipv6 = query_ipv4 = 1;
+ // Only implement AI_ADDRCONFIG if the application is not
+ // using its own DNS servers, since our implementation
+ // only works on the default connection.
+ if (!_using_alt_dns()) {
+ query_ipv6 = _have_ipv6();
+ query_ipv4 = _have_ipv4();
}
}
if (query_ipv6) {
diff --git a/libc/netbsd/net/getnameinfo.c b/libc/netbsd/net/getnameinfo.c
index d3d0011..8a1e95e 100644
--- a/libc/netbsd/net/getnameinfo.c
+++ b/libc/netbsd/net/getnameinfo.c
@@ -108,6 +108,10 @@ static int getnameinfo_link __P((const struct sockaddr *, socklen_t, char *,
socklen_t, char *, socklen_t, int));
static int hexname __P((const u_int8_t *, size_t, char *, socklen_t));
+// This should be synchronized to ResponseCode.h
+static const int DnsProxyQueryResult = 222;
+
+
/*
* Top-level getnameinfo() code. Look at the address family, and pick an
* appropriate function to call.
@@ -135,7 +139,7 @@ int getnameinfo(const struct sockaddr* sa, socklen_t salen, char* host, size_t h
* the address. On failure -1 is returned in which case
* normal execution flow shall continue. */
static int
-android_gethostbyaddr_proxy(struct hostent* hp, const void *addr, socklen_t addrLen, int addrFamily) {
+android_gethostbyaddr_proxy(char* nameBuf, size_t nameBufLen, const void *addr, socklen_t addrLen, int addrFamily) {
int sock;
const int one = 1;
@@ -183,7 +187,7 @@ android_gethostbyaddr_proxy(struct hostent* hp, const void *addr, socklen_t addr
}
char buf[INET6_ADDRSTRLEN]; // big enough for IPv4 and IPv6
- const char* addrStr = inet_ntop(addrFamily, addr, &buf, sizeof(buf));
+ const char* addrStr = inet_ntop(addrFamily, addr, buf, sizeof(buf));
if (addrStr == NULL) {
goto exit;
}
@@ -197,17 +201,29 @@ android_gethostbyaddr_proxy(struct hostent* hp, const void *addr, socklen_t addr
}
result = 0;
+ char msg_buf[4];
+ // read result code for gethostbyaddr
+ if (fread(msg_buf, 1, sizeof(msg_buf), proxy) != sizeof(msg_buf)) {
+ goto exit;
+ }
+
+ int result_code = (int)strtol(msg_buf, NULL, 10);
+ // verify the code itself
+ if (result_code != DnsProxyQueryResult) {
+ goto exit;
+ }
+
uint32_t name_len;
if (fread(&name_len, sizeof(name_len), 1, proxy) != 1) {
goto exit;
}
name_len = ntohl(name_len);
- if (name_len <= 0) {
+ if (name_len <= 0 || name_len >= nameBufLen) {
goto exit;
}
- if (fread(hp->h_name, name_len, 1, proxy) != 1) {
+ if (fread(nameBuf, name_len, 1, proxy) != 1) {
goto exit;
}
@@ -376,12 +392,14 @@ getnameinfo_inet(sa, salen, host, hostlen, serv, servlen, flags)
#ifdef ANDROID_CHANGES
struct hostent android_proxy_hostent;
char android_proxy_buf[MAXDNAME];
- android_proxy_hostent.h_name = android_proxy_buf;
- int hostnamelen = android_gethostbyaddr_proxy(&android_proxy_hostent,
- addr, afd->a_addrlen, afd->a_af);
- if (hostnamelen >= 0) {
- hp = (hostnamelen > 0) ? &android_proxy_hostent : NULL;
+ int hostnamelen = android_gethostbyaddr_proxy(android_proxy_buf,
+ MAXDNAME, addr, afd->a_addrlen, afd->a_af);
+ if (hostnamelen > 0) {
+ hp = &android_proxy_hostent;
+ hp->h_name = android_proxy_buf;
+ } else if (!hostnamelen) {
+ hp = NULL;
} else {
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
}
diff --git a/libc/netbsd/resolv/res_cache.c b/libc/netbsd/resolv/res_cache.c
index 284ca2f..0bb2f23 100644
--- a/libc/netbsd/resolv/res_cache.c
+++ b/libc/netbsd/resolv/res_cache.c
@@ -42,6 +42,7 @@
#include <arpa/inet.h>
#include "resolv_private.h"
+#include "resolv_iface.h"
/* This code implements a small and *simple* DNS resolver cache.
*
@@ -137,9 +138,19 @@
*
* The system property ro.net.dns_cache_size can be used to override the default
* value with a custom value
+ *
+ *
+ * ******************************************
+ * * NOTE - this has changed.
+ * * 1) we've added IPv6 support so each dns query results in 2 responses
+ * * 2) we've made this a system-wide cache, so the cost is less (it's not
+ * * duplicated in each process) and the need is greater (more processes
+ * * making different requests).
+ * * Upping by 2x for IPv6
+ * * Upping by another 5x for the centralized nature
+ * *****************************************
*/
-#define CONFIG_MAX_ENTRIES 64
-
+#define CONFIG_MAX_ENTRIES 64 * 2 * 5
/* name of the system property that can be used to set the cache size */
#define DNS_CACHE_SIZE_PROP_NAME "ro.net.dns_cache_size"
@@ -1217,6 +1228,16 @@ _res_cache_get_max_entries( void )
int result = -1;
char cache_size[PROP_VALUE_MAX];
+ const char* cache_mode = getenv("ANDROID_DNS_MODE");
+
+ if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
+ // Don't use the cache in local mode. This is used by the
+ // proxy itself.
+ // 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) {
result = atoi(cache_size);
}