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