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