Merge "Remove separate IPv4-only nsaddr_list from res_state"
am: 0a423e4b35
Change-Id: I7c8f04e20310350f05dde74974207a2481f8ab90
diff --git a/res_cache.cpp b/res_cache.cpp
index 55d9514..b9737fe 100644
--- a/res_cache.cpp
+++ b/res_cache.cpp
@@ -1583,16 +1583,7 @@
}
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;
- }
- }
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv], ai->ai_addr, ai->ai_addrlen);
} else {
LOG(INFO) << __func__ << ": found too long addrlen";
}
diff --git a/res_init.cpp b/res_init.cpp
index ecfb35d..502f9ea 100644
--- a/res_init.cpp
+++ b/res_init.cpp
@@ -94,22 +94,12 @@
#include "resolv_private.h"
// Set up Resolver state default settings.
-// Note that res_ninit() is called with an initialized res_state,
-// the memories it allocated must be freed after the task is done.
-// Or memory leak will happen.
-int res_ninit(res_state statp) {
- int nserv = 0; // number of nameserver records
- sockaddr_union u[2];
-
+// Note: this is called with statp zero-initialized
+void res_init(res_state statp) {
statp->netid = NETID_UNSET;
statp->id = arc4random_uniform(65536);
statp->_mark = MARK_UNSET;
- memset(u, 0, sizeof(u));
- u[nserv].sin.sin_addr.s_addr = INADDR_ANY;
- u[nserv].sin.sin_family = AF_INET;
- u[nserv].sin.sin_port = htons(NAMESERVER_PORT);
- nserv++;
statp->nscount = 0;
statp->ndots = 1;
statp->_vcsock = -1;
@@ -119,17 +109,20 @@
statp->netcontext_flags = 0;
if (statp->_u._ext.ext != NULL) {
memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
- statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
}
- res_setservers(statp, u, nserv);
- if (nserv > 0) {
- statp->nscount = nserv;
- }
- return (0);
+ // The following dummy initialization is probably useless because
+ // it's overwritten later by _resolv_populate_res_for_net().
+ // TODO: check if it's safe to remove.
+ const sockaddr_union u{
+ .sin.sin_addr.s_addr = INADDR_ANY,
+ .sin.sin_family = AF_INET,
+ .sin.sin_port = htons(NAMESERVER_PORT),
+ };
+ memcpy(&statp->_u._ext.ext->nsaddrs[0], &u, sizeof(u));
+ statp->nscount = 1;
}
-
/*
* This routine is for closing the socket if a virtual circuit is used and
* the program wants to close it. This provides support for endhostent()
@@ -159,90 +152,6 @@
statp->_u._ext.ext = NULL;
}
-void res_setservers(res_state statp, const sockaddr_union* set, int cnt) {
- int i, nserv;
- size_t size;
-
- /* close open servers */
- res_nclose(statp);
-
- /* cause rtt times to be forgotten */
- statp->_u._ext.nscount = 0;
-
- nserv = 0;
- for (i = 0; i < cnt && nserv < MAXNS; i++) {
- switch (set->sin.sin_family) {
- case AF_INET:
- size = sizeof(set->sin);
- if (statp->_u._ext.ext)
- memcpy(&statp->_u._ext.ext->nsaddrs[nserv], &set->sin, size);
- if (size <= sizeof(statp->nsaddr_list[nserv]))
- memcpy(&statp->nsaddr_list[nserv], &set->sin, size);
- else
- statp->nsaddr_list[nserv].sin_family = 0;
- nserv++;
- break;
-
-#ifdef HAS_INET6_STRUCTS
- case AF_INET6:
- size = sizeof(set->sin6);
- if (statp->_u._ext.ext)
- memcpy(&statp->_u._ext.ext->nsaddrs[nserv], &set->sin6, size);
- if (size <= sizeof(statp->nsaddr_list[nserv]))
- memcpy(&statp->nsaddr_list[nserv], &set->sin6, size);
- else
- statp->nsaddr_list[nserv].sin_family = 0;
- nserv++;
- break;
-#endif
-
- default:
- break;
- }
- set++;
- }
- statp->nscount = nserv;
-}
-
-int res_getservers(res_state statp, sockaddr_union* set, int cnt) {
- int i;
- size_t size;
- uint16_t family;
-
- for (i = 0; i < statp->nscount && i < cnt; i++) {
- if (statp->_u._ext.ext)
- family = statp->_u._ext.ext->nsaddrs[i].sin.sin_family;
- else
- family = statp->nsaddr_list[i].sin_family;
-
- switch (family) {
- case AF_INET:
- size = sizeof(set->sin);
- if (statp->_u._ext.ext)
- memcpy(&set->sin, &statp->_u._ext.ext->nsaddrs[i], size);
- else
- memcpy(&set->sin, &statp->nsaddr_list[i], size);
- break;
-
-#ifdef HAS_INET6_STRUCTS
- case AF_INET6:
- size = sizeof(set->sin6);
- if (statp->_u._ext.ext)
- memcpy(&set->sin6, &statp->_u._ext.ext->nsaddrs[i], size);
- else
- memcpy(&set->sin6, &statp->nsaddr_list[i], size);
- break;
-#endif
-
- default:
- set->sin.sin_family = 0;
- break;
- }
- set++;
- }
- return (statp->nscount);
-}
-
void res_setnetcontext(res_state statp, const struct android_net_context* netcontext,
android::net::NetworkDnsEventReported* _Nonnull event) {
if (statp != nullptr) {
diff --git a/res_init.h b/res_init.h
new file mode 100644
index 0000000..af76414
--- /dev/null
+++ b/res_init.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+struct __res_state;
+void res_init(__res_state* statp);
diff --git a/res_send.cpp b/res_send.cpp
index be5ec0b..af60376 100644
--- a/res_send.cpp
+++ b/res_send.cpp
@@ -470,13 +470,6 @@
needclose++;
} else {
for (int ns = 0; ns < statp->nscount; ns++) {
- if (statp->nsaddr_list[ns].sin_family &&
- !sock_eq((struct sockaddr*) (void*) &statp->nsaddr_list[ns],
- (struct sockaddr*) (void*) &statp->_u._ext.ext->nsaddrs[ns])) {
- needclose++;
- break;
- }
-
if (statp->_u._ext.nssocks[ns] == -1) continue;
peerlen = sizeof(peer);
if (getpeername(statp->_u._ext.nssocks[ns], (struct sockaddr*) (void*) &peer,
@@ -503,8 +496,6 @@
for (int ns = 0; ns < statp->nscount; ns++) {
statp->_u._ext.nstimes[ns] = RES_MAXTIME;
statp->_u._ext.nssocks[ns] = -1;
- if (!statp->nsaddr_list[ns].sin_family) continue;
- statp->_u._ext.ext->nsaddrs[ns].sin = statp->nsaddr_list[ns];
}
statp->_u._ext.nscount = statp->nscount;
}
@@ -692,25 +683,8 @@
return (0); /* unknown, die on connect */
}
-/*
- * pick appropriate nsaddr_list for use. see res_init() for initialization.
- */
static struct sockaddr* get_nsaddr(res_state statp, size_t n) {
- if (!statp->nsaddr_list[n].sin_family && statp->_u._ext.ext) {
- /*
- * - statp->_u._ext.ext->nsaddrs[n] holds an address that is larger
- * than struct sockaddr, and
- * - user code did not update statp->nsaddr_list[n].
- */
- return (struct sockaddr*) (void*) &statp->_u._ext.ext->nsaddrs[n];
- } else {
- /*
- * - user code updated statp->nsaddr_list[n], or
- * - statp->nsaddr_list[n] has the same content as
- * statp->_u._ext.ext->nsaddrs[n].
- */
- return (struct sockaddr*) (void*) &statp->nsaddr_list[n];
- }
+ return (struct sockaddr*)(void*)&statp->_u._ext.ext->nsaddrs[n];
}
static struct timespec get_timeout(res_state statp, const res_params* params, const int ns) {
diff --git a/res_state.cpp b/res_state.cpp
index 0a90733..372c37a 100644
--- a/res_state.cpp
+++ b/res_state.cpp
@@ -38,6 +38,7 @@
#include <android-base/logging.h>
+#include "res_init.h"
#include "resolv_cache.h"
#include "resolv_private.h"
@@ -99,14 +100,7 @@
pthread_setspecific(_res_key, rt);
LOG(VERBOSE) << __func__ << ": tid=" << gettid() << ", rt=" << rt;
- if (res_ninit(rt->_nres) < 0) {
- /* This should not happen */
- LOG(VERBOSE) << __func__ << ": tid=" << gettid() << " rt=" << rt
- << ", res_ninit() returned < 0";
- res_thread_free(rt);
- pthread_setspecific(_res_key, NULL);
- return NULL;
- }
+ res_init(rt->_nres);
return rt;
}
diff --git a/resolv_private.h b/resolv_private.h
index 8ab6939..0029254 100644
--- a/resolv_private.h
+++ b/resolv_private.h
@@ -89,8 +89,6 @@
unsigned netid; // NetId: cache key and socket mark
uid_t uid; // uid of the app that sent the DNS lookup
int nscount; // number of name srvers
- struct sockaddr_in nsaddr_list[MAXNS]; // address of name server
-#define nsaddr nsaddr_list[0] // for backward compatibility
uint16_t id; // current message id
std::vector<std::string> search_domains; // domains to search
unsigned ndots : 4; // threshold for initial abs. query
@@ -167,8 +165,6 @@
int res_nameinquery(const char*, int, int, const uint8_t*, const uint8_t*);
int res_queriesmatch(const uint8_t*, const uint8_t*, const uint8_t*, const uint8_t*);
-/* Things involving a resolver context. */
-int res_ninit(res_state);
int res_nquery(res_state, const char*, int, int, uint8_t*, int, int*);
int res_nsearch(res_state, const char*, int, int, uint8_t*, int, int*);