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 <arpa/inet.h> 18 #include <dirent.h> 19 #include <errno.h> 20 #include <linux/if.h> 21 #include <math.h> 22 #include <netdb.h> 23 #include <netinet/in.h> 24 #include <stdlib.h> 25 #include <sys/socket.h> 26 #include <sys/types.h> 27 #include <string.h> 28 #include <pthread.h> 29 #include <resolv_netid.h> 30 #include <net/if.h> 31 32 #define LOG_TAG "DnsProxyListener" 33 #define DBG 0 34 #define VDBG 0 35 36 #include <chrono> 37 #include <vector> 38 39 #include <cutils/log.h> 40 #include <utils/String16.h> 41 #include <sysutils/SocketClient.h> 42 43 #include "Fwmark.h" 44 #include "DnsProxyListener.h" 45 #include "NetdConstants.h" 46 #include "NetworkController.h" 47 #include "ResponseCode.h" 48 #include "Stopwatch.h" 49 #include "android/net/metrics/INetdEventListener.h" 50 51 using android::String16; 52 using android::net::metrics::INetdEventListener; 53 54 namespace android { 55 namespace net { 56 57 namespace { 58 59 template<typename T> 60 void* threadMain(void* obj) { 61 std::unique_ptr<T> handler(reinterpret_cast<T*>(obj)); 62 handler->run(); 63 return nullptr; 64 } 65 66 struct scoped_pthread_attr { 67 scoped_pthread_attr() { pthread_attr_init(&attr); } 68 ~scoped_pthread_attr() { pthread_attr_destroy(&attr); } 69 70 int detach() { 71 return pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 72 } 73 74 pthread_attr_t attr; 75 }; 76 77 template<typename T> 78 int threadLaunch(T* self) { 79 if (self == nullptr) { return -EINVAL;} 80 81 scoped_pthread_attr scoped_attr; 82 83 int rval = scoped_attr.detach(); 84 if (rval != 0) { return -errno; } 85 86 pthread_t thread; 87 rval = pthread_create(&thread, &scoped_attr.attr, &threadMain<T>, self); 88 if (rval != 0) { 89 ALOGW("pthread_create failed: %d", errno); 90 return -errno; 91 } 92 93 return rval; 94 } 95 96 template<typename T> 97 void tryThreadOrError(SocketClient* cli, T* handler) { 98 cli->incRef(); 99 100 const int rval = threadLaunch(handler); 101 if (rval == 0) { 102 // SocketClient decRef() happens in the handler's run() method. 103 return; 104 } 105 106 char* msg = NULL; 107 asprintf(&msg, "%s (%d)", strerror(-rval), -rval); 108 cli->sendMsg(ResponseCode::OperationFailed, msg, false); 109 free(msg); 110 111 delete handler; 112 cli->decRef(); 113 } 114 115 } // namespace 116 117 DnsProxyListener::DnsProxyListener(const NetworkController* netCtrl, EventReporter* eventReporter) : 118 FrameworkListener("dnsproxyd"), mNetCtrl(netCtrl), mEventReporter(eventReporter) { 119 registerCmd(new GetAddrInfoCmd(this)); 120 registerCmd(new GetHostByAddrCmd(this)); 121 registerCmd(new GetHostByNameCmd(this)); 122 } 123 124 DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler( 125 SocketClient *c, char* host, char* service, struct addrinfo* hints, 126 const struct android_net_context& netcontext, const int reportingLevel, 127 const android::sp<android::net::metrics::INetdEventListener>& netdEventListener) 128 : mClient(c), 129 mHost(host), 130 mService(service), 131 mHints(hints), 132 mNetContext(netcontext), 133 mReportingLevel(reportingLevel), 134 mNetdEventListener(netdEventListener) { 135 } 136 137 DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { 138 free(mHost); 139 free(mService); 140 free(mHints); 141 } 142 143 static bool sendBE32(SocketClient* c, uint32_t data) { 144 uint32_t be_data = htonl(data); 145 return c->sendData(&be_data, sizeof(be_data)) == 0; 146 } 147 148 // Sends 4 bytes of big-endian length, followed by the data. 149 // Returns true on success. 150 static bool sendLenAndData(SocketClient* c, const int len, const void* data) { 151 return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0); 152 } 153 154 // Returns true on success 155 static bool sendhostent(SocketClient *c, struct hostent *hp) { 156 bool success = true; 157 int i; 158 if (hp->h_name != NULL) { 159 success &= sendLenAndData(c, strlen(hp->h_name)+1, hp->h_name); 160 } else { 161 success &= sendLenAndData(c, 0, "") == 0; 162 } 163 164 for (i=0; hp->h_aliases[i] != NULL; i++) { 165 success &= sendLenAndData(c, strlen(hp->h_aliases[i])+1, hp->h_aliases[i]); 166 } 167 success &= sendLenAndData(c, 0, ""); // null to indicate we're done 168 169 uint32_t buf = htonl(hp->h_addrtype); 170 success &= c->sendData(&buf, sizeof(buf)) == 0; 171 172 buf = htonl(hp->h_length); 173 success &= c->sendData(&buf, sizeof(buf)) == 0; 174 175 for (i=0; hp->h_addr_list[i] != NULL; i++) { 176 success &= sendLenAndData(c, 16, hp->h_addr_list[i]); 177 } 178 success &= sendLenAndData(c, 0, ""); // null to indicate we're done 179 return success; 180 } 181 182 static bool sendaddrinfo(SocketClient* c, struct addrinfo* ai) { 183 // struct addrinfo { 184 // int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ 185 // int ai_family; /* PF_xxx */ 186 // int ai_socktype; /* SOCK_xxx */ 187 // int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ 188 // socklen_t ai_addrlen; /* length of ai_addr */ 189 // char *ai_canonname; /* canonical name for hostname */ 190 // struct sockaddr *ai_addr; /* binary address */ 191 // struct addrinfo *ai_next; /* next structure in linked list */ 192 // }; 193 194 // Write the struct piece by piece because we might be a 64-bit netd 195 // talking to a 32-bit process. 196 bool success = 197 sendBE32(c, ai->ai_flags) && 198 sendBE32(c, ai->ai_family) && 199 sendBE32(c, ai->ai_socktype) && 200 sendBE32(c, ai->ai_protocol); 201 if (!success) { 202 return false; 203 } 204 205 // ai_addrlen and ai_addr. 206 if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) { 207 return false; 208 } 209 210 // strlen(ai_canonname) and ai_canonname. 211 if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) { 212 return false; 213 } 214 215 return true; 216 } 217 218 void DnsProxyListener::GetAddrInfoHandler::run() { 219 if (DBG) { 220 ALOGD("GetAddrInfoHandler, now for %s / %s / {%u,%u,%u,%u,%u}", mHost, mService, 221 mNetContext.app_netid, mNetContext.app_mark, 222 mNetContext.dns_netid, mNetContext.dns_mark, 223 mNetContext.uid); 224 } 225 226 struct addrinfo* result = NULL; 227 Stopwatch s; 228 uint32_t rv = android_getaddrinfofornetcontext(mHost, mService, mHints, &mNetContext, &result); 229 const int latencyMs = lround(s.timeTaken()); 230 231 if (rv) { 232 // getaddrinfo failed 233 mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv)); 234 } else { 235 bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult); 236 struct addrinfo* ai = result; 237 while (ai && success) { 238 success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai); 239 ai = ai->ai_next; 240 } 241 success = success && sendBE32(mClient, 0); 242 if (!success) { 243 ALOGW("Error writing DNS result to client"); 244 } 245 } 246 std::vector<String16> ip_addrs; 247 int total_ip_addr_count = 0; 248 if (result) { 249 if (mNetdEventListener != nullptr 250 && mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) { 251 for (addrinfo* ai = result; ai; ai = ai->ai_next) { 252 sockaddr* ai_addr = ai->ai_addr; 253 if (ai_addr) { 254 addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen); 255 total_ip_addr_count++; 256 } 257 } 258 } 259 freeaddrinfo(result); 260 } 261 mClient->decRef(); 262 if (mNetdEventListener != nullptr) { 263 switch (mReportingLevel) { 264 case INetdEventListener::REPORTING_LEVEL_NONE: 265 // Skip reporting. 266 break; 267 case INetdEventListener::REPORTING_LEVEL_METRICS: 268 // Metrics reporting is on. Send metrics. 269 mNetdEventListener->onDnsEvent(mNetContext.dns_netid, 270 INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv, 271 latencyMs, String16(""), {}, -1, -1); 272 break; 273 case INetdEventListener::REPORTING_LEVEL_FULL: 274 // Full event info reporting is on. Send full info. 275 mNetdEventListener->onDnsEvent(mNetContext.dns_netid, 276 INetdEventListener::EVENT_GETADDRINFO, (int32_t) rv, 277 latencyMs, String16(mHost), ip_addrs, 278 total_ip_addr_count, mNetContext.uid); 279 break; 280 } 281 } else { 282 ALOGW("Netd event listener is not available; skipping."); 283 } 284 } 285 286 void DnsProxyListener::addIpAddrWithinLimit(std::vector<android::String16>& ip_addrs, 287 const sockaddr* addr, socklen_t addrlen) { 288 // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT 289 // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether 290 // some addresses didn't get logged. 291 if (ip_addrs.size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) { 292 char ip_addr[INET6_ADDRSTRLEN]; 293 if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) { 294 ip_addrs.push_back(String16(ip_addr)); 295 } 296 } 297 } 298 299 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd(DnsProxyListener* dnsProxyListener) : 300 NetdCommand("getaddrinfo"), 301 mDnsProxyListener(dnsProxyListener) { 302 } 303 304 int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient *cli, 305 int argc, char **argv) { 306 if (DBG) { 307 for (int i = 0; i < argc; i++) { 308 ALOGD("argv[%i]=%s", i, argv[i]); 309 } 310 } 311 if (argc != 8) { 312 char* msg = NULL; 313 asprintf( &msg, "Invalid number of arguments to getaddrinfo: %i", argc); 314 ALOGW("%s", msg); 315 cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 316 free(msg); 317 return -1; 318 } 319 320 char* name = argv[1]; 321 if (strcmp("^", name) == 0) { 322 name = NULL; 323 } else { 324 name = strdup(name); 325 } 326 327 char* service = argv[2]; 328 if (strcmp("^", service) == 0) { 329 service = NULL; 330 } else { 331 service = strdup(service); 332 } 333 334 struct addrinfo* hints = NULL; 335 int ai_flags = atoi(argv[3]); 336 int ai_family = atoi(argv[4]); 337 int ai_socktype = atoi(argv[5]); 338 int ai_protocol = atoi(argv[6]); 339 unsigned netId = strtoul(argv[7], NULL, 10); 340 uid_t uid = cli->getUid(); 341 342 struct android_net_context netcontext; 343 mDnsProxyListener->mNetCtrl->getNetworkContext(netId, uid, &netcontext); 344 345 if (ai_flags != -1 || ai_family != -1 || 346 ai_socktype != -1 || ai_protocol != -1) { 347 hints = (struct addrinfo*) calloc(1, sizeof(struct addrinfo)); 348 hints->ai_flags = ai_flags; 349 hints->ai_family = ai_family; 350 hints->ai_socktype = ai_socktype; 351 hints->ai_protocol = ai_protocol; 352 } 353 354 if (DBG) { 355 ALOGD("GetAddrInfoHandler for %s / %s / {%u,%u,%u,%u,%u}", 356 name ? name : "[nullhost]", 357 service ? service : "[nullservice]", 358 netcontext.app_netid, netcontext.app_mark, 359 netcontext.dns_netid, netcontext.dns_mark, 360 netcontext.uid); 361 } 362 363 const int metricsLevel = mDnsProxyListener->mEventReporter->getMetricsReportingLevel(); 364 365 DnsProxyListener::GetAddrInfoHandler* handler = 366 new DnsProxyListener::GetAddrInfoHandler(cli, name, service, hints, netcontext, 367 metricsLevel, mDnsProxyListener->mEventReporter->getNetdEventListener()); 368 tryThreadOrError(cli, handler); 369 return 0; 370 } 371 372 /******************************************************* 373 * GetHostByName * 374 *******************************************************/ 375 DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd(DnsProxyListener* dnsProxyListener) : 376 NetdCommand("gethostbyname"), 377 mDnsProxyListener(dnsProxyListener) { 378 } 379 380 int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient *cli, 381 int argc, char **argv) { 382 if (DBG) { 383 for (int i = 0; i < argc; i++) { 384 ALOGD("argv[%i]=%s", i, argv[i]); 385 } 386 } 387 if (argc != 4) { 388 char* msg = NULL; 389 asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc); 390 ALOGW("%s", msg); 391 cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 392 free(msg); 393 return -1; 394 } 395 396 uid_t uid = cli->getUid(); 397 unsigned netId = strtoul(argv[1], NULL, 10); 398 char* name = argv[2]; 399 int af = atoi(argv[3]); 400 401 if (strcmp(name, "^") == 0) { 402 name = NULL; 403 } else { 404 name = strdup(name); 405 } 406 407 uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid); 408 const int metricsLevel = mDnsProxyListener->mEventReporter->getMetricsReportingLevel(); 409 410 DnsProxyListener::GetHostByNameHandler* handler = 411 new DnsProxyListener::GetHostByNameHandler(cli, name, af, netId, mark, metricsLevel, 412 mDnsProxyListener->mEventReporter->getNetdEventListener()); 413 tryThreadOrError(cli, handler); 414 return 0; 415 } 416 417 DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler( 418 SocketClient* c, char* name, int af, unsigned netId, uint32_t mark, const int metricsLevel, 419 const android::sp<android::net::metrics::INetdEventListener>& netdEventListener) 420 : mClient(c), 421 mName(name), 422 mAf(af), 423 mNetId(netId), 424 mMark(mark), 425 mReportingLevel(metricsLevel), 426 mNetdEventListener(netdEventListener) { 427 } 428 429 DnsProxyListener::GetHostByNameHandler::~GetHostByNameHandler() { 430 free(mName); 431 } 432 433 void DnsProxyListener::GetHostByNameHandler::run() { 434 if (DBG) { 435 ALOGD("DnsProxyListener::GetHostByNameHandler::run\n"); 436 } 437 438 Stopwatch s; 439 struct hostent* hp = android_gethostbynamefornet(mName, mAf, mNetId, mMark); 440 const int latencyMs = lround(s.timeTaken()); 441 442 if (DBG) { 443 ALOGD("GetHostByNameHandler::run gethostbyname errno: %s hp->h_name = %s, name_len = %zu\n", 444 hp ? "success" : strerror(errno), 445 (hp && hp->h_name) ? hp->h_name : "null", 446 (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0); 447 } 448 449 bool success = true; 450 if (hp) { 451 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 452 success &= sendhostent(mClient, hp); 453 } else { 454 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 455 } 456 457 if (!success) { 458 ALOGW("GetHostByNameHandler: Error writing DNS result to client\n"); 459 } 460 461 if (mNetdEventListener != nullptr) { 462 std::vector<String16> ip_addrs; 463 int total_ip_addr_count = 0; 464 if (mReportingLevel == INetdEventListener::REPORTING_LEVEL_FULL) { 465 if (hp != nullptr && hp->h_addrtype == AF_INET) { 466 in_addr** list = (in_addr**) hp->h_addr_list; 467 for (int i = 0; list[i] != NULL; i++) { 468 sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = *list[i] }; 469 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin, sizeof(sin)); 470 total_ip_addr_count++; 471 } 472 } else if (hp != nullptr && hp->h_addrtype == AF_INET6) { 473 in6_addr** list = (in6_addr**) hp->h_addr_list; 474 for (int i = 0; list[i] != NULL; i++) { 475 sockaddr_in6 sin6 = { .sin6_family = AF_INET6, .sin6_addr = *list[i] }; 476 addIpAddrWithinLimit(ip_addrs, (sockaddr*) &sin6, sizeof(sin6)); 477 total_ip_addr_count++; 478 } 479 } 480 } 481 switch (mReportingLevel) { 482 case INetdEventListener::REPORTING_LEVEL_NONE: 483 // Reporting is off. 484 break; 485 case INetdEventListener::REPORTING_LEVEL_METRICS: 486 // Metrics reporting is on. Send metrics. 487 mNetdEventListener->onDnsEvent(mNetId, INetdEventListener::EVENT_GETHOSTBYNAME, 488 h_errno, latencyMs, String16(""), {}, -1, -1); 489 break; 490 case INetdEventListener::REPORTING_LEVEL_FULL: 491 // Full event info reporting is on. Send full info. 492 mNetdEventListener->onDnsEvent(mNetId, INetdEventListener::EVENT_GETHOSTBYNAME, 493 h_errno, latencyMs, String16(mName), ip_addrs, 494 total_ip_addr_count, mClient->getUid()); 495 break; 496 } 497 } 498 499 mClient->decRef(); 500 } 501 502 503 /******************************************************* 504 * GetHostByAddr * 505 *******************************************************/ 506 DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd(const DnsProxyListener* dnsProxyListener) : 507 NetdCommand("gethostbyaddr"), 508 mDnsProxyListener(dnsProxyListener) { 509 } 510 511 int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient *cli, 512 int argc, char **argv) { 513 if (DBG) { 514 for (int i = 0; i < argc; i++) { 515 ALOGD("argv[%i]=%s", i, argv[i]); 516 } 517 } 518 if (argc != 5) { 519 char* msg = NULL; 520 asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc); 521 ALOGW("%s", msg); 522 cli->sendMsg(ResponseCode::CommandParameterError, msg, false); 523 free(msg); 524 return -1; 525 } 526 527 char* addrStr = argv[1]; 528 int addrLen = atoi(argv[2]); 529 int addrFamily = atoi(argv[3]); 530 uid_t uid = cli->getUid(); 531 unsigned netId = strtoul(argv[4], NULL, 10); 532 533 void* addr = malloc(sizeof(struct in6_addr)); 534 errno = 0; 535 int result = inet_pton(addrFamily, addrStr, addr); 536 if (result <= 0) { 537 char* msg = NULL; 538 asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno)); 539 ALOGW("%s", msg); 540 cli->sendMsg(ResponseCode::OperationFailed, msg, false); 541 free(addr); 542 free(msg); 543 return -1; 544 } 545 546 uint32_t mark = mDnsProxyListener->mNetCtrl->getNetworkForDns(&netId, uid); 547 548 DnsProxyListener::GetHostByAddrHandler* handler = 549 new DnsProxyListener::GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netId, mark); 550 tryThreadOrError(cli, handler); 551 return 0; 552 } 553 554 DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, 555 void* address, 556 int addressLen, 557 int addressFamily, 558 unsigned netId, 559 uint32_t mark) 560 : mClient(c), 561 mAddress(address), 562 mAddressLen(addressLen), 563 mAddressFamily(addressFamily), 564 mNetId(netId), 565 mMark(mark) { 566 } 567 568 DnsProxyListener::GetHostByAddrHandler::~GetHostByAddrHandler() { 569 free(mAddress); 570 } 571 572 void DnsProxyListener::GetHostByAddrHandler::run() { 573 if (DBG) { 574 ALOGD("DnsProxyListener::GetHostByAddrHandler::run\n"); 575 } 576 struct hostent* hp; 577 578 // NOTE gethostbyaddr should take a void* but bionic thinks it should be char* 579 hp = android_gethostbyaddrfornet((char*)mAddress, mAddressLen, mAddressFamily, mNetId, mMark); 580 581 if (DBG) { 582 ALOGD("GetHostByAddrHandler::run gethostbyaddr errno: %s hp->h_name = %s, name_len = %zu\n", 583 hp ? "success" : strerror(errno), 584 (hp && hp->h_name) ? hp->h_name : "null", 585 (hp && hp->h_name) ? strlen(hp->h_name) + 1 : 0); 586 } 587 588 bool success = true; 589 if (hp) { 590 success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0; 591 success &= sendhostent(mClient, hp); 592 } else { 593 success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, NULL, 0) == 0; 594 } 595 596 if (!success) { 597 ALOGW("GetHostByAddrHandler: Error writing DNS result to client\n"); 598 } 599 mClient->decRef(); 600 } 601 602 } // namespace net 603 } // namespace android 604