16cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin/* 26cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * Copyright (C) 2016 The Android Open Source Project 36cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * 46cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * Licensed under the Apache License, Version 2.0 (the "License"); 56cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * you may not use this file except in compliance with the License. 66cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * You may obtain a copy of the License at 76cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * 86cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * http://www.apache.org/licenses/LICENSE-2.0 96cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * 106cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * Unless required by applicable law or agreed to in writing, software 116cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * distributed under the License is distributed on an "AS IS" BASIS, 126cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * See the License for the specific language governing permissions and 146cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin * limitations under the License. 156cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin */ 166cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 1713a269ea24a98111d2e84a7ffa3c05ab8a4e73a9Casey Dahlin#include "adb_mdns.h" 186cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin#include "sysdeps.h" 196cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 206cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin#include <dns_sd.h> 216cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin#include <endian.h> 226cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin#include <unistd.h> 236cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 24e1dacfc1b65b04958924d1f982263d4aa71b0b94Josh Gao#include <chrono> 25e1dacfc1b65b04958924d1f982263d4aa71b0b94Josh Gao#include <mutex> 26e1dacfc1b65b04958924d1f982263d4aa71b0b94Josh Gao#include <thread> 27e1dacfc1b65b04958924d1f982263d4aa71b0b94Josh Gao 286cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin#include <android-base/logging.h> 296cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin#include <android-base/properties.h> 306cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 316cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinusing namespace std::chrono_literals; 326cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 336cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic std::mutex& mdns_lock = *new std::mutex(); 346cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic int port; 356cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic DNSServiceRef mdns_ref; 366cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic bool mdns_registered = false; 376cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 386cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic void start_mdns() { 396cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin if (android::base::GetProperty("init.svc.mdnsd", "") == "running") { 406cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin return; 416cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin } 426cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 436cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin android::base::SetProperty("ctl.start", "mdnsd"); 446cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 456cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin if (! android::base::WaitForProperty("init.svc.mdnsd", "running", 5s)) { 466cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin LOG(ERROR) << "Could not start mdnsd."; 476cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin } 486cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin} 496cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 506cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic void mdns_callback(DNSServiceRef /*ref*/, 516cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin DNSServiceFlags /*flags*/, 526cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin DNSServiceErrorType errorCode, 536cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin const char* /*name*/, 546cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin const char* /*regtype*/, 556cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin const char* /*domain*/, 566cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin void* /*context*/) { 576cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin if (errorCode != kDNSServiceErr_NoError) { 586cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin LOG(ERROR) << "Encountered mDNS registration error (" 596cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin << errorCode << ")."; 606cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin } 616cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin} 626cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 63e1dacfc1b65b04958924d1f982263d4aa71b0b94Josh Gaostatic void setup_mdns_thread() { 646cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin start_mdns(); 656cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin std::lock_guard<std::mutex> lock(mdns_lock); 666cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 671fe3cae67ecc20f346aa38bb0ed4500f8e2885bfCasey Dahlin std::string hostname = "adb-"; 681fe3cae67ecc20f346aa38bb0ed4500f8e2885bfCasey Dahlin hostname += android::base::GetProperty("ro.serialno", "unidentified"); 691fe3cae67ecc20f346aa38bb0ed4500f8e2885bfCasey Dahlin 701fe3cae67ecc20f346aa38bb0ed4500f8e2885bfCasey Dahlin auto error = DNSServiceRegister(&mdns_ref, 0, 0, hostname.c_str(), 711fe3cae67ecc20f346aa38bb0ed4500f8e2885bfCasey Dahlin kADBServiceType, nullptr, nullptr, 721fe3cae67ecc20f346aa38bb0ed4500f8e2885bfCasey Dahlin htobe16((uint16_t)port), 0, nullptr, 731fe3cae67ecc20f346aa38bb0ed4500f8e2885bfCasey Dahlin mdns_callback, nullptr); 746cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 756cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin if (error != kDNSServiceErr_NoError) { 766cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin LOG(ERROR) << "Could not register mDNS service (" << error << ")."; 776cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin mdns_registered = false; 786cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin } 796cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 806cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin mdns_registered = true; 816cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin} 826cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 836cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinstatic void teardown_mdns() { 846cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin std::lock_guard<std::mutex> lock(mdns_lock); 856cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 866cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin if (mdns_registered) { 876cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin DNSServiceRefDeallocate(mdns_ref); 886cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin } 896cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin} 906cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 916cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlinvoid setup_mdns(int port_in) { 926cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin port = port_in; 93e1dacfc1b65b04958924d1f982263d4aa71b0b94Josh Gao std::thread(setup_mdns_thread).detach(); 946cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin 956cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin // TODO: Make this more robust against a hard kill. 966cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin atexit(teardown_mdns); 976cd5e0b4efded6b86c27de7d97dd910190436867Casey Dahlin} 98