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