blob: c8faab42f1bde79748ec5f2d10b05e1441d3de5b [file] [log] [blame]
Casey Dahlin10ad15f2016-05-06 16:19:13 -07001/*
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
Casey Dahlin3122cdf2016-06-23 14:19:37 -070017#include "adb_mdns.h"
Casey Dahlin10ad15f2016-05-06 16:19:13 -070018#include "sysdeps.h"
19
Casey Dahlin10ad15f2016-05-06 16:19:13 -070020#include <dns_sd.h>
21#include <endian.h>
Casey Dahlin10ad15f2016-05-06 16:19:13 -070022#include <unistd.h>
23
Josh Gao0f3312a2017-04-12 17:00:49 -070024#include <chrono>
25#include <mutex>
26#include <thread>
27
Casey Dahlin10ad15f2016-05-06 16:19:13 -070028#include <android-base/logging.h>
29#include <android-base/properties.h>
30
31using namespace std::chrono_literals;
32
33static std::mutex& mdns_lock = *new std::mutex();
34static int port;
Lingfeng Yangf44871a2018-11-16 22:47:31 -080035static DNSServiceRef mdns_refs[kNumADBDNSServices];
36static bool mdns_registered[kNumADBDNSServices];
Casey Dahlin10ad15f2016-05-06 16:19:13 -070037
38static 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
50static 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
Josh Gao0f3312a2017-04-12 17:00:49 -070063static void setup_mdns_thread() {
Casey Dahlin10ad15f2016-05-06 16:19:13 -070064 start_mdns();
65 std::lock_guard<std::mutex> lock(mdns_lock);
66
Casey Dahlin50b39b42016-05-20 16:34:51 -070067 std::string hostname = "adb-";
68 hostname += android::base::GetProperty("ro.serialno", "unidentified");
69
Lingfeng Yangf44871a2018-11-16 22:47:31 -080070 for (int i = 0; i < kNumADBDNSServices; i++) {
71 auto error = DNSServiceRegister(&mdns_refs[i], 0, 0, hostname.c_str(), kADBDNSServices[i],
72 nullptr, nullptr, htobe16((uint16_t)port), 0, nullptr,
73 mdns_callback, nullptr);
Casey Dahlin10ad15f2016-05-06 16:19:13 -070074
Lingfeng Yangf44871a2018-11-16 22:47:31 -080075 if (error != kDNSServiceErr_NoError) {
76 LOG(ERROR) << "Could not register mDNS service " << kADBDNSServices[i] << ", error ("
77 << error << ").";
78 mdns_registered[i] = false;
79 }
80
81 mdns_registered[i] = true;
Casey Dahlin10ad15f2016-05-06 16:19:13 -070082 }
83
Lingfeng Yangf44871a2018-11-16 22:47:31 -080084 for (int i = 0; i < kNumADBDNSServices; i++) {
85 LOG(INFO) << "adbd mDNS service " << kADBDNSServices[i]
86 << " registered: " << mdns_registered[i];
87 }
Casey Dahlin10ad15f2016-05-06 16:19:13 -070088}
89
90static void teardown_mdns() {
91 std::lock_guard<std::mutex> lock(mdns_lock);
92
Lingfeng Yangf44871a2018-11-16 22:47:31 -080093 for (int i = 0; i < kNumADBDNSServices; ++i) {
94 if (mdns_registered[i]) {
95 DNSServiceRefDeallocate(mdns_refs[i]);
96 }
Casey Dahlin10ad15f2016-05-06 16:19:13 -070097 }
98}
99
100void setup_mdns(int port_in) {
101 port = port_in;
Josh Gao0f3312a2017-04-12 17:00:49 -0700102 std::thread(setup_mdns_thread).detach();
Casey Dahlin10ad15f2016-05-06 16:19:13 -0700103
104 // TODO: Make this more robust against a hard kill.
105 atexit(teardown_mdns);
106}