summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRemi NGUYEN VAN <reminv@google.com>2022-02-04 12:07:38 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-02-04 12:07:38 +0000
commit2b9afc40ff8ddb93c44d1518080e6c44df7400ad (patch)
treeb5a1ae9fd76a1c2b51210b2ab0237edf0f53b8a7
parentfc745d1868262e0eec998615dc7621fcb9240328 (diff)
parenta0b196b3c8397ba0938eacf20045cc817e96b8c9 (diff)
downloadnetd-android-s-v2-beta-3.tar.gz
-rw-r--r--server/MDnsSdListener.cpp144
-rw-r--r--server/MDnsSdListener.h37
2 files changed, 101 insertions, 80 deletions
diff --git a/server/MDnsSdListener.cpp b/server/MDnsSdListener.cpp
index 42dcddf3..b17d3431 100644
--- a/server/MDnsSdListener.cpp
+++ b/server/MDnsSdListener.cpp
@@ -19,6 +19,7 @@
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
+#include <inttypes.h>
#include <linux/if.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -40,6 +41,11 @@
#include <netdutils/ThreadUtil.h>
#include <sysutils/SocketClient.h>
+#include "Controllers.h"
+#include "netid_client.h"
+
+using android::net::gCtls;
+
#define MDNS_SERVICE_NAME "mdnsd"
#define MDNS_SERVICE_STATUS "init.svc.mdnsd"
@@ -49,6 +55,27 @@ constexpr char RESCAN[] = "1";
using android::netdutils::ResponseCode;
+static int ifaceNameToI(const char* iface) {
+ if (iface != nullptr) {
+ return if_nametoindex(iface);
+ }
+
+ return 0;
+}
+
+static unsigned ifaceIndexToNetId(uint32_t interfaceIndex) {
+ char interfaceName[IFNAMSIZ] = {};
+ unsigned netId;
+ if (if_indextoname(interfaceIndex, interfaceName) == nullptr) {
+ ALOGE("Interface %d was not found", interfaceIndex);
+ return NETID_UNSET;
+ } else if ((netId = gCtls->netCtrl.getNetworkForInterface(interfaceName)) == NETID_UNSET) {
+ ALOGE("Network was not found for interface %s", interfaceName);
+ return NETID_UNSET;
+ }
+ return netId;
+}
+
MDnsSdListener::MDnsSdListener() : FrameworkListener(SOCKET_NAME, true) {
Monitor *m = new Monitor();
registerCmd(new Handler(m, this));
@@ -63,15 +90,11 @@ MDnsSdListener::Handler::Handler(Monitor *m, MDnsSdListener *listener) :
MDnsSdListener::Handler::~Handler() {}
-void MDnsSdListener::Handler::discover(SocketClient *cli,
- const char *iface,
- const char *regType,
- const char *domain,
- const int requestId,
- const int requestFlags) {
+void MDnsSdListener::Handler::discover(SocketClient* cli, uint32_t ifIndex, const char* regType,
+ const char* domain, const int requestId,
+ const int requestFlags) {
if (VDBG) {
- ALOGD("discover(%s, %s, %s, %d, %d)", iface, regType, domain, requestId,
- requestFlags);
+ ALOGD("discover(%d, %s, %s, %d, %d)", ifIndex, regType, domain, requestId, requestFlags);
}
Context *context = new Context(requestId, mListener);
DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
@@ -83,10 +106,9 @@ void MDnsSdListener::Handler::discover(SocketClient *cli,
}
if (VDBG) ALOGD("using ref %p", ref);
DNSServiceFlags nativeFlags = iToFlags(requestFlags);
- int interfaceInt = ifaceNameToI(iface);
- DNSServiceErrorType result = DNSServiceBrowse(ref, nativeFlags, interfaceInt, regType,
- domain, &MDnsSdListenerDiscoverCallback, context);
+ DNSServiceErrorType result = DNSServiceBrowse(ref, nativeFlags, ifIndex, regType, domain,
+ &MDnsSdListenerDiscoverCallback, context);
if (result != kDNSServiceErr_NoError) {
ALOGE("Discover request %d got an error from DNSServiceBrowse %d", requestId, result);
mMonitor->freeServiceRef(requestId);
@@ -101,16 +123,18 @@ void MDnsSdListener::Handler::discover(SocketClient *cli,
}
void MDnsSdListenerDiscoverCallback(DNSServiceRef /* sdRef */, DNSServiceFlags flags,
- uint32_t /* interfaceIndex */, DNSServiceErrorType errorCode, const char *serviceName,
- const char *regType, const char *replyDomain, void *inContext) {
+ uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char* serviceName, const char* regType,
+ const char* replyDomain, void* inContext) {
MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
- char *msg;
int refNumber = context->mRefNumber;
if (errorCode != kDNSServiceErr_NoError) {
+ char* msg;
asprintf(&msg, "%d %d", refNumber, errorCode);
context->mListener->sendBroadcast(ResponseCode::ServiceDiscoveryFailed, msg, false);
if (DBG) ALOGE("discover failure for %d, error= %d", refNumber, errorCode);
+ free(msg);
} else {
int respCode;
char *quotedServiceName = SocketClient::quoteArg(serviceName);
@@ -127,11 +151,16 @@ void MDnsSdListenerDiscoverCallback(DNSServiceRef /* sdRef */, DNSServiceFlags f
}
respCode = ResponseCode::ServiceDiscoveryServiceRemoved;
}
- asprintf(&msg, "%d %s %s %s", refNumber, quotedServiceName, regType, replyDomain);
- free(quotedServiceName);
+ unsigned netId = ifaceIndexToNetId(ifIndex);
+ // If the network is not found, still send the broadcast back and let
+ // the service decide what to do with a callback with an empty network
+ char* msg;
+ asprintf(&msg, "%d %s %s %s %" PRIu32 " %u", refNumber, quotedServiceName, regType,
+ replyDomain, ifIndex, netId);
context->mListener->sendBroadcast(respCode, msg, false);
+ free(msg);
+ free(quotedServiceName);
}
- free(msg);
}
void MDnsSdListener::Handler::stop(SocketClient *cli, int argc, char **argv, const char *str) {
@@ -213,13 +242,12 @@ void MDnsSdListenerRegisterCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /
free(msg);
}
-
-void MDnsSdListener::Handler::resolveService(SocketClient *cli, int requestId,
- const char *interfaceName, const char *serviceName, const char *regType,
- const char *domain) {
+void MDnsSdListener::Handler::resolveService(SocketClient* cli, int requestId, uint32_t ifIndex,
+ const char* serviceName, const char* regType,
+ const char* domain) {
if (VDBG) {
- ALOGD("resolveService(%d, %s, %s, %s, %s)", requestId, interfaceName,
- serviceName, regType, domain);
+ ALOGD("resolveService(%d, %d, %s, %s, %s)", requestId, ifIndex, serviceName, regType,
+ domain);
}
Context *context = new Context(requestId, mListener);
DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
@@ -230,12 +258,11 @@ void MDnsSdListener::Handler::resolveService(SocketClient *cli, int requestId,
return;
}
DNSServiceFlags nativeFlags = 0;
- int interfaceInt = ifaceNameToI(interfaceName);
- DNSServiceErrorType result = DNSServiceResolve(ref, nativeFlags, interfaceInt, serviceName,
- regType, domain, &MDnsSdListenerResolveCallback, context);
+ DNSServiceErrorType result = DNSServiceResolve(ref, nativeFlags, ifIndex, serviceName, regType,
+ domain, &MDnsSdListenerResolveCallback, context);
if (result != kDNSServiceErr_NoError) {
- ALOGE("service resolve request %d got an error from DNSServiceResolve %d", requestId,
- result);
+ ALOGE("service resolve request %d on iface %d: got an error from DNSServiceResolve %d",
+ requestId, ifIndex, result);
mMonitor->freeServiceRef(requestId);
cli->sendMsg(ResponseCode::CommandParameterError,
"resolveService got an error from DNSServiceResolve", false);
@@ -248,9 +275,10 @@ void MDnsSdListener::Handler::resolveService(SocketClient *cli, int requestId,
}
void MDnsSdListenerResolveCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
- uint32_t /* interface */, DNSServiceErrorType errorCode, const char *fullname,
- const char *hosttarget, uint16_t port, uint16_t txtLen,
- const unsigned char *txtRecord , void *inContext) {
+ uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char* fullname, const char* hosttarget, uint16_t port,
+ uint16_t txtLen, const unsigned char* txtRecord,
+ void* inContext) {
MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
char *msg;
int refNumber = context->mRefNumber;
@@ -270,8 +298,8 @@ void MDnsSdListenerResolveCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /*
char *dst = (char *)malloc(dstLength);
b64_ntop(txtRecord, txtLen, dst, dstLength);
- asprintf(&msg, "%d %s %s %d %d \"%s\"", refNumber, quotedFullName, quotedHostTarget, port,
- txtLen, dst);
+ asprintf(&msg, "%d %s %s %d %d \"%s\" %d", refNumber, quotedFullName, quotedHostTarget,
+ port, txtLen, dst, ifIndex);
free(quotedFullName);
free(quotedHostTarget);
free(dst);
@@ -284,9 +312,9 @@ void MDnsSdListenerResolveCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /*
free(msg);
}
-void MDnsSdListener::Handler::getAddrInfo(SocketClient *cli, int requestId,
- const char *interfaceName, uint32_t protocol, const char *hostname) {
- if (VDBG) ALOGD("getAddrInfo(%d, %s %d, %s)", requestId, interfaceName, protocol, hostname);
+void MDnsSdListener::Handler::getAddrInfo(SocketClient* cli, int requestId, uint32_t ifIndex,
+ uint32_t protocol, const char* hostname) {
+ if (VDBG) ALOGD("getAddrInfo(%d, %u %d, %s)", requestId, ifIndex, protocol, hostname);
Context *context = new Context(requestId, mListener);
DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
if (ref == nullptr) {
@@ -296,9 +324,9 @@ void MDnsSdListener::Handler::getAddrInfo(SocketClient *cli, int requestId,
return;
}
DNSServiceFlags nativeFlags = 0;
- int interfaceInt = ifaceNameToI(interfaceName);
- DNSServiceErrorType result = DNSServiceGetAddrInfo(ref, nativeFlags, interfaceInt, protocol,
- hostname, &MDnsSdListenerGetAddrInfoCallback, context);
+ DNSServiceErrorType result =
+ DNSServiceGetAddrInfo(ref, nativeFlags, ifIndex, protocol, hostname,
+ &MDnsSdListenerGetAddrInfoCallback, context);
if (result != kDNSServiceErr_NoError) {
ALOGE("getAddrInfo request %d got an error from DNSServiceGetAddrInfo %d", requestId,
result);
@@ -314,10 +342,14 @@ void MDnsSdListener::Handler::getAddrInfo(SocketClient *cli, int requestId,
}
void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
- uint32_t /* interface */, DNSServiceErrorType errorCode, const char *hostname,
- const struct sockaddr *const sa, uint32_t ttl, void *inContext) {
+ uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char* hostname, const struct sockaddr* const sa,
+ uint32_t ttl, void* inContext) {
MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
int refNumber = context->mRefNumber;
+ unsigned netId = ifaceIndexToNetId(ifIndex);
+ // If the network is not found, still send a callback with an empty network
+ // and let the service decide what to do with it
if (errorCode != kDNSServiceErr_NoError) {
char *msg;
@@ -334,7 +366,8 @@ void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef /* sdRef */, DNSServiceFlag
} else {
inet_ntop(sa->sa_family, &(((struct sockaddr_in6 *)sa)->sin6_addr), addr, sizeof(addr));
}
- asprintf(&msg, "%d %s %d %s", refNumber, quotedHostname, ttl, addr);
+ asprintf(&msg, "%d %s %d %s %" PRIu32 " %u", refNumber, quotedHostname, ttl, addr, ifIndex,
+ netId);
free(quotedHostname);
context->mListener->sendBroadcast(ResponseCode::ServiceGetAddrInfoSuccess, msg, false);
if (VDBG) {
@@ -390,15 +423,6 @@ void MDnsSdListenerSetHostnameCallback(DNSServiceRef /* sdRef */, DNSServiceFlag
free(msg);
}
-
-int MDnsSdListener::Handler::ifaceNameToI(const char * /* iface */) {
- return 0;
-}
-
-const char *MDnsSdListener::Handler::iToIfaceName(int /* i */) {
- return nullptr;
-}
-
DNSServiceFlags MDnsSdListener::Handler::iToFlags(int /* i */) {
return 0;
}
@@ -421,15 +445,15 @@ int MDnsSdListener::Handler::runCommand(SocketClient *cli,
char* cmd = argv[1];
if (strcmp(cmd, "discover") == 0) {
- if (argc != 4) {
+ if (argc != 5) {
cli->sendMsg(ResponseCode::CommandParameterError,
"Invalid number of arguments to mdnssd discover", false);
return 0;
}
int requestId = strtol(argv[2], nullptr, 10);
char *serviceType = argv[3];
-
- discover(cli, nullptr, serviceType, nullptr, requestId, 0);
+ uint32_t interfaceIdx = atoi(argv[4]);
+ discover(cli, interfaceIdx, serviceType, nullptr, requestId, 0);
} else if (strcmp(cmd, "stop-discover") == 0) {
stop(cli, argc, argv, "discover");
} else if (strcmp(cmd, "register") == 0) {
@@ -462,17 +486,17 @@ int MDnsSdListener::Handler::runCommand(SocketClient *cli,
} else if (strcmp(cmd, "stop-register") == 0) {
stop(cli, argc, argv, "register");
} else if (strcmp(cmd, "resolve") == 0) {
- if (argc != 6) {
+ if (argc != 7) {
cli->sendMsg(ResponseCode::CommandParameterError,
"Invalid number of arguments to mdnssd resolve", false);
return 0;
}
int requestId = atoi(argv[2]);
- char *interfaceName = nullptr; // will use all
char *serviceName = argv[3];
char *regType = argv[4];
char *domain = argv[5];
- resolveService(cli, requestId, interfaceName, serviceName, regType, domain);
+ uint32_t interfaceIdx = atoi(argv[6]);
+ resolveService(cli, requestId, interfaceIdx, serviceName, regType, domain);
} else if (strcmp(cmd, "stop-resolve") == 0) {
stop(cli, argc, argv, "resolve");
} else if (strcmp(cmd, "start-service") == 0) {
@@ -499,16 +523,16 @@ int MDnsSdListener::Handler::runCommand(SocketClient *cli,
} else if (strcmp(cmd, "stop-sethostname") == 0) {
stop(cli, argc, argv, "sethostname");
} else if (strcmp(cmd, "getaddrinfo") == 0) {
- if (argc != 4) {
+ if (argc != 5) {
cli->sendMsg(ResponseCode::CommandParameterError,
"Invalid number of arguments to mdnssd getaddrinfo", false);
return 0;
}
int requestId = atoi(argv[2]);
char *hostname = argv[3];
- char *interfaceName = nullptr; // default
+ uint32_t ifIndex = atoi(argv[4]);
int protocol = 0; // intelligient heuristic (both v4 + v6)
- getAddrInfo(cli, requestId, interfaceName, protocol, hostname);
+ getAddrInfo(cli, requestId, ifIndex, protocol, hostname);
} else if (strcmp(cmd, "stop-getaddrinfo") == 0) {
stop(cli, argc, argv, "getaddrinfo");
} else {
diff --git a/server/MDnsSdListener.h b/server/MDnsSdListener.h
index 83cf23e3..48860dd6 100644
--- a/server/MDnsSdListener.h
+++ b/server/MDnsSdListener.h
@@ -26,25 +26,26 @@
#include "NetdCommand.h"
// callbacks
-void MDnsSdListenerDiscoverCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
- uint32_t interfaceIndex, DNSServiceErrorType errorCode,
- const char *serviceName, const char *regType, const char *replyDomain,
- void *inContext);
+void MDnsSdListenerDiscoverCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
+ DNSServiceErrorType errorCode, const char* serviceName,
+ const char* regType, const char* replyDomain, void* inContext);
void MDnsSdListenerRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
DNSServiceErrorType errorCode, const char *serviceName, const char *regType,
const char *domain, void *inContext);
-void MDnsSdListenerResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interface,
- DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port,
- uint16_t txtLen, const unsigned char *txtRecord, void *inContext);
+void MDnsSdListenerResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
+ DNSServiceErrorType errorCode, const char* fullname,
+ const char* hosttarget, uint16_t port, uint16_t txtLen,
+ const unsigned char* txtRecord, void* inContext);
void MDnsSdListenerSetHostnameCallback(DNSServiceRef, DNSServiceFlags flags,
DNSServiceErrorType errorCode, const char *hostname, void *inContext);
-void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
- uint32_t interface, DNSServiceErrorType errorCode, const char *hostname,
- const struct sockaddr *const sa, uint32_t ttl, void *inContext);
+void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
+ DNSServiceErrorType errorCode, const char* hostname,
+ const struct sockaddr* const sa, uint32_t ttl,
+ void* inContext);
class MDnsSdListener : public FrameworkListener {
public:
@@ -114,25 +115,21 @@ private:
private:
void stop(SocketClient *cli, int argc, char **argv, const char *str);
- void discover(SocketClient *cli, const char *iface, const char *regType,
- const char *domain, const int requestNumber,
- const int requestFlags);
+ void discover(SocketClient* cli, uint32_t ifIndex, const char* regType, const char* domain,
+ const int requestNumber, const int requestFlags);
void serviceRegister(SocketClient *cli, int requestId, const char *interfaceName,
const char *serviceName, const char *serviceType, const char *domain,
const char *host, int port, int textLen, void *txtRecord);
- void resolveService(SocketClient *cli, int requestId,
- const char *interfaceName, const char *serviceName, const char *regType,
- const char *domain);
+ void resolveService(SocketClient* cli, int requestId, uint32_t ifIndex,
+ const char* serviceName, const char* regType, const char* domain);
void setHostname(SocketClient *cli, int requestId, const char *hostname);
- void getAddrInfo(SocketClient *cli, int requestId, const char *interfaceName,
- uint32_t protocol, const char *hostname);
+ void getAddrInfo(SocketClient* cli, int requestId, uint32_t ifIndex, uint32_t protocol,
+ const char* hostname);
- int ifaceNameToI(const char *iface);
- const char *iToIfaceName(int i);
DNSServiceFlags iToFlags(int i);
int flagsToI(DNSServiceFlags flags);
Monitor *mMonitor;