1 /*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "DnsProxyListener.h"
18
19 #include <arpa/inet.h>
20 #include <dirent.h>
21 #include <errno.h>
22 #include <linux/if.h>
23 #include <math.h>
24 #include <net/if.h>
25 #include <netdb.h>
26 #include <netinet/in.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/socket.h>
30 #include <sys/types.h>
31
32 #define LOG_TAG "DnsProxyListener"
33
34 #include <algorithm>
35 #include <list>
36 #include <vector>
37
38 #include <android-base/stringprintf.h>
39 #include <android/multinetwork.h> // ResNsendFlags
40 #include <cutils/misc.h> // FIRST_APPLICATION_UID
41 #include <netdutils/InternetAddresses.h>
42 #include <netdutils/OperationLimiter.h>
43 #include <netdutils/ResponseCode.h>
44 #include <netdutils/Slice.h>
45 #include <netdutils/Stopwatch.h>
46 #include <netdutils/ThreadUtil.h>
47 #include <private/android_filesystem_config.h> // AID_SYSTEM
48 #include <statslog_resolv.h>
49 #include <sysutils/SocketClient.h>
50
51 #include "DnsResolver.h"
52 #include "NetdClient.h" // NETID_USE_LOCAL_NAMESERVERS
53 #include "NetdPermissions.h"
54 #include "PrivateDnsConfiguration.h"
55 #include "ResolverEventReporter.h"
56 #include "getaddrinfo.h"
57 #include "gethnamaddr.h"
58 #include "netd_resolv/stats.h" // RCODE_TIMEOUT
59 #include "res_send.h"
60 #include "resolv_private.h"
61 #include "stats.pb.h"
62
63 using aidl::android::net::metrics::INetdEventListener;
64 using android::net::NetworkDnsEventReported;
65
66 namespace android {
67
68 using netdutils::ResponseCode;
69 using netdutils::Stopwatch;
70
71 namespace net {
72 namespace {
73
74 // Limits the number of outstanding DNS queries by client UID.
75 constexpr int MAX_QUERIES_PER_UID = 256;
76
77 // Max packet size for answer, sync with getaddrinfo.c
78 constexpr int MAXPACKET = 8 * 1024;
79
80 android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
81
logArguments(int argc,char ** argv)82 void logArguments(int argc, char** argv) {
83 if (!WOULD_LOG(VERBOSE)) return;
84 for (int i = 0; i < argc; i++) {
85 LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
86 }
87 }
88
89 template<typename T>
tryThreadOrError(SocketClient * cli,T * handler)90 void tryThreadOrError(SocketClient* cli, T* handler) {
91 cli->incRef();
92
93 const int rval = netdutils::threadLaunch(handler);
94 if (rval == 0) {
95 // SocketClient decRef() happens in the handler's run() method.
96 return;
97 }
98
99 char* msg = nullptr;
100 asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
101 cli->sendMsg(ResponseCode::OperationFailed, msg, false);
102 free(msg);
103
104 delete handler;
105 cli->decRef();
106 }
107
checkAndClearUseLocalNameserversFlag(unsigned * netid)108 bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
109 if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
110 return false;
111 }
112 *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
113 return true;
114 }
115
requestingUseLocalNameservers(unsigned flags)116 constexpr bool requestingUseLocalNameservers(unsigned flags) {
117 return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
118 }
119
queryingViaTls(unsigned dns_netid)120 inline bool queryingViaTls(unsigned dns_netid) {
121 // TODO: The simpler PrivateDnsStatus should suffice here.
122 ExternalPrivateDnsStatus privateDnsStatus = {PrivateDnsMode::OFF, 0, {}};
123 gPrivateDnsConfiguration.getStatus(dns_netid, &privateDnsStatus);
124 switch (static_cast<PrivateDnsMode>(privateDnsStatus.mode)) {
125 case PrivateDnsMode::OPPORTUNISTIC:
126 for (int i = 0; i < privateDnsStatus.numServers; i++) {
127 if (privateDnsStatus.serverStatus[i].validation == Validation::success) {
128 return true;
129 }
130 }
131 return false;
132 case PrivateDnsMode::STRICT:
133 return true;
134 default:
135 return false;
136 }
137 }
138
hasPermissionToBypassPrivateDns(uid_t uid)139 bool hasPermissionToBypassPrivateDns(uid_t uid) {
140 static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
141 "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
142 if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
143 return true;
144 }
145
146 for (const char* const permission :
147 {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
148 PERM_MAINLINE_NETWORK_STACK}) {
149 if (gResNetdCallbacks.check_calling_permission(permission)) {
150 return true;
151 }
152 }
153 return false;
154 }
155
maybeFixupNetContext(android_net_context * ctx)156 void maybeFixupNetContext(android_net_context* ctx) {
157 if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
158 // Not permitted; clear the flag.
159 ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
160 }
161
162 if (!requestingUseLocalNameservers(ctx->flags)) {
163 // If we're not explicitly bypassing DNS-over-TLS servers, check whether
164 // DNS-over-TLS is in use as an indicator for when to use more modern
165 // DNS resolution mechanics.
166 if (queryingViaTls(ctx->dns_netid)) {
167 ctx->flags |= NET_CONTEXT_FLAG_USE_EDNS;
168 }
169 }
170 }
171
172 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
173 socklen_t addrlen);
174
extractResNsendAnswers(const uint8_t * answer,size_t anslen,int ipType,std::vector<std::string> * ip_addrs)175 int extractResNsendAnswers(const uint8_t* answer, size_t anslen, int ipType,
176 std::vector<std::string>* ip_addrs) {
177 int total_ip_addr_count = 0;
178 ns_msg handle;
179 if (ns_initparse((const uint8_t*) answer, anslen, &handle) < 0) {
180 return 0;
181 }
182 int ancount = ns_msg_count(handle, ns_s_an);
183 ns_rr rr;
184 for (int i = 0; i < ancount; i++) {
185 if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
186 continue;
187 }
188 const uint8_t* rdata = ns_rr_rdata(rr);
189 if (ipType == ns_t_a) {
190 sockaddr_in sin = {.sin_family = AF_INET};
191 memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
192 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
193 total_ip_addr_count++;
194 } else if (ipType == ns_t_aaaa) {
195 sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
196 memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
197 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
198 total_ip_addr_count++;
199 }
200 }
201
202 return total_ip_addr_count;
203 }
204
extractGetAddrInfoAnswers(const addrinfo * result,std::vector<std::string> * ip_addrs)205 int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
206 int total_ip_addr_count = 0;
207 if (result == nullptr) {
208 return 0;
209 }
210 for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
211 sockaddr* ai_addr = ai->ai_addr;
212 if (ai_addr) {
213 addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
214 total_ip_addr_count++;
215 }
216 }
217 return total_ip_addr_count;
218 }
219
extractGetHostByNameAnswers(const hostent * hp,std::vector<std::string> * ip_addrs)220 int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
221 int total_ip_addr_count = 0;
222 if (hp == nullptr) {
223 return 0;
224 }
225 if (hp->h_addrtype == AF_INET) {
226 in_addr** list = (in_addr**) hp->h_addr_list;
227 for (int i = 0; list[i] != nullptr; i++) {
228 sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
229 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin));
230 total_ip_addr_count++;
231 }
232 } else if (hp->h_addrtype == AF_INET6) {
233 in6_addr** list = (in6_addr**) hp->h_addr_list;
234 for (int i = 0; list[i] != nullptr; i++) {
235 sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
236 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6));
237 total_ip_addr_count++;
238 }
239 }
240 return total_ip_addr_count;
241 }
242
rcodeToAiError(int rcode)243 int rcodeToAiError(int rcode) {
244 switch (rcode) {
245 case NOERROR:
246 return 0;
247 case RCODE_TIMEOUT:
248 return NETD_RESOLV_TIMEOUT;
249 default:
250 return EAI_NODATA;
251 }
252 }
253
resNSendToAiError(int err,int rcode)254 int resNSendToAiError(int err, int rcode) {
255 if (err > 0) {
256 return rcodeToAiError(rcode);
257 }
258 if (err == -ETIMEDOUT) {
259 return NETD_RESOLV_TIMEOUT;
260 }
261 return EAI_SYSTEM;
262 }
263
264 template <typename IntegralType>
simpleStrtoul(const char * input,IntegralType * output,int base=10)265 bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) {
266 char* endPtr;
267 errno = 0;
268 auto result = strtoul(input, &endPtr, base);
269 // Check the length in order to ensure there is no "-" sign
270 if (!*input || *endPtr || (endPtr - input) != static_cast<ptrdiff_t>(strlen(input)) ||
271 (errno == ERANGE && (result == ULONG_MAX))) {
272 return false;
273 }
274 *output = result;
275 return true;
276 }
277
setQueryId(uint8_t * msg,size_t msgLen,uint16_t query_id)278 bool setQueryId(uint8_t* msg, size_t msgLen, uint16_t query_id) {
279 if (msgLen < sizeof(HEADER)) {
280 errno = EINVAL;
281 return false;
282 }
283 auto hp = reinterpret_cast<HEADER*>(msg);
284 hp->id = htons(query_id);
285 return true;
286 }
287
parseQuery(const uint8_t * msg,size_t msgLen,uint16_t * query_id,int * rr_type,std::string * rr_name)288 bool parseQuery(const uint8_t* msg, size_t msgLen, uint16_t* query_id, int* rr_type,
289 std::string* rr_name) {
290 ns_msg handle;
291 ns_rr rr;
292 if (ns_initparse((const uint8_t*)msg, msgLen, &handle) < 0 ||
293 ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
294 return false;
295 }
296 *query_id = ns_msg_id(handle);
297 *rr_name = ns_rr_name(rr);
298 *rr_type = ns_rr_type(rr);
299 return true;
300 }
301
reportDnsEvent(int eventType,const android_net_context & netContext,int latencyUs,int returnCode,const NetworkDnsEventReported & dnsEvent,const std::string & query_name,const std::vector<std::string> & ip_addrs={},int total_ip_addr_count=0)302 void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
303 int returnCode, const NetworkDnsEventReported& dnsEvent,
304 const std::string& query_name, const std::vector<std::string>& ip_addrs = {},
305 int total_ip_addr_count = 0) {
306 std::string dnsQueryStats = dnsEvent.dns_query_events().SerializeAsString();
307 char const* dnsQueryStatsBytes = dnsQueryStats.c_str();
308 stats::BytesField dnsQueryBytesField{dnsQueryStatsBytes, dnsQueryStats.size()};
309 android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED, eventType,
310 returnCode, latencyUs, dnsEvent.hints_ai_flags(),
311 dnsEvent.res_nsend_flags(), dnsEvent.network_type(),
312 dnsEvent.private_dns_modes(), dnsQueryBytesField);
313
314 const auto& listeners = ResolverEventReporter::getInstance().getListeners();
315 if (listeners.size() == 0) {
316 LOG(ERROR) << __func__
317 << ": DNS event not sent since no INetdEventListener receiver is available.";
318 return;
319 }
320 const int latencyMs = latencyUs / 1000;
321 for (const auto& it : listeners) {
322 it->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name, ip_addrs,
323 total_ip_addr_count, netContext.uid);
324 }
325 }
326
onlyIPv4Answers(const addrinfo * res)327 bool onlyIPv4Answers(const addrinfo* res) {
328 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
329
330 for (const addrinfo* ai = res; ai; ai = ai->ai_next)
331 if (ai->ai_family != AF_INET) return false;
332
333 return true;
334 }
335
isSpecialUseIPv4Address(const struct in_addr & ia)336 bool isSpecialUseIPv4Address(const struct in_addr& ia) {
337 const uint32_t addr = ntohl(ia.s_addr);
338
339 // Only check necessary IP ranges in RFC 5735 section 4
340 return ((addr & 0xff000000) == 0x00000000) || // "This" Network
341 ((addr & 0xff000000) == 0x7f000000) || // Loopback
342 ((addr & 0xffff0000) == 0xa9fe0000) || // Link Local
343 ((addr & 0xf0000000) == 0xe0000000) || // Multicast
344 (addr == INADDR_BROADCAST); // Limited Broadcast
345 }
346
isSpecialUseIPv4Address(const struct sockaddr * sa)347 bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
348 if (sa->sa_family != AF_INET) return false;
349
350 return isSpecialUseIPv4Address(((struct sockaddr_in*) sa)->sin_addr);
351 }
352
onlyNonSpecialUseIPv4Addresses(struct hostent * hp)353 bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
354 // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
355
356 if (hp->h_addrtype != AF_INET) return false;
357
358 for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
359 if (isSpecialUseIPv4Address(*(struct in_addr*) hp->h_addr_list[i])) return false;
360
361 return true;
362 }
363
onlyNonSpecialUseIPv4Addresses(const addrinfo * res)364 bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
365 // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
366
367 for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
368 if (ai->ai_family != AF_INET) return false;
369 if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
370 }
371
372 return true;
373 }
374
logDnsQueryResult(const struct hostent * hp)375 void logDnsQueryResult(const struct hostent* hp) {
376 if (!WOULD_LOG(DEBUG)) return;
377 if (hp == nullptr) return;
378
379 LOG(DEBUG) << __func__ << ": DNS records:";
380 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
381 char ip_addr[INET6_ADDRSTRLEN];
382 if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
383 LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
384 } else {
385 PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
386 }
387 }
388 }
389
logDnsQueryResult(const addrinfo * res)390 void logDnsQueryResult(const addrinfo* res) {
391 if (!WOULD_LOG(DEBUG)) return;
392 if (res == nullptr) return;
393
394 int i;
395 const addrinfo* ai;
396 LOG(DEBUG) << __func__ << ": DNS records:";
397 for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
398 if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
399 char ip_addr[INET6_ADDRSTRLEN];
400 int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
401 NI_NUMERICHOST);
402 if (!ret) {
403 LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
404 << " " << ai->ai_socktype << " " << ai->ai_protocol;
405 } else {
406 LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
407 }
408 }
409 }
410
isValidNat64Prefix(const netdutils::IPPrefix prefix)411 bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
412 if (prefix.family() != AF_INET6) {
413 LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
414 return false;
415 }
416 if (prefix.length() != 96) {
417 LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << prefix.length();
418 return false;
419 }
420 return true;
421 }
422
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,struct hostent * hp)423 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
424 if (hp == nullptr) return false;
425 if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
426 if (!isValidNat64Prefix(prefix)) return false;
427
428 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
429 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
430 for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
431 struct in_addr iaOriginal = *(struct in_addr*) hp->h_addr_list[i];
432 struct in6_addr* ia6 = (struct in6_addr*) hp->h_addr_list[i];
433 memset(ia6, 0, sizeof(struct in6_addr));
434
435 // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
436 // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
437 // system/netd/resolv/sethostent.cpp.
438 *ia6 = v6prefix->sin6_addr;
439 ia6->s6_addr32[3] = iaOriginal.s_addr;
440
441 if (WOULD_LOG(DEBUG)) {
442 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
443 inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
444 LOG(DEBUG) << __func__ << ": DNS A record: " << buf;
445 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
446 LOG(DEBUG) << __func__ << ": NAT64 prefix: " << buf;
447 inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
448 LOG(DEBUG) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
449 }
450 }
451 hp->h_addrtype = AF_INET6;
452 hp->h_length = sizeof(in6_addr);
453
454 logDnsQueryResult(hp);
455 return true;
456 }
457
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,addrinfo * result)458 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo* result) {
459 if (result == nullptr) return false;
460 if (!onlyNonSpecialUseIPv4Addresses(result)) return false;
461 if (!isValidNat64Prefix(prefix)) return false;
462
463 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
464 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
465 for (addrinfo* ai = result; ai; ai = ai->ai_next) {
466 struct sockaddr_in sinOriginal = *(struct sockaddr_in*) ai->ai_addr;
467 struct sockaddr_in6* sin6 = (struct sockaddr_in6*) ai->ai_addr;
468 memset(sin6, 0, sizeof(sockaddr_in6));
469
470 // Synthesize /96 NAT64 prefix in place. The space has reserved by get_ai() in
471 // system/netd/resolv/getaddrinfo.cpp.
472 sin6->sin6_addr = v6prefix->sin6_addr;
473 sin6->sin6_addr.s6_addr32[3] = sinOriginal.sin_addr.s_addr;
474 sin6->sin6_family = AF_INET6;
475 sin6->sin6_port = sinOriginal.sin_port;
476 ai->ai_addrlen = sizeof(struct sockaddr_in6);
477 ai->ai_family = AF_INET6;
478
479 if (WOULD_LOG(DEBUG)) {
480 char buf[INET6_ADDRSTRLEN]; // big enough for either IPv4 or IPv6
481 inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
482 LOG(DEBUG) << __func__ << ": DNS A record: " << buf;
483 inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
484 LOG(DEBUG) << __func__ << ": NAT64 prefix: " << buf;
485 inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
486 LOG(DEBUG) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
487 }
488 }
489 logDnsQueryResult(result);
490 return true;
491 }
492
getDns64Prefix(unsigned netId,netdutils::IPPrefix * prefix)493 bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
494 return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
495 }
496
497 } // namespace
498
DnsProxyListener()499 DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
500 registerCmd(new GetAddrInfoCmd());
501 registerCmd(new GetHostByAddrCmd());
502 registerCmd(new GetHostByNameCmd());
503 registerCmd(new ResNSendCommand());
504 registerCmd(new GetDnsNetIdCommand());
505 }
506
GetAddrInfoHandler(SocketClient * c,char * host,char * service,addrinfo * hints,const android_net_context & netcontext)507 DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, char* host, char* service,
508 addrinfo* hints,
509 const android_net_context& netcontext)
510 : mClient(c), mHost(host), mService(service), mHints(hints), mNetContext(netcontext) {}
511
~GetAddrInfoHandler()512 DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() {
513 free(mHost);
514 free(mService);
515 free(mHints);
516 }
517
sendBE32(SocketClient * c,uint32_t data)518 static bool sendBE32(SocketClient* c, uint32_t data) {
519 uint32_t be_data = htonl(data);
520 return c->sendData(&be_data, sizeof(be_data)) == 0;
521 }
522
523 // Sends 4 bytes of big-endian length, followed by the data.
524 // Returns true on success.
sendLenAndData(SocketClient * c,const int len,const void * data)525 static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
526 return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
527 }
528
529 // Returns true on success
sendhostent(SocketClient * c,hostent * hp)530 static bool sendhostent(SocketClient* c, hostent* hp) {
531 bool success = true;
532 int i;
533 if (hp->h_name != nullptr) {
534 success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name);
535 } else {
536 success &= sendLenAndData(c, 0, "") == 0;
537 }
538
539 for (i=0; hp->h_aliases[i] != nullptr; i++) {
540 success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]);
541 }
542 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
543
544 uint32_t buf = htonl(hp->h_addrtype);
545 success &= c->sendData(&buf, sizeof(buf)) == 0;
546
547 buf = htonl(hp->h_length);
548 success &= c->sendData(&buf, sizeof(buf)) == 0;
549
550 for (i=0; hp->h_addr_list[i] != nullptr; i++) {
551 success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
552 }
553 success &= sendLenAndData(c, 0, ""); // null to indicate we're done
554 return success;
555 }
556
sendaddrinfo(SocketClient * c,addrinfo * ai)557 static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
558 // struct addrinfo {
559 // int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
560 // int ai_family; /* PF_xxx */
561 // int ai_socktype; /* SOCK_xxx */
562 // int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
563 // socklen_t ai_addrlen; /* length of ai_addr */
564 // char *ai_canonname; /* canonical name for hostname */
565 // struct sockaddr *ai_addr; /* binary address */
566 // struct addrinfo *ai_next; /* next structure in linked list */
567 // };
568
569 // Write the struct piece by piece because we might be a 64-bit netd
570 // talking to a 32-bit process.
571 bool success =
572 sendBE32(c, ai->ai_flags) &&
573 sendBE32(c, ai->ai_family) &&
574 sendBE32(c, ai->ai_socktype) &&
575 sendBE32(c, ai->ai_protocol);
576 if (!success) {
577 return false;
578 }
579
580 // ai_addrlen and ai_addr.
581 if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
582 return false;
583 }
584
585 // strlen(ai_canonname) and ai_canonname.
586 if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
587 return false;
588 }
589
590 return true;
591 }
592
doDns64Synthesis(int32_t * rv,addrinfo ** res)593 void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res) {
594 if (mHost == nullptr) return;
595
596 const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
597 const bool unspecWantedButNoIPv6 =
598 ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
599
600 if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
601 return;
602 }
603
604 netdutils::IPPrefix prefix{};
605 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
606 return;
607 }
608
609 if (ipv6WantedButNoData) {
610 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
611 const uid_t uid = mClient->getUid();
612 if (queryLimiter.start(uid)) {
613 mHints->ai_family = AF_INET;
614 // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
615 // DNS lookup is failed with error EAI_NODATA.
616 *rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, res);
617 queryLimiter.finish(uid);
618 if (*rv) {
619 *rv = EAI_NODATA; // return original error code
620 return;
621 }
622 } else {
623 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
624 return;
625 }
626 }
627
628 if (!synthesizeNat64PrefixWithARecord(prefix, *res)) {
629 if (ipv6WantedButNoData) {
630 // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
631 // don't return the IPv4 answers.
632 *rv = EAI_NODATA; // return original error code
633 if (*res) {
634 freeaddrinfo(*res);
635 *res = nullptr;
636 }
637 }
638 }
639 }
640
run()641 void DnsProxyListener::GetAddrInfoHandler::run() {
642 LOG(DEBUG) << "GetAddrInfoHandler::run: {" << mNetContext.app_netid << " "
643 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
644 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
645
646 addrinfo* result = nullptr;
647 Stopwatch s;
648 maybeFixupNetContext(&mNetContext);
649 const uid_t uid = mClient->getUid();
650 int32_t rv = 0;
651 NetworkDnsEventReported dnsEvent;
652 if (queryLimiter.start(uid)) {
653 rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result);
654 queryLimiter.finish(uid);
655 } else {
656 // Note that this error code is currently not passed down to the client.
657 // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
658 rv = EAI_MEMORY;
659 LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
660 << ", max concurrent queries reached";
661 }
662
663 doDns64Synthesis(&rv, &result);
664 const int latencyUs = int(s.timeTakenUs());
665
666 if (rv) {
667 // getaddrinfo failed
668 mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
669 } else {
670 bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
671 addrinfo* ai = result;
672 while (ai && success) {
673 success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
674 ai = ai->ai_next;
675 }
676 success = success && sendBE32(mClient, 0);
677 if (!success) {
678 LOG(WARNING) << "GetAddrInfoHandler::run: Error writing DNS result to client";
679 }
680 }
681 std::vector<std::string> ip_addrs;
682 const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
683 reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, dnsEvent,
684 mHost, ip_addrs, total_ip_addr_count);
685 freeaddrinfo(result);
686 mClient->decRef();
687 }
688
689 namespace {
690
addIpAddrWithinLimit(std::vector<std::string> * ip_addrs,const sockaddr * addr,socklen_t addrlen)691 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
692 socklen_t addrlen) {
693 // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
694 // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
695 // some addresses didn't get logged.
696 if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
697 char ip_addr[INET6_ADDRSTRLEN];
698 if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
699 ip_addrs->push_back(std::string(ip_addr));
700 }
701 }
702 }
703
704 } // namespace
705
GetAddrInfoCmd()706 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
707
runCommand(SocketClient * cli,int argc,char ** argv)708 int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli,
709 int argc, char **argv) {
710 logArguments(argc, argv);
711
712 if (argc != 8) {
713 char* msg = nullptr;
714 asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc);
715 LOG(WARNING) << "GetAddrInfoCmd::runCommand: " << (msg ? msg : "null");
716 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
717 free(msg);
718 return -1;
719 }
720
721 char* name = argv[1];
722 if (strcmp("^", name) == 0) {
723 name = nullptr;
724 } else {
725 name = strdup(name);
726 }
727
728 char* service = argv[2];
729 if (strcmp("^", service) == 0) {
730 service = nullptr;
731 } else {
732 service = strdup(service);
733 }
734
735 addrinfo* hints = nullptr;
736 int ai_flags = strtol(argv[3], nullptr, 10);
737 int ai_family = strtol(argv[4], nullptr, 10);
738 int ai_socktype = strtol(argv[5], nullptr, 10);
739 int ai_protocol = strtol(argv[6], nullptr, 10);
740 unsigned netId = strtoul(argv[7], nullptr, 10);
741 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
742 const uid_t uid = cli->getUid();
743
744 android_net_context netcontext;
745 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
746
747 if (useLocalNameservers) {
748 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
749 }
750
751 if (ai_flags != -1 || ai_family != -1 ||
752 ai_socktype != -1 || ai_protocol != -1) {
753 hints = (addrinfo*) calloc(1, sizeof(addrinfo));
754 hints->ai_flags = ai_flags;
755 hints->ai_family = ai_family;
756 hints->ai_socktype = ai_socktype;
757 hints->ai_protocol = ai_protocol;
758 }
759
760 DnsProxyListener::GetAddrInfoHandler* handler =
761 new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext);
762 tryThreadOrError(cli, handler);
763 return 0;
764 }
765
766 /*******************************************************
767 * ResNSendCommand *
768 *******************************************************/
ResNSendCommand()769 DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
770
runCommand(SocketClient * cli,int argc,char ** argv)771 int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
772 logArguments(argc, argv);
773
774 const uid_t uid = cli->getUid();
775 if (argc != 4) {
776 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
777 << ", invalid number of arguments to resnsend: " << argc;
778 sendBE32(cli, -EINVAL);
779 return -1;
780 }
781
782 unsigned netId;
783 if (!simpleStrtoul(argv[1], &netId)) {
784 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
785 << ", invalid netId";
786 sendBE32(cli, -EINVAL);
787 return -1;
788 }
789
790 uint32_t flags;
791 if (!simpleStrtoul(argv[2], &flags)) {
792 LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
793 << ", invalid flags";
794 sendBE32(cli, -EINVAL);
795 return -1;
796 }
797
798 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
799
800 android_net_context netcontext;
801 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
802
803 if (useLocalNameservers) {
804 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
805 }
806
807 DnsProxyListener::ResNSendHandler* handler =
808 new DnsProxyListener::ResNSendHandler(cli, argv[3], flags, netcontext);
809 tryThreadOrError(cli, handler);
810 return 0;
811 }
812
ResNSendHandler(SocketClient * c,std::string msg,uint32_t flags,const android_net_context & netcontext)813 DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
814 const android_net_context& netcontext)
815 : mClient(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
816
~ResNSendHandler()817 DnsProxyListener::ResNSendHandler::~ResNSendHandler() {
818 mClient->decRef();
819 }
820
run()821 void DnsProxyListener::ResNSendHandler::run() {
822 LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
823 << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
824 << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
825
826 Stopwatch s;
827 maybeFixupNetContext(&mNetContext);
828
829 // Decode
830 std::vector<uint8_t> msg(MAXPACKET, 0);
831
832 // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
833 int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
834 if (msgLen == -1) {
835 // Decode fail
836 sendBE32(mClient, -EILSEQ);
837 return;
838 }
839
840 const uid_t uid = mClient->getUid();
841 int rr_type = 0;
842 std::string rr_name;
843 uint16_t original_query_id = 0;
844
845 // TODO: Handle the case which is msg contains more than one query
846 if (!parseQuery(msg.data(), msgLen, &original_query_id, &rr_type, &rr_name) ||
847 !setQueryId(msg.data(), msgLen, arc4random_uniform(65536))) {
848 // If the query couldn't be parsed, block the request.
849 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
850 sendBE32(mClient, -EINVAL);
851 return;
852 }
853
854 // Send DNS query
855 std::vector<uint8_t> ansBuf(MAXPACKET, 0);
856 int arcode, nsendAns = -1;
857 NetworkDnsEventReported dnsEvent;
858 if (queryLimiter.start(uid)) {
859 nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET,
860 &arcode, static_cast<ResNsendFlags>(mFlags));
861 queryLimiter.finish(uid);
862 } else {
863 LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
864 << ", max concurrent queries reached";
865 nsendAns = -EBUSY;
866 }
867
868 const int latencyUs = int(s.timeTakenUs());
869
870 // Fail, send -errno
871 if (nsendAns < 0) {
872 sendBE32(mClient, nsendAns);
873 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
874 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
875 resNSendToAiError(nsendAns, arcode), dnsEvent, rr_name);
876 }
877 return;
878 }
879
880 // Send rcode
881 if (!sendBE32(mClient, arcode)) {
882 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid;
883 return;
884 }
885
886 // Restore query id and send answer
887 if (!setQueryId(ansBuf.data(), nsendAns, original_query_id) ||
888 !sendLenAndData(mClient, nsendAns, ansBuf.data())) {
889 PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid;
890 return;
891 }
892
893 if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
894 std::vector<std::string> ip_addrs;
895 const int total_ip_addr_count =
896 extractResNsendAnswers((uint8_t*) ansBuf.data(), nsendAns, rr_type, &ip_addrs);
897 reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
898 resNSendToAiError(nsendAns, arcode), dnsEvent, rr_name, ip_addrs,
899 total_ip_addr_count);
900 }
901 }
902
903 namespace {
904
sendCodeAndBe32(SocketClient * c,int code,int data)905 bool sendCodeAndBe32(SocketClient* c, int code, int data) {
906 return !c->sendCode(code) && sendBE32(c, data);
907 }
908
909 } // namespace
910
911 /*******************************************************
912 * GetDnsNetId *
913 *******************************************************/
GetDnsNetIdCommand()914 DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}
915
runCommand(SocketClient * cli,int argc,char ** argv)916 int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
917 logArguments(argc, argv);
918
919 const uid_t uid = cli->getUid();
920 if (argc != 2) {
921 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
922 << ", invalid number of arguments to getdnsnetid: " << argc;
923 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
924 return -1;
925 }
926
927 unsigned netId;
928 if (!simpleStrtoul(argv[1], &netId)) {
929 LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
930 << ", invalid netId";
931 sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
932 return -1;
933 }
934
935 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
936 android_net_context netcontext;
937 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
938
939 if (useLocalNameservers) {
940 netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
941 }
942
943 return sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid) ? 0 : -1;
944 }
945
946 /*******************************************************
947 * GetHostByName *
948 *******************************************************/
GetHostByNameCmd()949 DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
950
runCommand(SocketClient * cli,int argc,char ** argv)951 int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli,
952 int argc, char **argv) {
953 logArguments(argc, argv);
954
955 if (argc != 4) {
956 char* msg = nullptr;
957 asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
958 LOG(WARNING) << "GetHostByNameCmd::runCommand: " << (msg ? msg : "null");
959 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
960 free(msg);
961 return -1;
962 }
963
964 uid_t uid = cli->getUid();
965 unsigned netId = strtoul(argv[1], nullptr, 10);
966 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
967 char* name = argv[2];
968 int af = strtol(argv[3], nullptr, 10);
969
970 if (strcmp(name, "^") == 0) {
971 name = nullptr;
972 } else {
973 name = strdup(name);
974 }
975
976 android_net_context netcontext;
977 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
978
979 if (useLocalNameservers) {
980 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
981 }
982
983 DnsProxyListener::GetHostByNameHandler* handler =
984 new DnsProxyListener::GetHostByNameHandler(cli, name, af, netcontext);
985 tryThreadOrError(cli, handler);
986 return 0;
987 }
988
GetHostByNameHandler(SocketClient * c,char * name,int af,const android_net_context & netcontext)989 DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, char* name, int af,
990 const android_net_context& netcontext)
991 : mClient(c), mName(name), mAf(af), mNetContext(netcontext) {}
992
~GetHostByNameHandler()993 DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() {
994 free(mName);
995 }
996
doDns64Synthesis(int32_t * rv,struct hostent ** hpp)997 void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, struct hostent** hpp) {
998 // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
999 // family AF_INET or AF_INET6.
1000 const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
1001
1002 if (!ipv6WantedButNoData) {
1003 return;
1004 }
1005
1006 netdutils::IPPrefix prefix{};
1007 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1008 return;
1009 }
1010
1011 // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
1012 const uid_t uid = mClient->getUid();
1013 if (queryLimiter.start(uid)) {
1014 *rv = android_gethostbynamefornetcontext(mName, AF_INET, &mNetContext, hpp);
1015 queryLimiter.finish(uid);
1016 if (*rv) {
1017 *rv = EAI_NODATA; // return original error code
1018 return;
1019 }
1020 } else {
1021 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
1022 return;
1023 }
1024
1025 if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
1026 // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
1027 // don't return the IPv4 answers.
1028 *hpp = nullptr;
1029 }
1030 }
1031
run()1032 void DnsProxyListener::GetHostByNameHandler::run() {
1033 Stopwatch s;
1034 maybeFixupNetContext(&mNetContext);
1035 const uid_t uid = mClient->getUid();
1036 hostent* hp = nullptr;
1037 int32_t rv = 0;
1038 NetworkDnsEventReported dnsEvent;
1039 if (queryLimiter.start(uid)) {
1040 rv = android_gethostbynamefornetcontext(mName, mAf, &mNetContext, &hp);
1041 queryLimiter.finish(uid);
1042 } else {
1043 rv = EAI_MEMORY;
1044 LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
1045 << ", max concurrent queries reached";
1046 }
1047
1048 doDns64Synthesis(&rv, &hp);
1049 const int latencyUs = lround(s.timeTakenUs());
1050 LOG(DEBUG) << "GetHostByNameHandler::run: errno: " << (hp ? "success" : strerror(errno));
1051
1052 bool success = true;
1053 if (hp) {
1054 // hp is not nullptr iff. rv is 0.
1055 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1056 success &= sendhostent(mClient, hp);
1057 } else {
1058 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1059 }
1060
1061 if (!success) {
1062 LOG(WARNING) << "GetHostByNameHandler::run: Error writing DNS result to client";
1063 }
1064
1065 std::vector<std::string> ip_addrs;
1066 const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
1067 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, dnsEvent,
1068 mName, ip_addrs, total_ip_addr_count);
1069 mClient->decRef();
1070 }
1071
1072
1073 /*******************************************************
1074 * GetHostByAddr *
1075 *******************************************************/
GetHostByAddrCmd()1076 DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
1077
runCommand(SocketClient * cli,int argc,char ** argv)1078 int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli,
1079 int argc, char **argv) {
1080 logArguments(argc, argv);
1081
1082 if (argc != 5) {
1083 char* msg = nullptr;
1084 asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
1085 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
1086 cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1087 free(msg);
1088 return -1;
1089 }
1090
1091 char* addrStr = argv[1];
1092 int addrLen = strtol(argv[2], nullptr, 10);
1093 int addrFamily = strtol(argv[3], nullptr, 10);
1094 uid_t uid = cli->getUid();
1095 unsigned netId = strtoul(argv[4], nullptr, 10);
1096 const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1097
1098 void* addr = malloc(sizeof(in6_addr));
1099 errno = 0;
1100 int result = inet_pton(addrFamily, addrStr, addr);
1101 if (result <= 0) {
1102 char* msg = nullptr;
1103 asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
1104 LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
1105 cli->sendMsg(ResponseCode::OperationFailed, msg, false);
1106 free(addr);
1107 free(msg);
1108 return -1;
1109 }
1110
1111 android_net_context netcontext;
1112 gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1113
1114 if (useLocalNameservers) {
1115 netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1116 }
1117
1118 DnsProxyListener::GetHostByAddrHandler* handler = new DnsProxyListener::GetHostByAddrHandler(
1119 cli, addr, addrLen, addrFamily, netcontext);
1120 tryThreadOrError(cli, handler);
1121 return 0;
1122 }
1123
GetHostByAddrHandler(SocketClient * c,void * address,int addressLen,int addressFamily,const android_net_context & netcontext)1124 DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, void* address,
1125 int addressLen, int addressFamily,
1126 const android_net_context& netcontext)
1127 : mClient(c),
1128 mAddress(address),
1129 mAddressLen(addressLen),
1130 mAddressFamily(addressFamily),
1131 mNetContext(netcontext) {}
1132
~GetHostByAddrHandler()1133 DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() {
1134 free(mAddress);
1135 }
1136
doDns64ReverseLookup(struct hostent ** hpp)1137 void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(struct hostent** hpp) {
1138 if (*hpp != nullptr || mAddressFamily != AF_INET6 || !mAddress) {
1139 return;
1140 }
1141
1142 netdutils::IPPrefix prefix{};
1143 if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1144 return;
1145 }
1146
1147 if (!isValidNat64Prefix(prefix)) {
1148 return;
1149 }
1150
1151 struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
1152 struct sockaddr_in6* v6prefix = (struct sockaddr_in6*) &ss;
1153 struct in6_addr v6addr = *(in6_addr*) mAddress;
1154 // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
1155 if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
1156 (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
1157 (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
1158 return;
1159 }
1160
1161 const uid_t uid = mClient->getUid();
1162 if (queryLimiter.start(uid)) {
1163 // Remove NAT64 prefix and do reverse DNS query
1164 struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
1165 android_gethostbyaddrfornetcontext(&v4addr, sizeof(v4addr), AF_INET, &mNetContext, hpp);
1166 queryLimiter.finish(uid);
1167 if (*hpp) {
1168 // Replace IPv4 address with original queried IPv6 address in place. The space has
1169 // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
1170 // system/netd/resolv/gethnamaddr.cpp.
1171 // Note that android_gethostbyaddrfornetcontext returns only one entry in result.
1172 memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
1173 (*hpp)->h_addrtype = AF_INET6;
1174 (*hpp)->h_length = sizeof(struct in6_addr);
1175 }
1176 } else {
1177 LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
1178 }
1179 }
1180
run()1181 void DnsProxyListener::GetHostByAddrHandler::run() {
1182 Stopwatch s;
1183 maybeFixupNetContext(&mNetContext);
1184 const uid_t uid = mClient->getUid();
1185 hostent* hp = nullptr;
1186 int32_t rv = 0;
1187 NetworkDnsEventReported dnsEvent;
1188 if (queryLimiter.start(uid)) {
1189 rv = android_gethostbyaddrfornetcontext(mAddress, mAddressLen, mAddressFamily,
1190 &mNetContext, &hp);
1191 queryLimiter.finish(uid);
1192 } else {
1193 rv = EAI_MEMORY;
1194 LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
1195 << ", max concurrent queries reached";
1196 }
1197
1198 doDns64ReverseLookup(&hp);
1199 const int latencyUs = int(s.timeTakenUs());
1200
1201 LOG(DEBUG) << "GetHostByAddrHandler::run: result: " << (hp ? "success" : gai_strerror(rv));
1202
1203 bool success = true;
1204 if (hp) {
1205 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1206 success &= sendhostent(mClient, hp);
1207 } else {
1208 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1209 }
1210
1211 if (!success) {
1212 LOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client";
1213 }
1214
1215 reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, dnsEvent,
1216 (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
1217 mClient->decRef();
1218 }
1219
1220 } // namespace net
1221 } // namespace android
1222