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