Merge "Support DNS64 synthesis using externally-discovered prefixes."
diff --git a/Dns64Configuration.cpp b/Dns64Configuration.cpp
index f646d81..5b3849b 100644
--- a/Dns64Configuration.cpp
+++ b/Dns64Configuration.cpp
@@ -37,11 +37,13 @@
namespace android {
+using android::base::StringPrintf;
using android::net::NetworkDnsEventReported;
using netdutils::DumpWriter;
using netdutils::IPAddress;
using netdutils::IPPrefix;
using netdutils::ScopedAddrinfo;
+using netdutils::setThreadName;
namespace net {
@@ -64,7 +66,7 @@
// Note that capturing |cfg| in this lambda creates a copy.
std::thread discovery_thread([this, cfg, netId] {
- netdutils::setThreadName(android::base::StringPrintf("Nat64Pfx_%u", netId).c_str());
+ setThreadName(StringPrintf("Nat64Pfx_%u", netId).c_str());
// Make a mutable copy rather than mark the whole lambda mutable.
// No particular reason.
diff --git a/DnsTlsDispatcher.cpp b/DnsTlsDispatcher.cpp
index 8747e46..1fa4001 100644
--- a/DnsTlsDispatcher.cpp
+++ b/DnsTlsDispatcher.cpp
@@ -147,6 +147,10 @@
const Slice query, const Slice ans, int* resplen,
bool* connectTriggered) {
int connectCounter;
+
+ // TODO: This can cause the resolver to create multiple connections to the same DoT server
+ // merely due to different mark, such as the bit explicitlySelected unset.
+ // See if we can save them and just create one connection for one DoT server.
const Key key = std::make_pair(mark, server);
Transport* xport;
{
diff --git a/DnsTlsSocket.cpp b/DnsTlsSocket.cpp
index 9ce8ec2..cab678d 100644
--- a/DnsTlsSocket.cpp
+++ b/DnsTlsSocket.cpp
@@ -32,7 +32,6 @@
#include "DnsTlsSessionCache.h"
#include "IDnsTlsSocketObserver.h"
-#include <Fwmark.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <netdutils/SocketOption.h>
@@ -49,9 +48,11 @@
namespace android {
+using base::StringPrintf;
using netdutils::enableSockopt;
using netdutils::enableTcpKeepAlives;
using netdutils::isOk;
+using netdutils::setThreadName;
using netdutils::Slice;
using netdutils::Status;
@@ -70,13 +71,6 @@
return TEMP_FAILURE_RETRY(poll(&fds, 1, timeoutMs));
}
-std::string markToFwmarkString(unsigned mMark) {
- Fwmark mark;
- mark.intValue = mMark;
- return android::base::StringPrintf("%d, %d, %d, %d, %d", mark.netId, mark.explicitlySelected,
- mark.protectedFromVpn, mark.permission, mark.uidBillingDone);
-}
-
} // namespace
Status DnsTlsSocket::tcpConnect() {
@@ -243,9 +237,9 @@
}
for (;;) {
- LOG(DEBUG) << " Calling SSL_connect with " << markToFwmarkString(mMark);
+ LOG(DEBUG) << " Calling SSL_connect with mark 0x" << std::hex << mMark;
int ret = SSL_connect(ssl.get());
- LOG(DEBUG) << " SSL_connect returned " << ret << " with " << markToFwmarkString(mMark);
+ LOG(DEBUG) << " SSL_connect returned " << ret << " with mark 0x" << std::hex << mMark;
if (ret == 1) break; // SSL handshake complete;
const int ssl_err = SSL_get_error(ssl.get(), ret);
@@ -255,8 +249,8 @@
// the TCP connection handshake, the device is waiting for the SSL handshake reply
// from the server.
if (int err = waitForReading(fd, mServer.connectTimeout.count()); err <= 0) {
- PLOG(WARNING) << "SSL_connect read error " << err << ", "
- << markToFwmarkString(mMark);
+ PLOG(WARNING) << "SSL_connect read error " << err << ", mark 0x" << std::hex
+ << mMark;
return nullptr;
}
break;
@@ -264,14 +258,14 @@
// If no application data is sent during the TCP connection handshake, the
// device is waiting for the connection established to perform SSL handshake.
if (int err = waitForWriting(fd, mServer.connectTimeout.count()); err <= 0) {
- PLOG(WARNING) << "SSL_connect write error " << err << ", "
- << markToFwmarkString(mMark);
+ PLOG(WARNING) << "SSL_connect write error " << err << ", mark 0x" << std::hex
+ << mMark;
return nullptr;
}
break;
default:
- PLOG(WARNING) << "SSL_connect ssl error =" << ssl_err << ", "
- << markToFwmarkString(mMark);
+ PLOG(WARNING) << "SSL_connect ssl error =" << ssl_err << ", mark 0x" << std::hex
+ << mMark;
return nullptr;
}
}
@@ -321,9 +315,7 @@
std::deque<std::vector<uint8_t>> q;
const int timeout_msecs = DnsTlsSocket::kIdleTimeout.count() * 1000;
- Fwmark mark;
- mark.intValue = mMark;
- netdutils::setThreadName(android::base::StringPrintf("TlsListen_%u", mark.netId).c_str());
+ setThreadName(StringPrintf("TlsListen_%u", mMark & 0xffff).c_str());
while (true) {
// poll() ignores negative fds
struct pollfd fds[2] = { { .fd = -1 }, { .fd = -1 } };
diff --git a/DnsTlsTransport.cpp b/DnsTlsTransport.cpp
index 54a7f89..d0098c2 100644
--- a/DnsTlsTransport.cpp
+++ b/DnsTlsTransport.cpp
@@ -18,7 +18,6 @@
#include "DnsTlsTransport.h"
-#include <Fwmark.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <arpa/inet.h>
@@ -28,6 +27,9 @@
#include "DnsTlsSocketFactory.h"
#include "IDnsTlsSocketFactory.h"
+using android::base::StringPrintf;
+using android::netdutils::setThreadName;
+
namespace android {
namespace net {
@@ -112,9 +114,7 @@
void DnsTlsTransport::doReconnect() {
std::lock_guard guard(mLock);
- Fwmark mark;
- mark.intValue = mMark;
- netdutils::setThreadName(android::base::StringPrintf("TlsReconn_%u", mark.netId).c_str());
+ setThreadName(StringPrintf("TlsReconn_%u", mMark & 0xffff).c_str());
if (mClosing) {
return;
}
diff --git a/PrivateDnsConfiguration.cpp b/PrivateDnsConfiguration.cpp
index 2263153..182a5ac 100644
--- a/PrivateDnsConfiguration.cpp
+++ b/PrivateDnsConfiguration.cpp
@@ -31,6 +31,8 @@
#include "resolv_cache.h"
#include "util.h"
+using android::base::StringPrintf;
+using android::netdutils::setThreadName;
using std::chrono::milliseconds;
namespace android {
@@ -180,7 +182,7 @@
// Note that capturing |server| and |netId| in this lambda create copies.
std::thread validate_thread([this, server, netId, mark] {
- netdutils::setThreadName(android::base::StringPrintf("TlsVerify_%u", netId).c_str());
+ setThreadName(StringPrintf("TlsVerify_%u", netId).c_str());
// cat /proc/sys/net/ipv4/tcp_syn_retries yields "6".
//
diff --git a/ResolverController.cpp b/ResolverController.cpp
index 13600b8..be0b989 100644
--- a/ResolverController.cpp
+++ b/ResolverController.cpp
@@ -24,7 +24,6 @@
#include <netdb.h>
-#include <Fwmark.h>
#include <aidl/android/net/IDnsResolver.h>
#include <android-base/logging.h>
#include <android-base/strings.h>
@@ -202,21 +201,22 @@
int ResolverController::setResolverConfiguration(const ResolverParamsParcel& resolverParams) {
using aidl::android::net::IDnsResolver;
- // At private DNS validation time, we only know the netId, so we have to guess/compute the
- // corresponding socket mark.
- Fwmark fwmark;
- fwmark.netId = resolverParams.netId;
- fwmark.explicitlySelected = true;
- fwmark.protectedFromVpn = true;
- fwmark.permission = PERMISSION_SYSTEM;
+ // Expect to get the mark with system permission.
+ android_net_context netcontext;
+ gResNetdCallbacks.get_network_context(resolverParams.netId, 0 /* uid */, &netcontext);
// Allow at most MAXNS private DNS servers in a network to prevent too many broken servers.
std::vector<std::string> tlsServers = resolverParams.tlsServers;
if (tlsServers.size() > MAXNS) {
tlsServers.resize(MAXNS);
}
+
+ // Use app_mark for DoT connection. Using dns_mark might result in reaching the DoT servers
+ // through a different network. For example, on a VPN with no DNS servers (Do53), if the VPN
+ // applies to UID 0, dns_mark is assigned for default network rathan the VPN. (note that it's
+ // possible that a VPN doesn't have any DNS servers but DoT servers in DNS strict mode)
const int err =
- gPrivateDnsConfiguration.set(resolverParams.netId, fwmark.intValue, tlsServers,
+ gPrivateDnsConfiguration.set(resolverParams.netId, netcontext.app_mark, tlsServers,
resolverParams.tlsName, resolverParams.caCertificate);
if (err != 0) {
diff --git a/res_send.cpp b/res_send.cpp
index a10bbd1..2b84e82 100644
--- a/res_send.cpp
+++ b/res_send.cpp
@@ -130,6 +130,7 @@
using android::net::IV_IPV4;
using android::net::IV_IPV6;
using android::net::IV_UNKNOWN;
+using android::net::LinuxErrno;
using android::net::NetworkDnsEventReported;
using android::net::NS_T_INVALID;
using android::net::NsRcode;
@@ -499,7 +500,8 @@
int retryTimes = (flags & ANDROID_RESOLV_NO_RETRY) ? 1 : params.retry_count;
int useTcp = buflen > PACKETSZ;
int gotsomewhere = 0;
- int terrno = ETIMEDOUT;
+ // Use an impossible error code as default value
+ int terrno = ETIME;
for (int attempt = 0; attempt < retryTimes; ++attempt) {
for (size_t ns = 0; ns < statp->nsaddrs.size(); ++ns) {
@@ -521,6 +523,8 @@
Stopwatch queryStopwatch;
int retry_count_for_event = 0;
size_t actualNs = ns;
+ // Use an impossible error code as default value
+ terrno = ETIME;
if (useTcp) {
// TCP; at most one attempt per server.
attempt = retryTimes;
@@ -558,6 +562,7 @@
dnsQueryEvent->set_rcode(static_cast<NsRcode>(*rcode));
dnsQueryEvent->set_protocol(query_proto);
dnsQueryEvent->set_type(getQueryType(buf, buflen));
+ dnsQueryEvent->set_linux_errno(static_cast<LinuxErrno>(terrno));
// Only record stats the first time we try a query. This ensures that
// queries that deterministically fail (e.g., a name that always returns
@@ -643,6 +648,7 @@
// It should never happen, but just in case.
if (ns >= statp->nsaddrs.size()) {
LOG(ERROR) << __func__ << ": Out-of-bound indexing: " << ns;
+ *terrno = EINVAL;
return -1;
}
@@ -675,15 +681,14 @@
statp->tcp_nssock.reset(socket(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0));
if (statp->tcp_nssock < 0) {
+ *terrno = errno;
+ PLOG(DEBUG) << __func__ << ": socket(vc): ";
switch (errno) {
case EPROTONOSUPPORT:
case EPFNOSUPPORT:
case EAFNOSUPPORT:
- PLOG(DEBUG) << __func__ << ": socket(vc): ";
return 0;
default:
- *terrno = errno;
- PLOG(DEBUG) << __func__ << ": socket(vc): ";
return -1;
}
}
@@ -831,6 +836,7 @@
*delay = res_stats_calculate_rtt(&done, &start_time);
*rcode = anhp->rcode;
}
+ *terrno = 0;
return (resplen);
}
@@ -972,6 +978,7 @@
// It should never happen, but just in case.
if (*ns >= statp->nsaddrs.size()) {
LOG(ERROR) << __func__ << ": Out-of-bound indexing: " << ns;
+ *terrno = EINVAL;
return -1;
}
@@ -984,15 +991,14 @@
if (statp->nssocks[*ns] == -1) {
statp->nssocks[*ns].reset(socket(nsap->sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0));
if (statp->nssocks[*ns] < 0) {
+ *terrno = errno;
+ PLOG(DEBUG) << __func__ << ": socket(dg): ";
switch (errno) {
case EPROTONOSUPPORT:
case EPFNOSUPPORT:
case EAFNOSUPPORT:
- PLOG(DEBUG) << __func__ << ": socket(dg): ";
return (0);
default:
- *terrno = errno;
- PLOG(DEBUG) << __func__ << ": socket(dg): ";
return (-1);
}
}
@@ -1001,6 +1007,7 @@
if (statp->_mark != MARK_UNSET) {
if (setsockopt(statp->nssocks[*ns], SOL_SOCKET, SO_MARK, &(statp->_mark),
sizeof(statp->_mark)) < 0) {
+ *terrno = errno;
statp->closeSockets();
return -1;
}
@@ -1010,11 +1017,13 @@
// ICMP port-unreachable error. This way we can detect the absence of
// a nameserver without timing out.
if (random_bind(statp->nssocks[*ns], nsap->sa_family) < 0) {
+ *terrno = errno;
dump_error("bind(dg)", nsap, nsaplen);
statp->closeSockets();
return (0);
}
if (connect(statp->nssocks[*ns], nsap, (socklen_t)nsaplen) < 0) {
+ *terrno = errno;
dump_error("connect(dg)", nsap, nsaplen);
statp->closeSockets();
return (0);
@@ -1022,6 +1031,7 @@
LOG(DEBUG) << __func__ << ": new DG socket";
}
if (send(statp->nssocks[*ns], (const char*)buf, (size_t)buflen, 0) != buflen) {
+ *terrno = errno;
PLOG(DEBUG) << __func__ << ": send: ";
statp->closeSockets();
return 0;
@@ -1037,6 +1047,7 @@
if (!result.has_value()) {
const bool isTimeout = (result.error().code() == ETIMEDOUT);
*rcode = (isTimeout) ? RCODE_TIMEOUT : *rcode;
+ *terrno = (isTimeout) ? ETIMEDOUT : errno;
*gotsomewhere = (isTimeout) ? 1 : *gotsomewhere;
// Leave the UDP sockets open on timeout so we can keep listening for
// a late response from this server while retrying on the next server.
@@ -1052,6 +1063,7 @@
int resplen =
recvfrom(fd, (char*)ans, (size_t)anssiz, 0, (sockaddr*)(void*)&from, &fromlen);
if (resplen <= 0) {
+ *terrno = errno;
PLOG(DEBUG) << __func__ << ": recvfrom: ";
continue;
}
@@ -1080,6 +1092,7 @@
res_pquery(ans, (resplen > anssiz) ? anssiz : resplen);
// record the error
statp->_flags |= RES_F_EDNS0ERR;
+ *terrno = EREMOTEIO;
continue;
}
@@ -1095,6 +1108,7 @@
// To get the rest of answer,
// use TCP with same server.
LOG(DEBUG) << __func__ << ": truncated answer";
+ *terrno = E2BIG;
*v_circuit = 1;
return 1;
}
@@ -1103,6 +1117,7 @@
*rcode = anhp->rcode;
*ns = receivedFromNs;
+ *terrno = 0;
return resplen;
}
if (!needRetry) return 0;
diff --git a/resolv_cache_unit_test.cpp b/resolv_cache_unit_test.cpp
index 6e7ffee..40f1ec6 100644
--- a/resolv_cache_unit_test.cpp
+++ b/resolv_cache_unit_test.cpp
@@ -22,7 +22,6 @@
#include <ctime>
#include <thread>
-#include <aidl/android/net/IDnsResolver.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <android/multinetwork.h>
@@ -39,7 +38,6 @@
using namespace std::chrono_literals;
-using aidl::android::net::IDnsResolver;
using android::netdutils::IPSockAddr;
constexpr int TEST_NETID = 30;
@@ -839,64 +837,6 @@
EXPECT_STREQ(answer, domain_name);
}
-TEST_F(ResolvCacheTest, GetNetworkTypesForNet) {
- const SetupParams setup = {
- .servers = {"127.0.0.1", "::127.0.0.2", "fe80::3"},
- .domains = {"domain1.com", "domain2.com"},
- .params = kParams,
- .transportTypes = {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_VPN}};
- EXPECT_EQ(0, cacheCreate(TEST_NETID));
- EXPECT_EQ(0, cacheSetupResolver(TEST_NETID, setup));
- EXPECT_EQ(android::net::NT_WIFI_VPN, resolv_get_network_types_for_net(TEST_NETID));
-}
-
-TEST_F(ResolvCacheTest, ConvertTransportsToNetworkType) {
- static const struct TestConfig {
- int32_t networkType;
- std::vector<int32_t> transportTypes;
- } testConfigs[] = {
- {android::net::NT_CELLULAR, {IDnsResolver::TRANSPORT_CELLULAR}},
- {android::net::NT_WIFI, {IDnsResolver::TRANSPORT_WIFI}},
- {android::net::NT_BLUETOOTH, {IDnsResolver::TRANSPORT_BLUETOOTH}},
- {android::net::NT_ETHERNET, {IDnsResolver::TRANSPORT_ETHERNET}},
- {android::net::NT_VPN, {IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_WIFI_AWARE, {IDnsResolver::TRANSPORT_WIFI_AWARE}},
- {android::net::NT_LOWPAN, {IDnsResolver::TRANSPORT_LOWPAN}},
- {android::net::NT_CELLULAR_VPN,
- {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_CELLULAR_VPN,
- {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_CELLULAR}},
- {android::net::NT_WIFI_VPN,
- {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_WIFI_VPN,
- {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_WIFI}},
- {android::net::NT_BLUETOOTH_VPN,
- {IDnsResolver::TRANSPORT_BLUETOOTH, IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_BLUETOOTH_VPN,
- {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_BLUETOOTH}},
- {android::net::NT_ETHERNET_VPN,
- {IDnsResolver::TRANSPORT_ETHERNET, IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_ETHERNET_VPN,
- {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_ETHERNET}},
- {android::net::NT_UNKNOWN, {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_UNKNOWN,
- {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_LOWPAN}},
- {android::net::NT_UNKNOWN, {}},
- {android::net::NT_UNKNOWN,
- {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_BLUETOOTH,
- IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_WIFI_CELLULAR_VPN,
- {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_WIFI,
- IDnsResolver::TRANSPORT_VPN}},
- {android::net::NT_WIFI_CELLULAR_VPN,
- {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_WIFI,
- IDnsResolver::TRANSPORT_CELLULAR}},
- };
- for (const auto& config : testConfigs) {
- EXPECT_EQ(config.networkType, convert_network_type(config.transportTypes));
- }
-}
-
namespace {
constexpr int EAI_OK = 0;
diff --git a/resolv_unit_test.cpp b/resolv_unit_test.cpp
index e0166ea..3274ed8 100644
--- a/resolv_unit_test.cpp
+++ b/resolv_unit_test.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "resolv"
+#include <aidl/android/net/IDnsResolver.h>
#include <android-base/stringprintf.h>
#include <arpa/inet.h>
#include <gmock/gmock-matchers.h>
@@ -36,6 +37,7 @@
namespace android {
namespace net {
+using aidl::android::net::IDnsResolver;
using android::base::StringPrintf;
using android::net::NetworkDnsEventReported;
using android::netdutils::ScopedAddrinfo;
@@ -122,16 +124,6 @@
}
int SetResolvers() {
- const std::vector<std::string> servers = {test::kDefaultListenAddr};
- const std::vector<std::string> domains = {"example.com"};
- const res_params params = {
- .sample_validity = 300,
- .success_threshold = 25,
- .min_samples = 8,
- .max_samples = 8,
- .base_timeout_msec = 1000,
- .retry_count = 2,
- };
return resolv_set_nameservers(TEST_NETID, servers, domains, params);
}
@@ -142,10 +134,21 @@
.dns_mark = MARK_UNSET,
.uid = NET_CONTEXT_INVALID_UID,
};
+ const std::vector<std::string> servers = {test::kDefaultListenAddr};
+ const std::vector<std::string> domains = {"example.com"};
+ const res_params params = {
+ .sample_validity = 300,
+ .success_threshold = 25,
+ .min_samples = 8,
+ .max_samples = 8,
+ .base_timeout_msec = 1000,
+ .retry_count = 2,
+ };
};
class ResolvGetAddrInfoTest : public TestBase {};
class GetHostByNameForNetContextTest : public TestBase {};
+class ResolvCommonFunctionTest : public TestBase {};
TEST_F(ResolvGetAddrInfoTest, InvalidParameters) {
// Both null "netcontext" and null "res" of resolv_getaddrinfo() are not tested
@@ -410,6 +413,7 @@
dns_server_index: 0,
connected: 0,
latency_micros: 0,
+ linux_errno: 0,
},
{
rcode: 0,
@@ -421,6 +425,7 @@
dns_server_index: 0,
connected: 0,
latency_micros: 0,
+ linux_errno: 0,
},
{
rcode: 0,
@@ -432,6 +437,7 @@
dns_server_index: 0,
connected: 0,
latency_micros: 0,
+ linux_errno: 0,
},
{
rcode: 0,
@@ -443,6 +449,7 @@
dns_server_index: 0,
connected: 0,
latency_micros: 0,
+ linux_errno: 0,
}
]
}
@@ -486,6 +493,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
},
{
rcode: 0,
@@ -496,6 +504,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
}
]
}
@@ -515,6 +524,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
},
{
rcode: 0,
@@ -525,6 +535,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
}
]
}
@@ -660,6 +671,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -670,6 +682,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
}
{
rcode: 255,
@@ -680,6 +693,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -690,6 +704,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -700,6 +715,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -710,6 +726,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
}
{
rcode: 255,
@@ -720,6 +737,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -730,6 +748,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -740,6 +759,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -750,6 +770,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
}
{
rcode: 255,
@@ -760,6 +781,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -770,6 +792,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -780,6 +803,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -790,6 +814,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
}
{
rcode: 255,
@@ -800,6 +825,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
{
rcode: 255,
@@ -810,6 +836,7 @@
retry_times: 1,
dns_server_index: 0,
connected: 0,
+ linux_errno: 110,
},
]
}
@@ -1002,6 +1029,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 7,
},
{
rcode: 0,
@@ -1012,6 +1040,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
},
{
rcode: 0,
@@ -1022,6 +1051,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
}
]
}
@@ -1041,6 +1071,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 7,
},
{
rcode: 0,
@@ -1051,6 +1082,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
},
{
rcode: 0,
@@ -1061,6 +1093,7 @@
retry_times: 0,
dns_server_index: 0,
connected: 0,
+ linux_errno: 0,
}
]
}
@@ -1128,6 +1161,7 @@
dns_server_index: 0,
connected: 0,
latency_micros: 0,
+ linux_errno: 0,
}
]
}
@@ -1148,6 +1182,7 @@
dns_server_index: 0,
connected: 0,
latency_micros: 0,
+ linux_errno: 0,
}
]
}
@@ -1416,6 +1451,91 @@
}
}
+TEST_F(ResolvCommonFunctionTest, GetCustTableByName) {
+ const char custAddrV4[] = "1.2.3.4";
+ const char custAddrV6[] = "::1.2.3.4";
+ const char hostnameV4V6[] = "v4v6.example.com.";
+ const aidl::android::net::ResolverOptionsParcel& resolverOptions = {
+ {
+ {custAddrV4, hostnameV4V6},
+ {custAddrV6, hostnameV4V6},
+ },
+ aidl::android::net::IDnsResolver::TC_MODE_DEFAULT};
+ const std::vector<int32_t>& transportTypes = {IDnsResolver::TRANSPORT_WIFI};
+ EXPECT_EQ(0, resolv_set_nameservers(TEST_NETID, servers, domains, params, resolverOptions,
+ transportTypes));
+ EXPECT_THAT(getCustomizedTableByName(TEST_NETID, hostnameV4V6),
+ testing::UnorderedElementsAreArray({custAddrV4, custAddrV6}));
+
+ // Query address by mismatch hostname.
+ ASSERT_TRUE(getCustomizedTableByName(TEST_NETID, "not.in.cust.table").empty());
+
+ // Query address by different netid.
+ ASSERT_TRUE(getCustomizedTableByName(TEST_NETID + 1, hostnameV4V6).empty());
+ resolv_create_cache_for_net(TEST_NETID + 1);
+ EXPECT_EQ(0, resolv_set_nameservers(TEST_NETID + 1, servers, domains, params, resolverOptions,
+ transportTypes));
+ EXPECT_THAT(getCustomizedTableByName(TEST_NETID + 1, hostnameV4V6),
+ testing::UnorderedElementsAreArray({custAddrV4, custAddrV6}));
+}
+
+TEST_F(ResolvCommonFunctionTest, GetNetworkTypesForNet) {
+ const aidl::android::net::ResolverOptionsParcel& resolverOptions = {
+ {} /* hosts */, aidl::android::net::IDnsResolver::TC_MODE_DEFAULT};
+ const std::vector<int32_t>& transportTypes = {IDnsResolver::TRANSPORT_WIFI,
+ IDnsResolver::TRANSPORT_VPN};
+ EXPECT_EQ(0, resolv_set_nameservers(TEST_NETID, servers, domains, params, resolverOptions,
+ transportTypes));
+ EXPECT_EQ(android::net::NT_WIFI_VPN, resolv_get_network_types_for_net(TEST_NETID));
+}
+
+TEST_F(ResolvCommonFunctionTest, ConvertTransportsToNetworkType) {
+ static const struct TestConfig {
+ int32_t networkType;
+ std::vector<int32_t> transportTypes;
+ } testConfigs[] = {
+ {android::net::NT_CELLULAR, {IDnsResolver::TRANSPORT_CELLULAR}},
+ {android::net::NT_WIFI, {IDnsResolver::TRANSPORT_WIFI}},
+ {android::net::NT_BLUETOOTH, {IDnsResolver::TRANSPORT_BLUETOOTH}},
+ {android::net::NT_ETHERNET, {IDnsResolver::TRANSPORT_ETHERNET}},
+ {android::net::NT_VPN, {IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_WIFI_AWARE, {IDnsResolver::TRANSPORT_WIFI_AWARE}},
+ {android::net::NT_LOWPAN, {IDnsResolver::TRANSPORT_LOWPAN}},
+ {android::net::NT_CELLULAR_VPN,
+ {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_CELLULAR_VPN,
+ {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_CELLULAR}},
+ {android::net::NT_WIFI_VPN,
+ {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_WIFI_VPN,
+ {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_WIFI}},
+ {android::net::NT_BLUETOOTH_VPN,
+ {IDnsResolver::TRANSPORT_BLUETOOTH, IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_BLUETOOTH_VPN,
+ {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_BLUETOOTH}},
+ {android::net::NT_ETHERNET_VPN,
+ {IDnsResolver::TRANSPORT_ETHERNET, IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_ETHERNET_VPN,
+ {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_ETHERNET}},
+ {android::net::NT_UNKNOWN, {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_UNKNOWN,
+ {IDnsResolver::TRANSPORT_WIFI, IDnsResolver::TRANSPORT_LOWPAN}},
+ {android::net::NT_UNKNOWN, {}},
+ {android::net::NT_UNKNOWN,
+ {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_BLUETOOTH,
+ IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_WIFI_CELLULAR_VPN,
+ {IDnsResolver::TRANSPORT_CELLULAR, IDnsResolver::TRANSPORT_WIFI,
+ IDnsResolver::TRANSPORT_VPN}},
+ {android::net::NT_WIFI_CELLULAR_VPN,
+ {IDnsResolver::TRANSPORT_VPN, IDnsResolver::TRANSPORT_WIFI,
+ IDnsResolver::TRANSPORT_CELLULAR}},
+ };
+ for (const auto& config : testConfigs) {
+ EXPECT_EQ(config.networkType, convert_network_type(config.transportTypes));
+ }
+}
+
// Note that local host file function, files_getaddrinfo(), of resolv_getaddrinfo()
// is not tested because it only returns a boolean (success or failure) without any error number.
diff --git a/tests/resolv_stats_test_utils.cpp b/tests/resolv_stats_test_utils.cpp
index d31e6c0..06eff1b 100644
--- a/tests/resolv_stats_test_utils.cpp
+++ b/tests/resolv_stats_test_utils.cpp
@@ -130,6 +130,8 @@
dnsQueryEvent->set_connected(static_cast<bool>(value));
} else if (protoField[1] == "latency_micros" && ParseInt(protoField[2], &value)) {
dnsQueryEvent->set_latency_micros(value);
+ } else if (protoField[1] == "linux_errno" && ParseInt(protoField[2], &value)) {
+ dnsQueryEvent->set_linux_errno(static_cast<LinuxErrno>(value));
}
}
}
@@ -153,6 +155,7 @@
*os << " dns_server_index: " << event.dns_server_index() << "\n";
*os << " connected: " << event.connected() << "\n";
*os << " latency_micros: " << event.latency_micros() << "\n";
+ *os << " linux_errno: " << event.linux_errno() << "\n";
*os << "}";
}
diff --git a/tests/resolv_stats_test_utils.h b/tests/resolv_stats_test_utils.h
index cdfbe26..f0e0ea1 100644
--- a/tests/resolv_stats_test_utils.h
+++ b/tests/resolv_stats_test_utils.h
@@ -53,6 +53,8 @@
// Removing the latency check, because we can't predict the time.
/* ::testing::Property("latency_micros", &DnsQueryEvent::latency_micros,
::testing::Eq(other.latency_micros())),*/
+ ::testing::Property("linux_errno", &DnsQueryEvent::linux_errno,
+ ::testing::Eq(other.linux_errno())),
::testing::Property("connected", &DnsQueryEvent::connected,
::testing::Eq(other.connected()))),
arg, result_listener);