1 /*
2 * Copyright (C) 2016 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 "adb_mdns.h"
18 #include "sysdeps.h"
19
20 #include <dns_sd.h>
21 #include <endian.h>
22 #include <unistd.h>
23
24 #include <chrono>
25 #include <mutex>
26 #include <thread>
27
28 #include <android-base/logging.h>
29 #include <android-base/properties.h>
30
31 using namespace std::chrono_literals;
32
33 static std::mutex& mdns_lock = *new std::mutex();
34 static int port;
35 static DNSServiceRef mdns_ref;
36 static bool mdns_registered = false;
37
start_mdns()38 static void start_mdns() {
39 if (android::base::GetProperty("init.svc.mdnsd", "") == "running") {
40 return;
41 }
42
43 android::base::SetProperty("ctl.start", "mdnsd");
44
45 if (! android::base::WaitForProperty("init.svc.mdnsd", "running", 5s)) {
46 LOG(ERROR) << "Could not start mdnsd.";
47 }
48 }
49
mdns_callback(DNSServiceRef,DNSServiceFlags,DNSServiceErrorType errorCode,const char *,const char *,const char *,void *)50 static void mdns_callback(DNSServiceRef /*ref*/,
51 DNSServiceFlags /*flags*/,
52 DNSServiceErrorType errorCode,
53 const char* /*name*/,
54 const char* /*regtype*/,
55 const char* /*domain*/,
56 void* /*context*/) {
57 if (errorCode != kDNSServiceErr_NoError) {
58 LOG(ERROR) << "Encountered mDNS registration error ("
59 << errorCode << ").";
60 }
61 }
62
setup_mdns_thread()63 static void setup_mdns_thread() {
64 start_mdns();
65 std::lock_guard<std::mutex> lock(mdns_lock);
66
67 std::string hostname = "adb-";
68 hostname += android::base::GetProperty("ro.serialno", "unidentified");
69
70 auto error = DNSServiceRegister(&mdns_ref, 0, 0, hostname.c_str(),
71 kADBServiceType, nullptr, nullptr,
72 htobe16((uint16_t)port), 0, nullptr,
73 mdns_callback, nullptr);
74
75 if (error != kDNSServiceErr_NoError) {
76 LOG(ERROR) << "Could not register mDNS service (" << error << ").";
77 return;
78 }
79
80 mdns_registered = true;
81 }
82
teardown_mdns()83 static void teardown_mdns() {
84 std::lock_guard<std::mutex> lock(mdns_lock);
85
86 if (mdns_registered) {
87 DNSServiceRefDeallocate(mdns_ref);
88 }
89 }
90
setup_mdns(int port_in)91 void setup_mdns(int port_in) {
92 port = port_in;
93 std::thread(setup_mdns_thread).detach();
94
95 // TODO: Make this more robust against a hard kill.
96 atexit(teardown_mdns);
97 }
98