Skip to content

Commit f4ba8d7

Browse files
committed
Openscreen discovery integration for adb client.
The openscreen discovery library will allow adb client on all three platforms to discover mdns services without relying on having Bonjour on the host machine. If the host does have bonjour running, we will fallback to using the MdnsResponder client. The openscreen discovery code path will be disabled by default for now. You can enable it by setting ADB_MDNS_OPENSCREEN=1. Check `adb host-features` string for 'openscreen_mdns' feature. Test: test_adb.py Bug: 152884934 Change-Id: Ief153afe7f080cb21134897d8eaf00d90c6983d8
1 parent 8df5407 commit f4ba8d7

23 files changed

+2532
-695
lines changed

Android.bp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
tidy_errors = [
1616
"-*",
1717
"bugprone-inaccurate-erase",
18+
"bugprone-use-after-move",
1819
]
1920

2021
cc_defaults {
@@ -76,6 +77,7 @@ cc_defaults {
7677
"-lws2_32",
7778
"-lgdi32",
7879
"-luserenv",
80+
"-liphlpapi",
7981
],
8082
},
8183
},
@@ -181,6 +183,7 @@ libadb_srcs = [
181183
"adb.cpp",
182184
"adb_io.cpp",
183185
"adb_listeners.cpp",
186+
"adb_mdns.cpp",
184187
"adb_trace.cpp",
185188
"adb_unique_fd.cpp",
186189
"adb_utils.cpp",
@@ -233,13 +236,19 @@ cc_library_host_static {
233236
defaults: ["adb_defaults"],
234237

235238
srcs: libadb_srcs + [
239+
"client/openscreen/mdns_service_info.cpp",
240+
"client/openscreen/mdns_service_watcher.cpp",
241+
"client/openscreen/platform/logging.cpp",
242+
"client/openscreen/platform/task_runner.cpp",
243+
"client/openscreen/platform/udp_socket.cpp",
236244
"client/auth.cpp",
237245
"client/adb_wifi.cpp",
238246
"client/usb_libusb.cpp",
239247
"client/usb_dispatch.cpp",
240248
"client/transport_local.cpp",
241-
"client/transport_mdns.cpp",
249+
"client/mdnsresponder_client.cpp",
242250
"client/mdns_utils.cpp",
251+
"client/transport_mdns.cpp",
243252
"client/transport_usb.cpp",
244253
"client/pairing/pairing_client.cpp",
245254
],
@@ -279,6 +288,8 @@ cc_library_host_static {
279288
"libutils",
280289
"liblog",
281290
"libcutils",
291+
"libopenscreen-discovery",
292+
"libopenscreen-platform-impl",
282293
"libprotobuf-cpp-lite",
283294
],
284295
}
@@ -344,6 +355,8 @@ cc_test_host {
344355
"liblog",
345356
"libmdnssd",
346357
"libdiagnose_usb",
358+
"libopenscreen-discovery",
359+
"libopenscreen-platform-impl",
347360
"libprotobuf-cpp-lite",
348361
"libssl",
349362
"libusb",
@@ -406,6 +419,8 @@ cc_binary_host {
406419
"liblog",
407420
"liblz4",
408421
"libmdnssd",
422+
"libopenscreen-discovery",
423+
"libopenscreen-platform-impl",
409424
"libprotobuf-cpp-full",
410425
"libssl",
411426
"libusb",
@@ -907,6 +922,8 @@ cc_test_host {
907922
"libfastdeploy_host",
908923
"liblog",
909924
"libmdnssd",
925+
"libopenscreen-discovery",
926+
"libopenscreen-platform-impl",
910927
"libprotobuf-cpp-lite",
911928
"libssl",
912929
"libusb",

PREUPLOAD.cfg

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[Builtin Hooks]
2+
clang_format = true
3+
4+
[Builtin Hooks Options]
5+
clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
6+
7+
[Hook Scripts]
8+
aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "."

adb.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@
5151
#include "adb_auth.h"
5252
#include "adb_io.h"
5353
#include "adb_listeners.h"
54+
#include "adb_mdns.h"
5455
#include "adb_unique_fd.h"
5556
#include "adb_utils.h"
56-
#include "adb_wifi.h"
5757
#include "sysdeps/chrono.h"
5858
#include "transport.h"
5959

adb_mdns.cpp

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright (C) 2020 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+
#define TRACE_TAG TRANSPORT
18+
19+
#include "adb_mdns.h"
20+
21+
#include <set>
22+
23+
#include <android-base/stringprintf.h>
24+
#include <android-base/strings.h>
25+
26+
#include "adb_trace.h"
27+
28+
#define ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ver) ("v=" #ver)
29+
30+
const char* kADBSecurePairingServiceTxtRecord =
31+
ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ADB_SECURE_SERVICE_VERSION);
32+
const char* kADBSecureConnectServiceTxtRecord =
33+
ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ADB_SECURE_SERVICE_VERSION);
34+
35+
#define ADB_FULL_MDNS_SERVICE_TYPE(atype) ("_" atype "._tcp")
36+
const char* kADBDNSServices[] = {ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_SERVICE_TYPE),
37+
ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_TLS_PAIRING_TYPE),
38+
ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_TLS_CONNECT_TYPE)};
39+
40+
const char* kADBDNSServiceTxtRecords[] = {
41+
nullptr,
42+
kADBSecurePairingServiceTxtRecord,
43+
kADBSecureConnectServiceTxtRecord,
44+
};
45+
46+
#if ADB_HOST
47+
namespace {
48+
49+
std::atomic<bool> g_allowedlist_configured{false};
50+
[[clang::no_destroy]] std::set<int> g_autoconn_allowedlist;
51+
52+
void config_auto_connect_services() {
53+
bool expected = false;
54+
if (!g_allowedlist_configured.compare_exchange_strong(expected, true)) {
55+
return;
56+
}
57+
58+
// ADB_MDNS_AUTO_CONNECT is a comma-delimited list of mdns services
59+
// that are allowed to auto-connect. By default, only allow "adb-tls-connect"
60+
// to auto-connect, since this is filtered down to auto-connect only to paired
61+
// devices.
62+
g_autoconn_allowedlist.insert(kADBSecureConnectServiceRefIndex);
63+
const char* srvs = getenv("ADB_MDNS_AUTO_CONNECT");
64+
if (!srvs) {
65+
return;
66+
}
67+
68+
if (strcmp(srvs, "0") == 0) {
69+
D("Disabling all auto-connecting");
70+
g_autoconn_allowedlist.clear();
71+
return;
72+
}
73+
74+
if (strcmp(srvs, "all") == 0) {
75+
D("Allow all auto-connecting");
76+
g_autoconn_allowedlist.insert(kADBTransportServiceRefIndex);
77+
return;
78+
}
79+
80+
// Selectively choose which services to allow auto-connect.
81+
// E.g. ADB_MDNS_AUTO_CONNECT=adb,adb-tls-connect would allow
82+
// _adb._tcp and _adb-tls-connnect._tcp services to auto-connect.
83+
auto srvs_list = android::base::Split(srvs, ",");
84+
std::set<int> new_allowedlist;
85+
for (const auto& item : srvs_list) {
86+
auto full_srv = android::base::StringPrintf("_%s._tcp", item.data());
87+
std::optional<int> idx = adb_DNSServiceIndexByName(full_srv);
88+
if (idx.has_value()) {
89+
new_allowedlist.insert(*idx);
90+
}
91+
}
92+
93+
if (!new_allowedlist.empty()) {
94+
g_autoconn_allowedlist = std::move(new_allowedlist);
95+
}
96+
97+
std::string res;
98+
std::for_each(g_autoconn_allowedlist.begin(), g_autoconn_allowedlist.end(), [&](const int& i) {
99+
res += kADBDNSServices[i];
100+
res += ",";
101+
});
102+
D("mdns auto-connect allowedlist: [%s]", res.data());
103+
}
104+
105+
} // namespace
106+
107+
std::optional<int> adb_DNSServiceIndexByName(std::string_view reg_type) {
108+
for (int i = 0; i < kNumADBDNSServices; ++i) {
109+
if (!strncmp(reg_type.data(), kADBDNSServices[i], strlen(kADBDNSServices[i]))) {
110+
return i;
111+
}
112+
}
113+
return std::nullopt;
114+
}
115+
116+
bool adb_DNSServiceShouldAutoConnect(std::string_view reg_type, std::string_view service_name) {
117+
config_auto_connect_services();
118+
119+
// Try to auto-connect to any "_adb" or "_adb-tls-connect" services excluding emulator services.
120+
std::optional<int> index = adb_DNSServiceIndexByName(reg_type);
121+
if (!index ||
122+
(index != kADBTransportServiceRefIndex && index != kADBSecureConnectServiceRefIndex)) {
123+
return false;
124+
}
125+
if (g_autoconn_allowedlist.find(*index) == g_autoconn_allowedlist.end()) {
126+
D("Auto-connect for reg_type '%s' disabled", reg_type.data());
127+
return false;
128+
}
129+
// Ignore adb-EMULATOR* service names, as it interferes with the
130+
// emulator ports that are already connected.
131+
if (android::base::StartsWith(service_name, "adb-EMULATOR")) {
132+
LOG(INFO) << "Ignoring emulator transport service [" << service_name << "]";
133+
return false;
134+
}
135+
return true;
136+
}
137+
138+
#endif // ADB_HOST

adb_mdns.h

Lines changed: 60 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@
1414
* limitations under the License.
1515
*/
1616

17-
#ifndef _ADB_MDNS_H_
18-
#define _ADB_MDNS_H_
17+
#pragma once
1918

20-
#include <android-base/macros.h>
19+
#include <optional>
20+
#include <string>
21+
#include <string_view>
2122

2223
// The rules for Service Names [RFC6335] state that they may be no more
2324
// than fifteen characters long (not counting the mandatory underscore),
@@ -28,65 +29,70 @@
2829
#define ADB_MDNS_TLS_PAIRING_TYPE "adb-tls-pairing"
2930
#define ADB_MDNS_TLS_CONNECT_TYPE "adb-tls-connect"
3031

31-
const int kADBTransportServiceRefIndex = 0;
32-
const int kADBSecurePairingServiceRefIndex = 1;
33-
const int kADBSecureConnectServiceRefIndex = 2;
34-
35-
// Each ADB Secure service advertises with a TXT record indicating the version
36-
// using a key/value pair per RFC 6763 (https://tools.ietf.org/html/rfc6763).
37-
//
38-
// The first key/value pair is always the version of the protocol.
39-
// There may be more key/value pairs added after.
40-
//
41-
// The version is purposely represented as the single letter "v" due to the
42-
// need to minimize DNS traffic. The version starts at 1. With each breaking
43-
// protocol change, the version is incremented by 1.
44-
//
45-
// Newer adb clients/daemons need to recognize and either reject
46-
// or be backward-compatible with older verseions if there is a mismatch.
47-
//
48-
// Relevant sections:
49-
//
50-
// """
51-
// 6.4. Rules for Keys in DNS-SD Key/Value Pairs
52-
//
53-
// The key MUST be at least one character. DNS-SD TXT record strings
54-
// beginning with an '=' character (i.e., the key is missing) MUST be
55-
// silently ignored.
56-
//
57-
// ...
58-
//
59-
// 6.5. Rules for Values in DNS-SD Key/Value Pairs
60-
//
61-
// If there is an '=' in a DNS-SD TXT record string, then everything
62-
// after the first '=' to the end of the string is the value. The value
63-
// can contain any eight-bit values including '='.
64-
// """
65-
66-
#define ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ver) ("v=" #ver)
67-
6832
// Client/service versions are initially defined to be matching,
6933
// but may go out of sync as different clients and services
7034
// try to talk to each other.
7135
#define ADB_SECURE_SERVICE_VERSION 1
7236
#define ADB_SECURE_CLIENT_VERSION ADB_SECURE_SERVICE_VERSION
7337

74-
const char* kADBSecurePairingServiceTxtRecord =
75-
ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ADB_SECURE_SERVICE_VERSION);
76-
const char* kADBSecureConnectServiceTxtRecord =
77-
ADB_SECURE_SERVICE_VERSION_TXT_RECORD(ADB_SECURE_SERVICE_VERSION);
38+
constexpr int kADBTransportServiceRefIndex = 0;
39+
constexpr int kADBSecurePairingServiceRefIndex = 1;
40+
constexpr int kADBSecureConnectServiceRefIndex = 2;
41+
constexpr int kNumADBDNSServices = 3;
42+
43+
extern const char* _Nonnull kADBSecurePairingServiceTxtRecord;
44+
extern const char* _Nonnull kADBSecureConnectServiceTxtRecord;
45+
46+
extern const char* _Nonnull kADBDNSServices[kNumADBDNSServices];
47+
extern const char* _Nonnull kADBDNSServiceTxtRecords[kNumADBDNSServices];
48+
49+
#if ADB_HOST
50+
// ADB Secure DNS service interface. Used to query what ADB Secure DNS services have been
51+
// resolved, and to run some kind of callback for each one.
52+
using adb_secure_foreach_service_callback =
53+
std::function<void(const std::string& service_name, const std::string& reg_type,
54+
const std::string& ip_address, uint16_t port)>;
7855

79-
#define ADB_FULL_MDNS_SERVICE_TYPE(atype) ("_" atype "._tcp")
80-
const char* kADBDNSServices[] = {ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_SERVICE_TYPE),
81-
ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_TLS_PAIRING_TYPE),
82-
ADB_FULL_MDNS_SERVICE_TYPE(ADB_MDNS_TLS_CONNECT_TYPE)};
56+
// Tries to connect to a |service_name| if found. Returns true if found and
57+
// connected, false otherwise.
58+
bool adb_secure_connect_by_service_name(const std::string& instance_name);
8359

84-
const char* kADBDNSServiceTxtRecords[] = {
85-
nullptr,
86-
kADBSecurePairingServiceTxtRecord,
87-
kADBSecureConnectServiceTxtRecord,
60+
// Returns the index in kADBDNSServices array if |reg_type| matches a service name, otherwise
61+
// std::nullopt.
62+
std::optional<int> adb_DNSServiceIndexByName(std::string_view reg_type);
63+
// Returns true if auto-connect is allowed for |service_name| and |instance_name|.
64+
// See ADB_MDNS_AUTO_CONNECT environment variable for more info.
65+
bool adb_DNSServiceShouldAutoConnect(std::string_view service_name, std::string_view instance_name);
66+
67+
void mdns_cleanup(void);
68+
std::string mdns_check();
69+
std::string mdns_list_discovered_services();
70+
71+
struct MdnsInfo {
72+
std::string service_name;
73+
std::string service_type;
74+
std::string addr;
75+
uint16_t port = 0;
76+
77+
MdnsInfo(std::string_view name, std::string_view type, std::string_view addr, uint16_t port)
78+
: service_name(name), service_type(type), addr(addr), port(port) {}
8879
};
8980

90-
const int kNumADBDNSServices = arraysize(kADBDNSServices);
81+
std::optional<MdnsInfo> mdns_get_connect_service_info(const std::string& name);
82+
std::optional<MdnsInfo> mdns_get_pairing_service_info(const std::string& name);
83+
84+
// TODO: Remove once openscreen has support for bonjour client APIs.
85+
struct AdbMdnsResponderFuncs {
86+
std::string (*_Nonnull mdns_check)(void);
87+
std::string (*_Nonnull mdns_list_discovered_services)(void);
88+
std::optional<MdnsInfo> (*_Nonnull mdns_get_connect_service_info)(const std::string&);
89+
std::optional<MdnsInfo> (*_Nonnull mdns_get_pairing_service_info)(const std::string&);
90+
void (*_Nonnull mdns_cleanup)(void);
91+
bool (*_Nonnull adb_secure_connect_by_service_name)(const std::string&);
92+
}; // AdbBonjourCallbacks
9193

92-
#endif
94+
// TODO: Remove once openscreen has support for bonjour client APIs.
95+
// Start mdns discovery using MdnsResponder backend. Fills in AdbMdnsResponderFuncs for adb mdns
96+
// related functions.
97+
AdbMdnsResponderFuncs StartMdnsResponderDiscovery();
98+
#endif // ADB_HOST

adb_wifi.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,6 @@ void adb_wifi_pair_device(const std::string& host, const std::string& password,
2828
std::string& response);
2929
bool adb_wifi_is_known_host(const std::string& host);
3030

31-
std::string mdns_check();
32-
std::string mdns_list_discovered_services();
33-
34-
struct MdnsInfo {
35-
std::string service_name;
36-
std::string service_type;
37-
std::string addr;
38-
uint16_t port = 0;
39-
40-
MdnsInfo(std::string_view name, std::string_view type, std::string_view addr, uint16_t port)
41-
: service_name(name), service_type(type), addr(addr), port(port) {}
42-
};
43-
44-
std::optional<MdnsInfo> mdns_get_connect_service_info(std::string_view name);
45-
std::optional<MdnsInfo> mdns_get_pairing_service_info(std::string_view name);
46-
4731
#else // !ADB_HOST
4832

4933
struct AdbdAuthContext;

0 commit comments

Comments
 (0)