Merge "Clean up DNS proxying."
This commit is contained in:
commit
e7b8bc4e29
@ -69,6 +69,7 @@
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include <syslog.h>
|
||||
@ -532,30 +533,32 @@ android_gethostbynamefornet(const char *name, int af, unsigned netid, unsigned m
|
||||
return hp;
|
||||
}
|
||||
|
||||
|
||||
static FILE* android_open_proxy()
|
||||
{
|
||||
int sock;
|
||||
const int one = 1;
|
||||
struct sockaddr_un proxy_addr;
|
||||
|
||||
sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (sock < 0) {
|
||||
__LIBC_HIDDEN__ FILE* android_open_proxy() {
|
||||
const char* cache_mode = getenv("ANDROID_DNS_MODE");
|
||||
bool use_proxy = (cache_mode == NULL || strcmp(cache_mode, "local") != 0);
|
||||
if (!use_proxy) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
int s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (s == -1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int one = 1;
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
|
||||
struct sockaddr_un proxy_addr;
|
||||
memset(&proxy_addr, 0, sizeof(proxy_addr));
|
||||
proxy_addr.sun_family = AF_UNIX;
|
||||
strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd", sizeof(proxy_addr.sun_path));
|
||||
if (TEMP_FAILURE_RETRY(connect(sock,
|
||||
(const struct sockaddr*) &proxy_addr,
|
||||
sizeof(proxy_addr))) != 0) {
|
||||
close(sock);
|
||||
|
||||
if (TEMP_FAILURE_RETRY(connect(s, (const struct sockaddr*) &proxy_addr, sizeof(proxy_addr))) != 0) {
|
||||
close(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return fdopen(sock, "r+");
|
||||
return fdopen(s, "r+");
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
@ -565,8 +568,8 @@ android_read_hostent(FILE* proxy)
|
||||
char buf[4];
|
||||
if (fread(buf, 1, sizeof(buf), proxy) != sizeof(buf)) return NULL;
|
||||
|
||||
/* This is reading serialized data from system/netd/server/DnsProxyListener.cpp
|
||||
* and changes here need to be matched there */
|
||||
// This is reading serialized data from system/netd/server/DnsProxyListener.cpp
|
||||
// and changes here need to be matched there.
|
||||
int result_code = strtol(buf, NULL, 10);
|
||||
if (result_code != DnsProxyQueryResult) {
|
||||
fread(&size, 1, sizeof(size), proxy);
|
||||
@ -748,80 +751,39 @@ gethostbyname_internal_real(const char *name, int af, res_state res)
|
||||
static struct hostent *
|
||||
gethostbyname_internal(const char *name, int af, res_state res, unsigned netid, unsigned mark)
|
||||
{
|
||||
const char *cache_mode = getenv("ANDROID_DNS_MODE");
|
||||
FILE* proxy = NULL;
|
||||
struct hostent *result = NULL;
|
||||
|
||||
if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) {
|
||||
FILE* proxy = android_open_proxy();
|
||||
if (proxy == NULL) {
|
||||
// Either we're not supposed to be using the proxy or the proxy is unavailable.
|
||||
res_setnetid(res, netid);
|
||||
res_setmark(res, mark);
|
||||
return gethostbyname_internal_real(name, af, res);
|
||||
}
|
||||
|
||||
proxy = android_open_proxy();
|
||||
if (proxy == NULL) goto exit;
|
||||
|
||||
netid = __netdClientDispatch.netIdForResolv(netid);
|
||||
|
||||
/* This is writing to system/netd/server/DnsProxyListener.cpp and changes
|
||||
* here need to be matched there */
|
||||
// This is writing to system/netd/server/DnsProxyListener.cpp and changes
|
||||
// here need to be matched there.
|
||||
if (fprintf(proxy, "gethostbyname %u %s %d",
|
||||
netid,
|
||||
name == NULL ? "^" : name,
|
||||
af) < 0) {
|
||||
goto exit;
|
||||
fclose(proxy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fputc(0, proxy) == EOF || fflush(proxy) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = android_read_hostent(proxy);
|
||||
|
||||
exit:
|
||||
if (proxy != NULL) {
|
||||
fclose(proxy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hostent* result = android_read_hostent(proxy);
|
||||
fclose(proxy);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
struct hostent *
|
||||
android_gethostbyaddrfornet_proxy(const void *addr,
|
||||
socklen_t len, int af, unsigned netid)
|
||||
{
|
||||
struct hostent *result = NULL;
|
||||
FILE* proxy = android_open_proxy();
|
||||
|
||||
if (proxy == NULL) goto exit;
|
||||
|
||||
char buf[INET6_ADDRSTRLEN]; //big enough for IPv4 and IPv6
|
||||
const char * addrStr = inet_ntop(af, addr, buf, sizeof(buf));
|
||||
if (addrStr == NULL) goto exit;
|
||||
|
||||
netid = __netdClientDispatch.netIdForResolv(netid);
|
||||
|
||||
if (fprintf(proxy, "gethostbyaddr %s %d %d %u",
|
||||
addrStr, len, af, netid) < 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fputc(0, proxy) == EOF || fflush(proxy) != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
result = android_read_hostent(proxy);
|
||||
exit:
|
||||
if (proxy != NULL) {
|
||||
fclose(proxy);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
android_gethostbyaddrfornet_real(const void *addr,
|
||||
socklen_t len, int af, unsigned netid, unsigned mark)
|
||||
{
|
||||
static struct hostent *
|
||||
android_gethostbyaddrfornet_real(const void *addr, socklen_t len, int af, unsigned netid, unsigned mark) {
|
||||
const u_char *uaddr = (const u_char *)addr;
|
||||
socklen_t size;
|
||||
struct hostent *hp;
|
||||
@ -874,16 +836,43 @@ android_gethostbyaddrfornet_real(const void *addr,
|
||||
return hp;
|
||||
}
|
||||
|
||||
__LIBC_HIDDEN__ struct hostent*
|
||||
android_gethostbyaddrfornet_proxy(const void* addr, socklen_t len, int af, unsigned netid, unsigned mark) {
|
||||
FILE* proxy = android_open_proxy();
|
||||
if (proxy == NULL) {
|
||||
// Either we're not supposed to be using the proxy or the proxy is unavailable.
|
||||
return android_gethostbyaddrfornet_real(addr,len, af, netid, mark);
|
||||
}
|
||||
|
||||
char buf[INET6_ADDRSTRLEN]; //big enough for IPv4 and IPv6
|
||||
const char * addrStr = inet_ntop(af, addr, buf, sizeof(buf));
|
||||
if (addrStr == NULL) {
|
||||
fclose(proxy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
netid = __netdClientDispatch.netIdForResolv(netid);
|
||||
|
||||
if (fprintf(proxy, "gethostbyaddr %s %d %d %u",
|
||||
addrStr, len, af, netid) < 0) {
|
||||
fclose(proxy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fputc(0, proxy) == EOF || fflush(proxy) != 0) {
|
||||
fclose(proxy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct hostent *result = android_read_hostent(proxy);
|
||||
fclose(proxy);
|
||||
return result;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
android_gethostbyaddrfornet(const void *addr, socklen_t len, int af, unsigned netid, unsigned mark)
|
||||
{
|
||||
const char *cache_mode = getenv("ANDROID_DNS_MODE");
|
||||
|
||||
if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
|
||||
return android_gethostbyaddrfornet_proxy(addr, len, af, netid);
|
||||
} else {
|
||||
return android_gethostbyaddrfornet_real(addr,len, af, netid, mark);
|
||||
}
|
||||
return android_gethostbyaddrfornet_proxy(addr, len, af, netid, mark);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
|
@ -34,6 +34,7 @@
|
||||
*/
|
||||
#include <sys/cdefs.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Passing NETID_UNSET as the netId causes system/netd/server/DnsProxyListener.cpp to
|
||||
@ -68,9 +69,9 @@ extern void _resolv_flush_cache_for_net(unsigned netid) __used_in_netd;
|
||||
extern void _resolv_delete_cache_for_net(unsigned netid) __used_in_netd;
|
||||
|
||||
/* Internal use only. */
|
||||
struct hostent *android_gethostbyaddrfornet_proxy(const void *, socklen_t, int , unsigned);
|
||||
int android_getnameinfofornet(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t,
|
||||
int, unsigned, unsigned);
|
||||
struct hostent *android_gethostbyaddrfornet_proxy(const void *, socklen_t, int , unsigned, unsigned) __LIBC_HIDDEN__;
|
||||
int android_getnameinfofornet(const struct sockaddr *, socklen_t, char *, size_t, char *, size_t, int, unsigned, unsigned) __LIBC_HIDDEN__;
|
||||
FILE* android_open_proxy(void) __LIBC_HIDDEN__;
|
||||
|
||||
/* delete the cache associated with a certain network */
|
||||
extern void _resolv_delete_cache_for_net(unsigned netid);
|
||||
|
@ -423,10 +423,6 @@ android_getaddrinfo_proxy(
|
||||
const char *hostname, const char *servname,
|
||||
const struct addrinfo *hints, struct addrinfo **res, unsigned netid)
|
||||
{
|
||||
int sock;
|
||||
const int one = 1;
|
||||
struct sockaddr_un proxy_addr;
|
||||
FILE* proxy = NULL;
|
||||
int success = 0;
|
||||
|
||||
// Clear this at start, as we use its non-NULLness later (in the
|
||||
@ -442,36 +438,14 @@ android_getaddrinfo_proxy(
|
||||
return EAI_NODATA;
|
||||
}
|
||||
|
||||
sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (sock < 0) {
|
||||
return EAI_NODATA;
|
||||
}
|
||||
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
|
||||
memset(&proxy_addr, 0, sizeof(proxy_addr));
|
||||
proxy_addr.sun_family = AF_UNIX;
|
||||
strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd",
|
||||
sizeof(proxy_addr.sun_path));
|
||||
if (TEMP_FAILURE_RETRY(connect(sock,
|
||||
(const struct sockaddr*) &proxy_addr,
|
||||
sizeof(proxy_addr))) != 0) {
|
||||
close(sock);
|
||||
return EAI_NODATA;
|
||||
FILE* proxy = android_open_proxy();
|
||||
if (proxy == NULL) {
|
||||
return EAI_SYSTEM;
|
||||
}
|
||||
|
||||
netid = __netdClientDispatch.netIdForResolv(netid);
|
||||
|
||||
// Send the request.
|
||||
proxy = fdopen(sock, "r+");
|
||||
if (proxy == NULL) {
|
||||
// Failed to map sock to FILE*. Check errno for the cause.
|
||||
// @sonymobile.com saw failures in automated testing, but
|
||||
// couldn't reproduce it for debugging.
|
||||
// Fail with EAI_SYSTEM and let callers handle the failure.
|
||||
close(sock);
|
||||
return EAI_SYSTEM;
|
||||
}
|
||||
|
||||
if (fprintf(proxy, "getaddrinfo %s %s %d %d %d %d %u",
|
||||
hostname == NULL ? "^" : hostname,
|
||||
servname == NULL ? "^" : servname,
|
||||
@ -618,7 +592,6 @@ android_getaddrinfofornet(const char *hostname, const char *servname,
|
||||
struct addrinfo ai0;
|
||||
struct addrinfo *pai;
|
||||
const struct explore *ex;
|
||||
const char* cache_mode = getenv("ANDROID_DNS_MODE");
|
||||
|
||||
/* hostname is allowed to be NULL */
|
||||
/* servname is allowed to be NULL */
|
||||
@ -753,13 +726,12 @@ android_getaddrinfofornet(const char *hostname, const char *servname,
|
||||
if (pai->ai_flags & AI_NUMERICHOST)
|
||||
ERR(EAI_NONAME);
|
||||
|
||||
/*
|
||||
* BEGIN ANDROID CHANGES; proxying to the cache
|
||||
*/
|
||||
if (cache_mode == NULL || strcmp(cache_mode, "local") != 0) {
|
||||
// we're not the proxy - pass the request to them
|
||||
return android_getaddrinfo_proxy(hostname, servname, hints, res, netid);
|
||||
#if defined(__ANDROID__)
|
||||
int gai_error = android_getaddrinfo_proxy(hostname, servname, hints, res, netid);
|
||||
if (gai_error != EAI_SYSTEM) {
|
||||
return gai_error;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* hostname as alphabetical name.
|
||||
|
@ -303,7 +303,7 @@ getnameinfo_inet(const struct sockaddr* sa, socklen_t salen,
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
hp = android_gethostbyaddrfornet_proxy(addr, afd->a_addrlen, afd->a_af, netid);
|
||||
hp = android_gethostbyaddrfornet_proxy(addr, afd->a_addrlen, afd->a_af, netid, mark);
|
||||
if (hp) {
|
||||
#if 0
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user