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, uint32_t ifIndex, 30 DNSServiceErrorType errorCode, const char* serviceName, 31 const char* regType, const char* replyDomain, 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 ifIndex, 38 DNSServiceErrorType errorCode, const char* fullname, 39 const char* hosttarget, uint16_t port, uint16_t txtLen, 40 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, uint32_t ifIndex, 46 DNSServiceErrorType errorCode, const char* hostname, 47 const struct sockaddr* const sa, uint32_t ttl, 48 void* inContext); 49 50 class MDnsSdListener { 51 public: 52 static constexpr const char* SOCKET_NAME = "mdns"; 53 54 class Context { 55 public: 56 int mRefNumber; 57 Context(int refNumber)58 Context(int refNumber) { mRefNumber = refNumber; } 59 ~Context()60 ~Context() { 61 } 62 }; 63 64 int stop(int requestId); 65 66 int discover(uint32_t ifIndex, const char* regType, const char* domain, const int requestId, 67 const int requestFlags); 68 69 int serviceRegister(int requestId, const char* serviceName, const char* serviceType, 70 const char* domain, const char* host, int port, 71 const std::vector<unsigned char>& txtRecord, uint32_t ifIndex); 72 73 int resolveService(int requestId, uint32_t ifIndex, const char* serviceName, 74 const char* regType, const char* domain); 75 76 int getAddrInfo(int requestId, uint32_t ifIndex, uint32_t protocol, const char* hostname); 77 78 int startDaemon(); 79 80 int stopDaemon(); 81 82 private: 83 class Monitor { 84 public: 85 Monitor(); ~Monitor()86 virtual ~Monitor() {} 87 DNSServiceRef *allocateServiceRef(int id, Context *c); 88 void startMonitoring(int id); 89 DNSServiceRef *lookupServiceRef(int id); 90 void freeServiceRef(int id); 91 int startService(); 92 int stopService(); 93 void run(); 94 void deallocateServiceRef(DNSServiceRef* ref); threadName()95 std::string threadName() { return std::string("MDnsSdMonitor"); } 96 97 private: 98 int rescan(); // returns the number of elements in the poll 99 100 struct Element { ElementElement101 Element(int id, Context* context) : mId(id), mContext(context) {} ~ElementElement102 ~Element() { delete mContext; } 103 104 int mId; 105 Element* mNext = nullptr; 106 DNSServiceRef mRef = nullptr; 107 Context *mContext; 108 int mReady = 0; 109 }; 110 Element* mHead GUARDED_BY(mMutex); 111 int mLiveCount; 112 struct pollfd *mPollFds; 113 DNSServiceRef **mPollRefs; 114 int mPollSize; 115 int mCtrlSocketPair[2]; 116 std::mutex mMutex; 117 }; 118 Monitor mMonitor; 119 }; 120 121 #endif 122