Merge "Fix benign case of uninitialized variable"
diff --git a/DnsProxyListener.cpp b/DnsProxyListener.cpp
index 5c5529e..bb8251c 100644
--- a/DnsProxyListener.cpp
+++ b/DnsProxyListener.cpp
@@ -74,10 +74,6 @@
// Limits the number of outstanding DNS queries by client UID.
constexpr int MAX_QUERIES_PER_UID = 256;
-// Max packet size for answer, sync with getaddrinfo.c
-// TODO: switch to dynamically allocated buffers with std::vector
-constexpr int MAXPACKET = 8 * 1024;
-
android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
void logArguments(int argc, char** argv) {
diff --git a/getaddrinfo.cpp b/getaddrinfo.cpp
index a9550b0..e77b8b3 100644
--- a/getaddrinfo.cpp
+++ b/getaddrinfo.cpp
@@ -108,20 +108,13 @@
};
#define PTON_MAX 16
-#define MAXPACKET (8 * 1024)
-
-typedef union {
- HEADER hdr;
- uint8_t buf[MAXPACKET];
-} querybuf;
struct res_target {
struct res_target* next;
- const char* name; /* domain name */
- int qclass, qtype; /* class and type of query */
- uint8_t* answer; /* buffer to put answer */
- int anslen; /* size of answer buffer */
- int n; /* result length */
+ const char* name; // domain name
+ int qclass, qtype; // class and type of query
+ std::vector<uint8_t> answer = std::vector<uint8_t>(MAXPACKET, 0); // buffer to put answer
+ int n = 0; // result length
};
static int str2number(const char*);
@@ -139,8 +132,8 @@
static const struct afd* find_afd(int);
static int ip6_str2scopeid(const char*, struct sockaddr_in6*, uint32_t*);
-static struct addrinfo* getanswer(const querybuf*, int, const char*, int, const struct addrinfo*,
- int* herrno);
+static struct addrinfo* getanswer(const std::vector<uint8_t>&, int, const char*, int,
+ const struct addrinfo*, int* herrno);
static int dns_getaddrinfo(const char* name, const addrinfo* pai,
const android_net_context* netcontext, addrinfo** rv,
NetworkDnsEventReported* event);
@@ -838,8 +831,8 @@
} \
} while (0)
-static struct addrinfo* getanswer(const querybuf* answer, int anslen, const char* qname, int qtype,
- const struct addrinfo* pai, int* herrno) {
+static struct addrinfo* getanswer(const std::vector<uint8_t>& answer, int anslen, const char* qname,
+ int qtype, const struct addrinfo* pai, int* herrno) {
struct addrinfo sentinel = {};
struct addrinfo *cur;
struct addrinfo ai;
@@ -856,14 +849,13 @@
int (*name_ok)(const char*);
char hostbuf[8 * 1024];
- assert(answer != NULL);
assert(qname != NULL);
assert(pai != NULL);
cur = &sentinel;
canonname = NULL;
- eom = answer->buf + anslen;
+ eom = answer.data() + anslen;
switch (qtype) {
case T_A:
case T_AAAA:
@@ -876,18 +868,18 @@
/*
* find first satisfactory answer
*/
- hp = &answer->hdr;
+ hp = reinterpret_cast<const HEADER*>(answer.data());
ancount = ntohs(hp->ancount);
qdcount = ntohs(hp->qdcount);
bp = hostbuf;
ep = hostbuf + sizeof hostbuf;
- cp = answer->buf;
+ cp = answer.data();
BOUNDED_INCR(HFIXEDSZ);
if (qdcount != 1) {
*herrno = NO_RECOVERY;
return (NULL);
}
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
+ n = dn_expand(answer.data(), eom, cp, bp, ep - bp);
if ((n < 0) || !(*name_ok)(bp)) {
*herrno = NO_RECOVERY;
return (NULL);
@@ -911,7 +903,7 @@
haveanswer = 0;
had_error = 0;
while (ancount-- > 0 && cp < eom && !had_error) {
- n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
+ n = dn_expand(answer.data(), eom, cp, bp, ep - bp);
if ((n < 0) || !(*name_ok)(bp)) {
had_error++;
continue;
@@ -931,7 +923,7 @@
continue; /* XXX - had_error++ ? */
}
if ((qtype == T_A || qtype == T_AAAA || qtype == T_ANY) && type == T_CNAME) {
- n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
+ n = dn_expand(answer.data(), eom, cp, tbuf, sizeof tbuf);
if ((n < 0) || !(*name_ok)(tbuf)) {
had_error++;
continue;
@@ -1397,16 +1389,11 @@
res_target q = {};
res_target q2 = {};
- auto buf = std::make_unique<querybuf>();
- auto buf2 = std::make_unique<querybuf>();
-
switch (pai->ai_family) {
case AF_UNSPEC: {
/* prefer IPv6 */
q.name = name;
q.qclass = C_IN;
- q.answer = buf->buf;
- q.anslen = sizeof(buf->buf);
int query_ipv6 = 1, query_ipv4 = 1;
if (pai->ai_flags & AI_ADDRCONFIG) {
query_ipv6 = have_ipv6(netcontext->app_mark, netcontext->uid);
@@ -1419,8 +1406,6 @@
q2.name = name;
q2.qclass = C_IN;
q2.qtype = T_A;
- q2.answer = buf2->buf;
- q2.anslen = sizeof(buf2->buf);
}
} else if (query_ipv4) {
q.qtype = T_A;
@@ -1433,15 +1418,11 @@
q.name = name;
q.qclass = C_IN;
q.qtype = T_A;
- q.answer = buf->buf;
- q.anslen = sizeof(buf->buf);
break;
case AF_INET6:
q.name = name;
q.qclass = C_IN;
q.qtype = T_AAAA;
- q.answer = buf->buf;
- q.anslen = sizeof(buf->buf);
break;
default:
return EAI_FAMILY;
@@ -1460,13 +1441,13 @@
addrinfo sentinel = {};
addrinfo* cur = &sentinel;
- addrinfo* ai = getanswer(buf.get(), q.n, q.name, q.qtype, pai, &he);
+ addrinfo* ai = getanswer(q.answer, q.n, q.name, q.qtype, pai, &he);
if (ai) {
cur->ai_next = ai;
while (cur && cur->ai_next) cur = cur->ai_next;
}
if (q.next) {
- ai = getanswer(buf2.get(), q2.n, q2.name, q2.qtype, pai, &he);
+ ai = getanswer(q2.answer, q2.n, q2.name, q2.qtype, pai, &he);
if (ai) cur->ai_next = ai;
}
if (sentinel.ai_next == NULL) {
@@ -1578,7 +1559,6 @@
*/
static int res_queryN(const char* name, res_target* target, res_state res, int* herrno) {
uint8_t buf[MAXPACKET];
- HEADER* hp;
int n;
struct res_target* t;
int rcode;
@@ -1591,10 +1571,7 @@
ancount = 0;
for (t = target; t; t = t->next) {
- uint8_t* answer;
- int anslen;
-
- hp = (HEADER*) (void*) t->answer;
+ HEADER* hp = (HEADER*)(void*)t->answer.data();
bool retried = false;
again:
hp->rcode = NOERROR; /* default */
@@ -1602,8 +1579,7 @@
/* make it easier... */
int cl = t->qclass;
int type = t->qtype;
- answer = t->answer;
- anslen = t->anslen;
+ const int anslen = t->answer.size();
LOG(DEBUG) << __func__ << ": (" << cl << ", " << type << ")";
@@ -1620,7 +1596,7 @@
return n;
}
- n = res_nsend(res, buf, n, answer, anslen, &rcode, 0);
+ n = res_nsend(res, buf, n, t->answer.data(), anslen, &rcode, 0);
if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
// Record rcode from DNS response header only if no timeout.
// Keep rcode timeout for reporting later if any.
@@ -1689,7 +1665,7 @@
assert(name != NULL);
assert(target != NULL);
- hp = (HEADER*) (void*) target->answer; /*XXX*/
+ hp = (HEADER*)(void*)target->answer.data();
errno = 0;
*herrno = HOST_NOT_FOUND; /* default, if we never query */
diff --git a/gethnamaddr.cpp b/gethnamaddr.cpp
index 2a8c92b..6dcd358 100644
--- a/gethnamaddr.cpp
+++ b/gethnamaddr.cpp
@@ -95,8 +95,6 @@
#define maybe_hnok(res, hn) maybe_ok((res), (hn), res_hnok)
#define maybe_dnok(res, dn) maybe_ok((res), (dn), res_dnok)
-#define MAXPACKET (8 * 1024)
-
constexpr int MAXADDRS = 35;
typedef union {
diff --git a/res_query.cpp b/res_query.cpp
index 43c81fa..be0ff83 100644
--- a/res_query.cpp
+++ b/res_query.cpp
@@ -89,12 +89,6 @@
#include "resolv_cache.h"
#include "resolv_private.h"
-#if PACKETSZ > 1024
-#define MAXPACKET PACKETSZ
-#else
-#define MAXPACKET 1024
-#endif
-
/*
* Formulate a normal query, send, and await answer.
* Returned answer is placed in supplied buffer "answer".
diff --git a/res_send.cpp b/res_send.cpp
index 2fba22c..e917b13 100644
--- a/res_send.cpp
+++ b/res_send.cpp
@@ -226,15 +226,6 @@
return tsnow;
}
-static struct iovec evConsIovec(void* buf, size_t cnt) {
- struct iovec ret;
-
- memset(&ret, 0xf5, sizeof ret);
- ret.iov_base = buf;
- ret.iov_len = cnt;
- return ret;
-}
-
// END: Code copied from ISC eventlib
/* BIONIC-BEGIN: implement source port randomization */
@@ -449,6 +440,25 @@
return -ESRCH;
}
+ // DoT
+ if (!(statp->netcontext_flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS)) {
+ bool fallback = false;
+ resplen = res_tls_send(statp, Slice(const_cast<uint8_t*>(buf), buflen), Slice(ans, anssiz),
+ rcode, &fallback);
+ if (resplen > 0) {
+ LOG(DEBUG) << __func__ << ": got answer from DoT";
+ res_pquery(ans, resplen);
+ if (cache_status == RESOLV_CACHE_NOTFOUND) {
+ resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
+ }
+ return resplen;
+ }
+ if (!fallback) {
+ _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
+ return -terrno;
+ }
+ }
+
res_stats stats[MAXNS];
res_params params;
int revision_id = resolv_cache_get_resolver_stats(statp->netid, ¶ms, stats);
@@ -486,28 +496,6 @@
nsaplen = get_salen(nsap);
same_ns:
- // TODO: Since we expect there is only one DNS server being queried here while this
- // function tries to query all of private DNS servers. Consider moving it to other
- // reasonable place. In addition, maybe add stats for private DNS.
- if (!(statp->netcontext_flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS)) {
- bool fallback = false;
- resplen = res_tls_send(statp, Slice(const_cast<uint8_t*>(buf), buflen),
- Slice(ans, anssiz), rcode, &fallback);
- if (resplen > 0) {
- LOG(DEBUG) << __func__ << ": got answer from DoT";
- res_pquery(ans, resplen);
- if (cache_status == RESOLV_CACHE_NOTFOUND) {
- resolv_cache_add(statp->netid, buf, buflen, ans, resplen);
- }
- return resplen;
- }
- if (!fallback) {
- _resolv_cache_query_failed(statp->netid, buf, buflen, flags);
- res_nclose(statp);
- return -terrno;
- }
- }
-
static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
char abuf[NI_MAXHOST];
DnsQueryEvent* dnsQueryEvent = addDnsQueryEvent(statp->event);
@@ -669,7 +657,6 @@
struct sockaddr* nsap;
int nsaplen;
int truncating, connreset, n;
- struct iovec iov[2];
uint8_t* cp;
LOG(INFO) << __func__ << ": using send_vc";
@@ -754,8 +741,10 @@
* Send length & message
*/
uint16_t len = htons(static_cast<uint16_t>(buflen));
- iov[0] = evConsIovec(&len, INT16SZ);
- iov[1] = evConsIovec((void*) buf, (size_t) buflen);
+ const iovec iov[] = {
+ {.iov_base = &len, .iov_len = INT16SZ},
+ {.iov_base = const_cast<uint8_t*>(buf), .iov_len = static_cast<size_t>(buflen)},
+ };
if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
*terrno = errno;
PLOG(DEBUG) << __func__ << ": write failed: ";
@@ -863,8 +852,8 @@
}
/* return -1 on error (errno set), 0 on success */
-static int connect_with_timeout(int sock, const struct sockaddr* nsap, socklen_t salen,
- const struct timespec timeout) {
+static int connect_with_timeout(int sock, const sockaddr* nsap, socklen_t salen,
+ const timespec timeout) {
int res, origflags;
origflags = fcntl(sock, F_GETFL, 0);
@@ -876,8 +865,8 @@
goto done;
}
if (res != 0) {
- struct timespec now = evNowTime();
- struct timespec finish = evAddTime(now, timeout);
+ timespec now = evNowTime();
+ timespec finish = evAddTime(now, timeout);
LOG(INFO) << __func__ << ": " << sock << " send_vc";
res = retrying_poll(sock, POLLIN | POLLOUT, &finish);
if (res <= 0) {
@@ -1102,6 +1091,7 @@
char hbuf[NI_MAXHOST];
char sbuf[NI_MAXSERV];
constexpr int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
+ const int err = errno;
if (!WOULD_LOG(DEBUG)) return;
@@ -1111,6 +1101,7 @@
strncpy(sbuf, "?", sizeof(sbuf) - 1);
sbuf[sizeof(sbuf) - 1] = '\0';
}
+ errno = err;
PLOG(DEBUG) << __func__ << ": " << str << " ([" << hbuf << "]." << sbuf << "): ";
}
diff --git a/resolv_cache_unit_test.cpp b/resolv_cache_unit_test.cpp
index 1db209f..4235480 100644
--- a/resolv_cache_unit_test.cpp
+++ b/resolv_cache_unit_test.cpp
@@ -43,7 +43,6 @@
// Constant values sync'd from res_cache.cpp
constexpr int DNS_HEADER_SIZE = 12;
constexpr int MAX_ENTRIES = 64 * 2 * 5;
-constexpr int MAXPACKET = 8 * 1024;
namespace {
@@ -99,13 +98,6 @@
return std::time(nullptr);
}
-std::string addrToString(const sockaddr_storage* addr) {
- char out[INET6_ADDRSTRLEN] = {0};
- getnameinfo((const sockaddr*)addr, sizeof(sockaddr_storage), out, INET6_ADDRSTRLEN, nullptr, 0,
- NI_NUMERICHOST);
- return std::string(out);
-}
-
// Comparison for res_stats. Simply check the count in the cache test.
bool operator==(const res_stats& a, const res_stats& b) {
return std::tie(a.sample_count, a.sample_next) == std::tie(b.sample_count, b.sample_next);
diff --git a/resolv_private.h b/resolv_private.h
index 1babd84..e5efc64 100644
--- a/resolv_private.h
+++ b/resolv_private.h
@@ -86,6 +86,7 @@
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
};
+constexpr int MAXPACKET = 8 * 1024;
struct ResState {
unsigned netid; // NetId: cache key and socket mark
@@ -195,4 +196,11 @@
}
}
+inline std::string addrToString(const sockaddr_storage* addr) {
+ char out[INET6_ADDRSTRLEN] = {0};
+ getnameinfo((const sockaddr*)addr, sizeof(sockaddr_storage), out, INET6_ADDRSTRLEN, nullptr, 0,
+ NI_NUMERICHOST);
+ return std::string(out);
+}
+
#endif // NETD_RESOLV_PRIVATE_H