• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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