1 /* 2 * Copyright (C) 2012 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 17 #ifndef _MDNSSDLISTENER_H__ 18 #define _MDNSSDLISTENER_H__ 19 20 #include <android-base/thread_annotations.h> 21 #include <dns_sd.h> 22 #include <sysutils/FrameworkListener.h> 23 #include <mutex> 24 #include <string> 25 26 #include "NetdCommand.h" 27 28 // callbacks 29 void MDnsSdListenerDiscoverCallback(DNSServiceRef sdRef, DNSServiceFlags flags, 30 uint32_t interfaceIndex, DNSServiceErrorType errorCode, 31 const char *serviceName, const char *regType, const char *replyDomain, 32 void *inContext); 33 34 void MDnsSdListenerRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags, 35 DNSServiceErrorType errorCode, const char *serviceName, const char *regType, 36 const char *domain, void *inContext); 37 38 void MDnsSdListenerResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interface, 39 DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port, 40 uint16_t txtLen, const unsigned char *txtRecord, void *inContext); 41 42 void MDnsSdListenerSetHostnameCallback(DNSServiceRef, DNSServiceFlags flags, 43 DNSServiceErrorType errorCode, const char *hostname, void *inContext); 44 45 void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef sdRef, DNSServiceFlags flags, 46 uint32_t interface, DNSServiceErrorType errorCode, const char *hostname, 47 const struct sockaddr *const sa, uint32_t ttl, void *inContext); 48 49 class MDnsSdListener : public FrameworkListener { 50 public: 51 MDnsSdListener(); ~MDnsSdListener()52 virtual ~MDnsSdListener() {} 53 54 static constexpr const char* SOCKET_NAME = "mdns"; 55 56 class Context { 57 public: 58 MDnsSdListener *mListener; 59 int mRefNumber; 60 Context(int refNumber,MDnsSdListener * m)61 Context(int refNumber, MDnsSdListener *m) { 62 mRefNumber = refNumber; 63 mListener = m; 64 } 65 ~Context()66 ~Context() { 67 } 68 }; 69 70 private: 71 class Monitor { 72 public: 73 Monitor(); ~Monitor()74 virtual ~Monitor() {} 75 DNSServiceRef *allocateServiceRef(int id, Context *c); 76 void startMonitoring(int id); 77 DNSServiceRef *lookupServiceRef(int id); 78 void freeServiceRef(int id); 79 int startService(); 80 int stopService(); 81 void run(); 82 void deallocateServiceRef(DNSServiceRef* ref); threadName()83 std::string threadName() { return std::string("MDnsSdMonitor"); } 84 85 private: 86 int rescan(); // returns the number of elements in the poll 87 88 struct Element { ElementElement89 Element(int id, Context* context) : mId(id), mContext(context) {} ~ElementElement90 ~Element() { delete mContext; } 91 92 int mId; 93 Element* mNext = nullptr; 94 DNSServiceRef mRef = nullptr; 95 Context *mContext; 96 int mReady = 0; 97 }; 98 Element* mHead GUARDED_BY(mMutex); 99 int mLiveCount; 100 struct pollfd *mPollFds; 101 DNSServiceRef **mPollRefs; 102 int mPollSize; 103 int mCtrlSocketPair[2]; 104 std::mutex mMutex; 105 }; 106 107 class Handler : public NetdCommand { 108 public: 109 Handler(Monitor *m, MDnsSdListener *listener); 110 virtual ~Handler(); 111 int runCommand(SocketClient *c, int argc, char** argv); 112 113 MDnsSdListener *mListener; // needed for broadcast purposes 114 private: 115 void stop(SocketClient *cli, int argc, char **argv, const char *str); 116 117 void discover(SocketClient *cli, const char *iface, const char *regType, 118 const char *domain, const int requestNumber, 119 const int requestFlags); 120 121 void serviceRegister(SocketClient *cli, int requestId, const char *interfaceName, 122 const char *serviceName, const char *serviceType, const char *domain, 123 const char *host, int port, int textLen, void *txtRecord); 124 125 void resolveService(SocketClient *cli, int requestId, 126 const char *interfaceName, const char *serviceName, const char *regType, 127 const char *domain); 128 129 void setHostname(SocketClient *cli, int requestId, const char *hostname); 130 131 void getAddrInfo(SocketClient *cli, int requestId, const char *interfaceName, 132 uint32_t protocol, const char *hostname); 133 134 int ifaceNameToI(const char *iface); 135 const char *iToIfaceName(int i); 136 DNSServiceFlags iToFlags(int i); 137 int flagsToI(DNSServiceFlags flags); 138 Monitor *mMonitor; 139 }; 140 }; 141 142 #endif 143