From 6cd5e0b4efded6b86c27de7d97dd910190436867 Mon Sep 17 00:00:00 2001 From: Casey Dahlin Date: Fri, 6 May 2016 16:19:13 -0700 Subject: [PATCH] Make ADBD announce its presence over mDNS We now request mdnsd from adb and register a service of type _adb._tcp for clients to connect to. Test: Verified service appears in avahi-browse Bug: 28074466 (cherry picked from 379ac414e4d9f53388d903913022a55695292775) Change-Id: Ie871b9c8b40e86063cc1e68e8f3e4290ead2d279 --- adb/Android.mk | 2 + adb/daemon/main.cpp | 11 +++++- adb/daemon/mdns.cpp | 90 +++++++++++++++++++++++++++++++++++++++++++++ adb/daemon/mdns.h | 22 +++++++++++ 4 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 adb/daemon/mdns.cpp create mode 100644 adb/daemon/mdns.h diff --git a/adb/Android.mk b/adb/Android.mk index a2ea699bc..d5b8ddb24 100644 --- a/adb/Android.mk +++ b/adb/Android.mk @@ -325,6 +325,7 @@ LOCAL_CLANG := true LOCAL_SRC_FILES := \ daemon/main.cpp \ + daemon/mdns.cpp \ services.cpp \ file_sync_service.cpp \ framebuffer_service.cpp \ @@ -372,6 +373,7 @@ LOCAL_STATIC_LIBRARIES := \ libcrypto_utils \ libcrypto \ libminijail \ + libmdnssd \ libdebuggerd_handler \ include $(BUILD_EXECUTABLE) diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp index 6382b6789..7da94ce10 100644 --- a/adb/daemon/main.cpp +++ b/adb/daemon/main.cpp @@ -45,6 +45,8 @@ #include "adb_utils.h" #include "transport.h" +#include "mdns.h" + static const char* root_seclabel = nullptr; static void drop_capabilities_bounding_set_if_needed(struct minijail *j) { @@ -140,6 +142,11 @@ static void drop_privileges(int server_port) { } } +static void setup_port(int port) { + local_init(port); + setup_mdns(port); +} + int adbd_main(int server_port) { umask(0); @@ -188,10 +195,10 @@ int adbd_main(int server_port) { if (sscanf(prop_port.c_str(), "%d", &port) == 1 && port > 0) { D("using port=%d", port); // Listen on TCP port specified by service.adb.tcp.port property. - local_init(port); + setup_port(port); } else if (!is_usb) { // Listen on default port. - local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); + setup_port(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); } D("adbd_main(): pre init_jdwp()"); diff --git a/adb/daemon/mdns.cpp b/adb/daemon/mdns.cpp new file mode 100644 index 000000000..85c5a07d4 --- /dev/null +++ b/adb/daemon/mdns.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sysdeps.h" + +#include +#include +#include +#include +#include + +#include +#include + +using namespace std::chrono_literals; + +static std::mutex& mdns_lock = *new std::mutex(); +static int port; +static DNSServiceRef mdns_ref; +static bool mdns_registered = false; + +static void start_mdns() { + if (android::base::GetProperty("init.svc.mdnsd", "") == "running") { + return; + } + + android::base::SetProperty("ctl.start", "mdnsd"); + + if (! android::base::WaitForProperty("init.svc.mdnsd", "running", 5s)) { + LOG(ERROR) << "Could not start mdnsd."; + } +} + +static void mdns_callback(DNSServiceRef /*ref*/, + DNSServiceFlags /*flags*/, + DNSServiceErrorType errorCode, + const char* /*name*/, + const char* /*regtype*/, + const char* /*domain*/, + void* /*context*/) { + if (errorCode != kDNSServiceErr_NoError) { + LOG(ERROR) << "Encountered mDNS registration error (" + << errorCode << ")."; + } +} + +static void setup_mdns_thread(void* /* unused */) { + start_mdns(); + std::lock_guard lock(mdns_lock); + + auto error = DNSServiceRegister(&mdns_ref, 0, 0, nullptr, "_adb._tcp", + nullptr, nullptr, htobe16((uint16_t)port), + 0, nullptr, mdns_callback, nullptr); + + if (error != kDNSServiceErr_NoError) { + LOG(ERROR) << "Could not register mDNS service (" << error << ")."; + mdns_registered = false; + } + + mdns_registered = true; +} + +static void teardown_mdns() { + std::lock_guard lock(mdns_lock); + + if (mdns_registered) { + DNSServiceRefDeallocate(mdns_ref); + } +} + +void setup_mdns(int port_in) { + port = port_in; + adb_thread_create(setup_mdns_thread, nullptr, nullptr); + + // TODO: Make this more robust against a hard kill. + atexit(teardown_mdns); +} diff --git a/adb/daemon/mdns.h b/adb/daemon/mdns.h new file mode 100644 index 000000000..4c6b1ca02 --- /dev/null +++ b/adb/daemon/mdns.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _DAEMON_MDNS_H_ +#define _DAEMON_MDNS_H_ + +void setup_mdns(int port); + +#endif // _DAEMON_MDNS_H_