diff options
author | Remi NGUYEN VAN <reminv@google.com> | 2022-02-04 12:07:38 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2022-02-04 12:07:38 +0000 |
commit | 2b9afc40ff8ddb93c44d1518080e6c44df7400ad (patch) | |
tree | b5a1ae9fd76a1c2b51210b2ab0237edf0f53b8a7 | |
parent | fc745d1868262e0eec998615dc7621fcb9240328 (diff) | |
parent | a0b196b3c8397ba0938eacf20045cc817e96b8c9 (diff) | |
download | netd-android-s-v2-beta-3.tar.gz |
Merge "Support discover/resolve on specific interfaces"android-t-preview-2android-t-preview-1android-t-beta-3android-s-v2-beta-3android-s-qpr3-beta-1android-t-preview-1android-s-v2-beta-3android-s-qpr3-beta-1
-rw-r--r-- | server/MDnsSdListener.cpp | 144 | ||||
-rw-r--r-- | server/MDnsSdListener.h | 37 |
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; |