Loading DnsProxyListener.cpp +4 −11 Original line number Diff line number Diff line Loading @@ -118,18 +118,11 @@ constexpr bool requestingUseLocalNameservers(unsigned flags) { return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0; } inline bool queryingViaTls(unsigned dns_netid) { // TODO: The simpler PrivateDnsStatus should suffice here. ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}}; gPrivateDnsConfiguration.getStatus(dns_netid, &privateDnsStatus); switch (static_cast<PrivateDnsMode>(privateDnsStatus.mode)) { bool queryingViaTls(unsigned dns_netid) { const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(dns_netid); switch (privateDnsStatus.mode) { case PrivateDnsMode::OPPORTUNISTIC: for (int i = 0; i < privateDnsStatus.numServers; i++) { if (privateDnsStatus.serverStatus[i].validation == Validation::success) { return true; } } return false; return !privateDnsStatus.validatedServers().empty(); case PrivateDnsMode::STRICT: return true; default: Loading PrivateDnsConfiguration.cpp +4 −25 Original line number Diff line number Diff line Loading @@ -126,37 +126,13 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) { const auto netPair = mPrivateDnsTransports.find(netId); if (netPair != mPrivateDnsTransports.end()) { for (const auto& serverPair : netPair->second) { if (serverPair.second == Validation::success) { status.validatedServers.push_back(serverPair.first); } status.serversMap.emplace(serverPair.first, serverPair.second); } } return status; } void PrivateDnsConfiguration::getStatus(unsigned netId, ExternalPrivateDnsStatus* status) { std::lock_guard guard(mPrivateDnsLock); const auto mode = mPrivateDnsModes.find(netId); if (mode == mPrivateDnsModes.end()) return; status->mode = mode->second; const auto netPair = mPrivateDnsTransports.find(netId); if (netPair != mPrivateDnsTransports.end()) { int count = 0; for (const auto& serverPair : netPair->second) { status->serverStatus[count].ss = serverPair.first.ss; status->serverStatus[count].hostname = serverPair.first.name.empty() ? "" : serverPair.first.name.c_str(); status->serverStatus[count].validation = serverPair.second; count++; if (count >= MAXNS) break; // Lose the rest } status->numServers = count; } } void PrivateDnsConfiguration::clear(unsigned netId) { LOG(DEBUG) << "PrivateDnsConfiguration::clear(" << netId << ")"; std::lock_guard guard(mPrivateDnsLock); Loading Loading @@ -242,6 +218,9 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser auto& tracker = netPair->second; auto serverPair = tracker.find(server); if (serverPair == tracker.end()) { // TODO: Consider not adding this server to the tracker since this server is not expected // to be one of the private DNS servers for this network now. This could prevent this // server from being included when dumping status. LOG(WARNING) << "Server " << addrToString(&server.ss) << " was removed during private DNS validation"; success = false; Loading PrivateDnsConfiguration.h +16 −22 Original line number Diff line number Diff line Loading @@ -14,8 +14,7 @@ * limitations under the License. */ #ifndef NETD_RESOLV_PRIVATEDNSCONFIGURATION_H #define NETD_RESOLV_PRIVATEDNSCONFIGURATION_H #pragma once #include <list> #include <map> Loading @@ -37,31 +36,28 @@ enum class Validation : uint8_t { in_process, success, fail, unknown_server, unk struct PrivateDnsStatus { PrivateDnsMode mode; std::list<DnsTlsServer> validatedServers; }; // TODO: remove this C-style struct and use PrivateDnsStatus everywhere. struct ExternalPrivateDnsStatus { PrivateDnsMode mode; int numServers; struct PrivateDnsInfo { sockaddr_storage ss; const char* hostname; Validation validation; } serverStatus[MAXNS]; std::map<DnsTlsServer, Validation, AddressComparator> serversMap; std::list<DnsTlsServer> validatedServers() const { std::list<DnsTlsServer> servers; for (const auto& pair : serversMap) { if (pair.second == Validation::success) { servers.push_back(pair.first); } } return servers; } }; class PrivateDnsConfiguration { public: int set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert); const std::string& name, const std::string& caCert) EXCLUDES(mPrivateDnsLock); PrivateDnsStatus getStatus(unsigned netId); PrivateDnsStatus getStatus(unsigned netId) EXCLUDES(mPrivateDnsLock); // DEPRECATED, use getStatus() above. void getStatus(unsigned netId, ExternalPrivateDnsStatus* status); void clear(unsigned netId); void clear(unsigned netId) EXCLUDES(mPrivateDnsLock); private: typedef std::map<DnsTlsServer, Validation, AddressComparator> PrivateDnsTracker; Loading @@ -88,5 +84,3 @@ extern PrivateDnsConfiguration gPrivateDnsConfiguration; } // namespace net } // namespace android #endif /* NETD_RESOLV_PRIVATEDNSCONFIGURATION_H */ ResolverController.cpp +10 −15 Original line number Diff line number Diff line Loading @@ -249,11 +249,9 @@ int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* // Serialize the information for binder. ResolverStats::encodeAll(res_stats, stats); ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}}; gPrivateDnsConfiguration.getStatus(netId, &privateDnsStatus); for (int i = 0; i < privateDnsStatus.numServers; i++) { std::string tlsServer_str = addrToString(&(privateDnsStatus.serverStatus[i].ss)); tlsServers->push_back(std::move(tlsServer_str)); const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId); for (const auto& pair : privateDnsStatus.serversMap) { tlsServers->push_back(addrToString(&pair.first.ss)); } params->resize(IDnsResolver::RESOLVER_PARAMS_COUNT); Loading Loading @@ -344,20 +342,17 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { } mDns64Configuration.dump(dw, netId); ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}}; gPrivateDnsConfiguration.getStatus(netId, &privateDnsStatus); const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId); dw.println("Private DNS mode: %s", getPrivateDnsModeString(privateDnsStatus.mode)); if (!privateDnsStatus.numServers) { if (privateDnsStatus.serversMap.size() == 0) { dw.println("No Private DNS servers configured"); } else { dw.println("Private DNS configuration (%u entries)", privateDnsStatus.numServers); dw.println("Private DNS configuration (%u entries)", static_cast<uint32_t>(privateDnsStatus.serversMap.size())); dw.incIndent(); for (int i = 0; i < privateDnsStatus.numServers; i++) { dw.println("%s name{%s} status{%s}", addrToString(&(privateDnsStatus.serverStatus[i].ss)).c_str(), privateDnsStatus.serverStatus[i].hostname, validationStatusToString(static_cast<Validation>( privateDnsStatus.serverStatus[i].validation))); for (const auto& pair : privateDnsStatus.serversMap) { dw.println("%s name{%s} status{%s}", addrToString(&pair.first.ss).c_str(), pair.first.name.c_str(), validationStatusToString(pair.second)); } dw.decIndent(); } Loading res_cache.cpp +6 −109 Original line number Diff line number Diff line Loading @@ -581,98 +581,6 @@ static int _dnsPacket_checkQuery(DnsPacket* packet) { return 1; } /** QUERY DEBUGGING **/ static char* dnsPacket_bprintQName(DnsPacket* packet, char* bp, char* bend) { const uint8_t* p = packet->cursor; const uint8_t* end = packet->end; int first = 1; for (;;) { int c; if (p >= end) break; c = *p++; if (c == 0) { packet->cursor = p; return bp; } /* we don't expect label compression in QNAMEs */ if (c >= 64) break; if (first) first = 0; else bp = bprint_c(bp, bend, '.'); bp = bprint_b(bp, bend, (const char*) p, c); p += c; /* we rely on the bound check at the start * of the loop here */ } /* malformed data */ bp = bprint_s(bp, bend, "<MALFORMED>"); return bp; } static char* dnsPacket_bprintQR(DnsPacket* packet, char* p, char* end) { #define QQ(x) \ { DNS_TYPE_##x, #x } static const struct { const char* typeBytes; const char* typeString; } qTypes[] = {QQ(A), QQ(PTR), QQ(MX), QQ(AAAA), QQ(ALL), {NULL, NULL}}; int nn; const char* typeString = NULL; /* dump QNAME */ p = dnsPacket_bprintQName(packet, p, end); /* dump TYPE */ p = bprint_s(p, end, " ("); for (nn = 0; qTypes[nn].typeBytes != NULL; nn++) { if (_dnsPacket_checkBytes(packet, 2, qTypes[nn].typeBytes)) { typeString = qTypes[nn].typeString; break; } } if (typeString != NULL) p = bprint_s(p, end, typeString); else { int typeCode = _dnsPacket_readInt16(packet); p = bprint(p, end, "UNKNOWN-%d", typeCode); } p = bprint_c(p, end, ')'); /* skip CLASS */ _dnsPacket_skip(packet, 2); return p; } /* this function assumes the packet has already been checked */ static char* dnsPacket_bprintQuery(DnsPacket* packet, char* p, char* end) { int qdCount; if (packet->base[2] & 0x1) { p = bprint_s(p, end, "RECURSIVE "); } _dnsPacket_skip(packet, 4); qdCount = _dnsPacket_readInt16(packet); _dnsPacket_skip(packet, 6); for (; qdCount > 0; qdCount--) { p = dnsPacket_bprintQR(packet, p, end); } return p; } /** QUERY HASHING SUPPORT ** ** THE FOLLOWING CODE ASSUMES THAT THE INPUT PACKET HAS ALREADY Loading Loading @@ -1292,17 +1200,6 @@ static resolv_cache* resolv_cache_create() { return cache; } static void dump_query(const uint8_t* query, int querylen) { if (!WOULD_LOG(VERBOSE)) return; char temp[256], *p = temp, *end = p + sizeof(temp); DnsPacket pack[1]; _dnsPacket_init(pack, query, querylen); p = dnsPacket_bprintQuery(pack, p, end); LOG(VERBOSE) << __func__ << ": " << temp; } static void cache_dump_mru(Cache* cache) { char temp[512], *p = temp, *end = p + sizeof(temp); Entry* e; Loading Loading @@ -1385,7 +1282,7 @@ static void _cache_remove_oldest(Cache* cache) { return; } LOG(INFO) << __func__ << ": Cache full - removing oldest"; dump_query(oldest->query, oldest->querylen); res_pquery(oldest->query, oldest->querylen); _cache_remove_p(cache, lookup); } Loading Loading @@ -1430,7 +1327,7 @@ ResolvCacheStatus resolv_cache_lookup(unsigned netid, const void* query, int que Cache* cache; LOG(INFO) << __func__ << ": lookup"; dump_query((u_char*) query, querylen); res_pquery(reinterpret_cast<const u_char*>(query), querylen); /* we don't cache malformed queries */ if (!entry_init_key(&key, query, querylen)) { Loading Loading @@ -1494,7 +1391,7 @@ ResolvCacheStatus resolv_cache_lookup(unsigned netid, const void* query, int que /* remove stale entries here */ if (now >= e->expires) { LOG(INFO) << __func__ << ": NOT IN CACHE (STALE ENTRY " << *lookup << "DISCARDED)"; dump_query(e->query, e->querylen); res_pquery(e->query, e->querylen); _cache_remove_p(cache, lookup); return RESOLV_CACHE_NOTFOUND; } Loading Loading @@ -1541,10 +1438,10 @@ int resolv_cache_add(unsigned netid, const void* query, int querylen, const void } LOG(INFO) << __func__ << ": query:"; dump_query((u_char*)query, querylen); res_pquery((u_char*)answer, answerlen); if (kDumpData) { res_pquery(reinterpret_cast<const u_char*>(query), querylen); LOG(INFO) << __func__ << ": answer:"; res_pquery(reinterpret_cast<const u_char*>(answer), answerlen); if (kDumpData) { dump_bytes((u_char*)answer, answerlen); } Loading Loading
DnsProxyListener.cpp +4 −11 Original line number Diff line number Diff line Loading @@ -118,18 +118,11 @@ constexpr bool requestingUseLocalNameservers(unsigned flags) { return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0; } inline bool queryingViaTls(unsigned dns_netid) { // TODO: The simpler PrivateDnsStatus should suffice here. ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}}; gPrivateDnsConfiguration.getStatus(dns_netid, &privateDnsStatus); switch (static_cast<PrivateDnsMode>(privateDnsStatus.mode)) { bool queryingViaTls(unsigned dns_netid) { const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(dns_netid); switch (privateDnsStatus.mode) { case PrivateDnsMode::OPPORTUNISTIC: for (int i = 0; i < privateDnsStatus.numServers; i++) { if (privateDnsStatus.serverStatus[i].validation == Validation::success) { return true; } } return false; return !privateDnsStatus.validatedServers().empty(); case PrivateDnsMode::STRICT: return true; default: Loading
PrivateDnsConfiguration.cpp +4 −25 Original line number Diff line number Diff line Loading @@ -126,37 +126,13 @@ PrivateDnsStatus PrivateDnsConfiguration::getStatus(unsigned netId) { const auto netPair = mPrivateDnsTransports.find(netId); if (netPair != mPrivateDnsTransports.end()) { for (const auto& serverPair : netPair->second) { if (serverPair.second == Validation::success) { status.validatedServers.push_back(serverPair.first); } status.serversMap.emplace(serverPair.first, serverPair.second); } } return status; } void PrivateDnsConfiguration::getStatus(unsigned netId, ExternalPrivateDnsStatus* status) { std::lock_guard guard(mPrivateDnsLock); const auto mode = mPrivateDnsModes.find(netId); if (mode == mPrivateDnsModes.end()) return; status->mode = mode->second; const auto netPair = mPrivateDnsTransports.find(netId); if (netPair != mPrivateDnsTransports.end()) { int count = 0; for (const auto& serverPair : netPair->second) { status->serverStatus[count].ss = serverPair.first.ss; status->serverStatus[count].hostname = serverPair.first.name.empty() ? "" : serverPair.first.name.c_str(); status->serverStatus[count].validation = serverPair.second; count++; if (count >= MAXNS) break; // Lose the rest } status->numServers = count; } } void PrivateDnsConfiguration::clear(unsigned netId) { LOG(DEBUG) << "PrivateDnsConfiguration::clear(" << netId << ")"; std::lock_guard guard(mPrivateDnsLock); Loading Loading @@ -242,6 +218,9 @@ bool PrivateDnsConfiguration::recordPrivateDnsValidation(const DnsTlsServer& ser auto& tracker = netPair->second; auto serverPair = tracker.find(server); if (serverPair == tracker.end()) { // TODO: Consider not adding this server to the tracker since this server is not expected // to be one of the private DNS servers for this network now. This could prevent this // server from being included when dumping status. LOG(WARNING) << "Server " << addrToString(&server.ss) << " was removed during private DNS validation"; success = false; Loading
PrivateDnsConfiguration.h +16 −22 Original line number Diff line number Diff line Loading @@ -14,8 +14,7 @@ * limitations under the License. */ #ifndef NETD_RESOLV_PRIVATEDNSCONFIGURATION_H #define NETD_RESOLV_PRIVATEDNSCONFIGURATION_H #pragma once #include <list> #include <map> Loading @@ -37,31 +36,28 @@ enum class Validation : uint8_t { in_process, success, fail, unknown_server, unk struct PrivateDnsStatus { PrivateDnsMode mode; std::list<DnsTlsServer> validatedServers; }; // TODO: remove this C-style struct and use PrivateDnsStatus everywhere. struct ExternalPrivateDnsStatus { PrivateDnsMode mode; int numServers; struct PrivateDnsInfo { sockaddr_storage ss; const char* hostname; Validation validation; } serverStatus[MAXNS]; std::map<DnsTlsServer, Validation, AddressComparator> serversMap; std::list<DnsTlsServer> validatedServers() const { std::list<DnsTlsServer> servers; for (const auto& pair : serversMap) { if (pair.second == Validation::success) { servers.push_back(pair.first); } } return servers; } }; class PrivateDnsConfiguration { public: int set(int32_t netId, uint32_t mark, const std::vector<std::string>& servers, const std::string& name, const std::string& caCert); const std::string& name, const std::string& caCert) EXCLUDES(mPrivateDnsLock); PrivateDnsStatus getStatus(unsigned netId); PrivateDnsStatus getStatus(unsigned netId) EXCLUDES(mPrivateDnsLock); // DEPRECATED, use getStatus() above. void getStatus(unsigned netId, ExternalPrivateDnsStatus* status); void clear(unsigned netId); void clear(unsigned netId) EXCLUDES(mPrivateDnsLock); private: typedef std::map<DnsTlsServer, Validation, AddressComparator> PrivateDnsTracker; Loading @@ -88,5 +84,3 @@ extern PrivateDnsConfiguration gPrivateDnsConfiguration; } // namespace net } // namespace android #endif /* NETD_RESOLV_PRIVATEDNSCONFIGURATION_H */
ResolverController.cpp +10 −15 Original line number Diff line number Diff line Loading @@ -249,11 +249,9 @@ int ResolverController::getResolverInfo(int32_t netId, std::vector<std::string>* // Serialize the information for binder. ResolverStats::encodeAll(res_stats, stats); ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}}; gPrivateDnsConfiguration.getStatus(netId, &privateDnsStatus); for (int i = 0; i < privateDnsStatus.numServers; i++) { std::string tlsServer_str = addrToString(&(privateDnsStatus.serverStatus[i].ss)); tlsServers->push_back(std::move(tlsServer_str)); const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId); for (const auto& pair : privateDnsStatus.serversMap) { tlsServers->push_back(addrToString(&pair.first.ss)); } params->resize(IDnsResolver::RESOLVER_PARAMS_COUNT); Loading Loading @@ -344,20 +342,17 @@ void ResolverController::dump(DumpWriter& dw, unsigned netId) { } mDns64Configuration.dump(dw, netId); ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}}; gPrivateDnsConfiguration.getStatus(netId, &privateDnsStatus); const auto privateDnsStatus = gPrivateDnsConfiguration.getStatus(netId); dw.println("Private DNS mode: %s", getPrivateDnsModeString(privateDnsStatus.mode)); if (!privateDnsStatus.numServers) { if (privateDnsStatus.serversMap.size() == 0) { dw.println("No Private DNS servers configured"); } else { dw.println("Private DNS configuration (%u entries)", privateDnsStatus.numServers); dw.println("Private DNS configuration (%u entries)", static_cast<uint32_t>(privateDnsStatus.serversMap.size())); dw.incIndent(); for (int i = 0; i < privateDnsStatus.numServers; i++) { dw.println("%s name{%s} status{%s}", addrToString(&(privateDnsStatus.serverStatus[i].ss)).c_str(), privateDnsStatus.serverStatus[i].hostname, validationStatusToString(static_cast<Validation>( privateDnsStatus.serverStatus[i].validation))); for (const auto& pair : privateDnsStatus.serversMap) { dw.println("%s name{%s} status{%s}", addrToString(&pair.first.ss).c_str(), pair.first.name.c_str(), validationStatusToString(pair.second)); } dw.decIndent(); } Loading
res_cache.cpp +6 −109 Original line number Diff line number Diff line Loading @@ -581,98 +581,6 @@ static int _dnsPacket_checkQuery(DnsPacket* packet) { return 1; } /** QUERY DEBUGGING **/ static char* dnsPacket_bprintQName(DnsPacket* packet, char* bp, char* bend) { const uint8_t* p = packet->cursor; const uint8_t* end = packet->end; int first = 1; for (;;) { int c; if (p >= end) break; c = *p++; if (c == 0) { packet->cursor = p; return bp; } /* we don't expect label compression in QNAMEs */ if (c >= 64) break; if (first) first = 0; else bp = bprint_c(bp, bend, '.'); bp = bprint_b(bp, bend, (const char*) p, c); p += c; /* we rely on the bound check at the start * of the loop here */ } /* malformed data */ bp = bprint_s(bp, bend, "<MALFORMED>"); return bp; } static char* dnsPacket_bprintQR(DnsPacket* packet, char* p, char* end) { #define QQ(x) \ { DNS_TYPE_##x, #x } static const struct { const char* typeBytes; const char* typeString; } qTypes[] = {QQ(A), QQ(PTR), QQ(MX), QQ(AAAA), QQ(ALL), {NULL, NULL}}; int nn; const char* typeString = NULL; /* dump QNAME */ p = dnsPacket_bprintQName(packet, p, end); /* dump TYPE */ p = bprint_s(p, end, " ("); for (nn = 0; qTypes[nn].typeBytes != NULL; nn++) { if (_dnsPacket_checkBytes(packet, 2, qTypes[nn].typeBytes)) { typeString = qTypes[nn].typeString; break; } } if (typeString != NULL) p = bprint_s(p, end, typeString); else { int typeCode = _dnsPacket_readInt16(packet); p = bprint(p, end, "UNKNOWN-%d", typeCode); } p = bprint_c(p, end, ')'); /* skip CLASS */ _dnsPacket_skip(packet, 2); return p; } /* this function assumes the packet has already been checked */ static char* dnsPacket_bprintQuery(DnsPacket* packet, char* p, char* end) { int qdCount; if (packet->base[2] & 0x1) { p = bprint_s(p, end, "RECURSIVE "); } _dnsPacket_skip(packet, 4); qdCount = _dnsPacket_readInt16(packet); _dnsPacket_skip(packet, 6); for (; qdCount > 0; qdCount--) { p = dnsPacket_bprintQR(packet, p, end); } return p; } /** QUERY HASHING SUPPORT ** ** THE FOLLOWING CODE ASSUMES THAT THE INPUT PACKET HAS ALREADY Loading Loading @@ -1292,17 +1200,6 @@ static resolv_cache* resolv_cache_create() { return cache; } static void dump_query(const uint8_t* query, int querylen) { if (!WOULD_LOG(VERBOSE)) return; char temp[256], *p = temp, *end = p + sizeof(temp); DnsPacket pack[1]; _dnsPacket_init(pack, query, querylen); p = dnsPacket_bprintQuery(pack, p, end); LOG(VERBOSE) << __func__ << ": " << temp; } static void cache_dump_mru(Cache* cache) { char temp[512], *p = temp, *end = p + sizeof(temp); Entry* e; Loading Loading @@ -1385,7 +1282,7 @@ static void _cache_remove_oldest(Cache* cache) { return; } LOG(INFO) << __func__ << ": Cache full - removing oldest"; dump_query(oldest->query, oldest->querylen); res_pquery(oldest->query, oldest->querylen); _cache_remove_p(cache, lookup); } Loading Loading @@ -1430,7 +1327,7 @@ ResolvCacheStatus resolv_cache_lookup(unsigned netid, const void* query, int que Cache* cache; LOG(INFO) << __func__ << ": lookup"; dump_query((u_char*) query, querylen); res_pquery(reinterpret_cast<const u_char*>(query), querylen); /* we don't cache malformed queries */ if (!entry_init_key(&key, query, querylen)) { Loading Loading @@ -1494,7 +1391,7 @@ ResolvCacheStatus resolv_cache_lookup(unsigned netid, const void* query, int que /* remove stale entries here */ if (now >= e->expires) { LOG(INFO) << __func__ << ": NOT IN CACHE (STALE ENTRY " << *lookup << "DISCARDED)"; dump_query(e->query, e->querylen); res_pquery(e->query, e->querylen); _cache_remove_p(cache, lookup); return RESOLV_CACHE_NOTFOUND; } Loading Loading @@ -1541,10 +1438,10 @@ int resolv_cache_add(unsigned netid, const void* query, int querylen, const void } LOG(INFO) << __func__ << ": query:"; dump_query((u_char*)query, querylen); res_pquery((u_char*)answer, answerlen); if (kDumpData) { res_pquery(reinterpret_cast<const u_char*>(query), querylen); LOG(INFO) << __func__ << ": answer:"; res_pquery(reinterpret_cast<const u_char*>(answer), answerlen); if (kDumpData) { dump_bytes((u_char*)answer, answerlen); } Loading