Imported Upstream version 878.70.2
[platform/upstream/mdnsresponder.git] / mDNSMacOSX / mDNSMacOSX.h
1 /* -*- Mode: C; tab-width: 4 -*-
2  *
3  * Copyright (c) 2002-2015 Apple Inc. All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #ifndef __mDNSMacOSX_h
19 #define __mDNSMacOSX_h
20
21 #ifdef  __cplusplus
22 extern "C" {
23 #endif
24
25 #include <SystemConfiguration/SystemConfiguration.h>
26 #include <IOKit/pwr_mgt/IOPM.h>
27 #include <IOKit/pwr_mgt/IOPMLib.h>
28 #include <IOKit/pwr_mgt/IOPMLibPrivate.h>
29 #include <sys/socket.h>
30 #include <netinet/in.h>
31 #include "mDNSEmbeddedAPI.h"  // for domain name structure
32
33 #include <net/if.h>
34 #include <os/log.h>
35
36 //#define MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
37 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
38 #include <dispatch/dispatch.h>
39 #include <dispatch/private.h>
40 #endif
41
42 #if TARGET_OS_EMBEDDED
43 #define NO_SECURITYFRAMEWORK 1
44 #define NO_CFUSERNOTIFICATION 1
45 #include <MobileGestalt.h> // for IsAppleTV()
46 #endif
47
48 #ifndef NO_SECURITYFRAMEWORK
49 #include <Security/SecureTransport.h>
50 #include <Security/Security.h>
51 #endif /* NO_SECURITYFRAMEWORK */
52
53 enum mDNSDynamicStoreSetConfigKey
54 {
55     kmDNSMulticastConfig = 1,
56     kmDNSDynamicConfig,
57     kmDNSPrivateConfig,
58     kmDNSBackToMyMacConfig,
59     kmDNSSleepProxyServersState,
60     kmDNSDebugState, 
61 };
62
63 typedef struct NetworkInterfaceInfoOSX_struct NetworkInterfaceInfoOSX;
64
65 typedef void (*KQueueEventCallback)(int fd, short filter, void *context, mDNSBool encounteredEOF);
66 typedef struct
67 {
68     KQueueEventCallback KQcallback;
69     void                *KQcontext;
70     const char          *KQtask;        // For debugging messages
71 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
72     dispatch_source_t readSource;
73     dispatch_source_t writeSource;
74     mDNSBool fdClosed;
75 #endif
76 } KQueueEntry;
77
78 typedef struct
79 {
80     mDNSIPPort port; // MUST BE FIRST FIELD -- UDPSocket_struct begins with a KQSocketSet,
81     // and mDNSCore requires every UDPSocket_struct to begin with a mDNSIPPort port
82     mDNS                    *m;
83     int sktv4;
84     KQueueEntry kqsv4;
85     int sktv6;
86     KQueueEntry kqsv6;
87     int                     *closeFlag;
88     mDNSBool proxy;
89     mDNSBool sktv4EOF;
90     mDNSBool sktv6EOF;
91 } KQSocketSet;
92
93 struct UDPSocket_struct
94 {
95     KQSocketSet ss;     // First field of KQSocketSet has to be mDNSIPPort -- mDNSCore requires every UDPSocket_struct to begin with mDNSIPPort port
96 };
97
98 // TCP socket support
99
100 typedef enum
101 {
102     handshake_required,
103     handshake_in_progress,
104     handshake_completed,
105     handshake_to_be_closed
106 } handshakeStatus;
107
108 struct TCPSocket_struct
109 {
110     TCPSocketFlags flags;       // MUST BE FIRST FIELD -- mDNSCore expects every TCPSocket_struct to begin with TCPSocketFlags flags
111     TCPConnectionCallback callback;
112     int fd;
113     KQueueEntry *kqEntry;
114     KQSocketSet ss;
115 #ifndef NO_SECURITYFRAMEWORK
116     SSLContextRef tlsContext;
117     pthread_t handshake_thread;
118 #endif /* NO_SECURITYFRAMEWORK */
119     domainname hostname;
120     void *context;
121     mDNSBool setup;
122     mDNSBool connected;
123     handshakeStatus handshake;
124     mDNS *m; // So we can call KQueueLock from the SSLHandshake thread
125     mStatus err;
126 };
127
128 // Value assiged to 'Exists' to indicate the multicast state of the interface has changed.
129 #define MulticastStateChanged   2
130
131 struct NetworkInterfaceInfoOSX_struct
132 {
133     NetworkInterfaceInfo ifinfo;                // MUST be the first element in this structure
134     NetworkInterfaceInfoOSX *next;
135     mDNS                    *m;
136     mDNSu8 Exists;                              // 1 = currently exists in getifaddrs list; 0 = doesn't
137                                                 // 2 = exists, but McastTxRx state changed
138     mDNSu8 Flashing;                            // Set if interface appeared for less than 60 seconds and then vanished
139     mDNSu8 Occulting;                           // Set if interface vanished for less than 60 seconds and then came back
140     mDNSu8 D2DInterface;                        // IFEF_LOCALNET_PRIVATE flag indicates we should call
141                                                 // D2D plugin for operations over this interface
142     mDNSs32 AppearanceTime;                     // Time this interface appeared most recently in getifaddrs list
143                                                 // i.e. the first time an interface is seen, AppearanceTime is set.
144                                                 // If an interface goes away temporarily and then comes back then
145                                                 // AppearanceTime is updated to the time of the most recent appearance.
146     mDNSs32 LastSeen;                           // If Exists==0, last time this interface appeared in getifaddrs list
147     unsigned int ifa_flags;
148     struct in_addr ifa_v4addr;
149     mDNSu32 scope_id;                           // interface index / IPv6 scope ID
150     mDNSEthAddr BSSID;                          // BSSID of 802.11 base station, if applicable
151     u_short sa_family;
152     int BPF_fd;                                 // -1 uninitialized; -2 requested BPF; -3 failed
153     int BPF_mcfd;                               // Socket for our IPv6 ND group membership
154     u_int BPF_len;
155     mDNSBool isExpensive;                       // True if this interface has the IFEF_EXPENSIVE flag set.
156 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
157     dispatch_source_t BPF_source;
158 #else
159     CFSocketRef BPF_cfs;
160     CFRunLoopSourceRef BPF_rls;
161 #endif
162     NetworkInterfaceInfoOSX *Registered;        // non-NULL means registered with mDNS Core
163 };
164
165 struct mDNS_PlatformSupport_struct
166 {
167     NetworkInterfaceInfoOSX *InterfaceList;
168     KQSocketSet permanentsockets;
169     int num_mcasts;                             // Number of multicasts received during this CPU scheduling period (used for CPU limiting)
170     domainlabel userhostlabel;                  // The hostlabel as it was set in System Preferences the last time we looked
171     domainlabel usernicelabel;                  // The nicelabel as it was set in System Preferences the last time we looked
172     // Following four variables are used for optimization where the helper is not
173     // invoked when not needed. It records the state of what we told helper the
174     // last time we invoked mDNSPreferencesSetName
175     domainlabel prevoldhostlabel;               // Previous m->p->userhostlabel
176     domainlabel prevnewhostlabel;               // Previous m->hostlabel
177     domainlabel prevoldnicelabel;               // Previous m->p->usernicelabel
178     domainlabel prevnewnicelabel;               // Previous m->nicelabel
179     mDNSs32 NotifyUser;
180     mDNSs32 HostNameConflict;                   // Time we experienced conflict on our link-local host name
181     mDNSs32 KeyChainTimer;
182
183     SCDynamicStoreRef Store;
184     CFRunLoopSourceRef StoreRLS;
185     CFRunLoopSourceRef PMRLS;
186     int SysEventNotifier;
187     KQueueEntry SysEventKQueue;
188     IONotificationPortRef PowerPortRef;
189     io_connect_t PowerConnection;
190     io_object_t PowerNotifier;
191 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
192     IOPMConnection IOPMConnection;
193 #endif
194     IOPMAssertionID IOPMAssertion;
195     long SleepCookie;                           // Cookie we need to pass to IOAllowPowerChange()
196     long WakeAtUTC;
197     mDNSs32 RequestReSleep;
198 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
199     dispatch_source_t timer;
200     dispatch_source_t custom;
201 #else
202     pthread_mutex_t BigMutex;
203 #endif
204     mDNSs32 BigMutexStartTime;
205     int WakeKQueueLoopFD;
206     mDNSu8 v4answers;                  // non-zero if we are receiving answers
207     mDNSu8 v6answers;                  // for A/AAAA from external DNS servers
208     mDNSs32 DNSTrigger;                // Time the DNSTrigger was given
209     uint64_t LastConfigGeneration;     // DNS configuration generation number
210     UDPSocket UDPProxy;
211     TCPSocket TCPProxy;
212     ProxyCallback *UDPProxyCallback;
213     ProxyCallback *TCPProxyCallback;
214 };
215
216 extern int OfferSleepProxyService;
217 extern int DisableSleepProxyClient;
218 extern int UseInternalSleepProxy;
219 extern int OSXVers, iOSVers;
220
221 extern int KQueueFD;
222
223 extern void NotifyOfElusiveBug(const char *title, const char *msg); // Both strings are UTF-8 text
224 extern void SetDomainSecrets(mDNS *m);
225 extern void mDNSMacOSXNetworkChanged(void);
226 extern void mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring);
227 extern NetworkInterfaceInfoOSX *IfindexToInterfaceInfoOSX(mDNSInterfaceID ifindex);
228 extern void mDNSUpdatePacketFilter(const ResourceRecord *const excludeRecord);
229 extern void myKQSocketCallBack(int s1, short filter, void *context, mDNSBool encounteredEOF);
230 extern void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropertyListRef value);
231 extern void UpdateDebugState(void);
232
233 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
234 extern int KQueueSet(int fd, u_short flags, short filter, KQueueEntry *const entryRef);
235 mDNSexport void TriggerEventCompletion(void);
236 #else
237 extern int KQueueSet(int fd, u_short flags, short filter, const KQueueEntry *const entryRef);
238 #endif
239
240 // When events are processed on the non-kqueue thread (i.e. CFRunLoop notifications like Sleep/Wake,
241 // Interface changes, Keychain changes, etc.) they must use KQueueLock/KQueueUnlock to lock out the kqueue thread
242 extern void KQueueLock(void);
243 extern void KQueueUnlock(const char* task);
244 extern void mDNSPlatformCloseFD(KQueueEntry *kq, int fd);
245 extern ssize_t myrecvfrom(const int s, void *const buffer, const size_t max,
246                              struct sockaddr *const from, size_t *const fromlen, mDNSAddr *dstaddr, char *ifname, mDNSu8 *ttl);
247
248 extern mDNSBool DictionaryIsEnabled(CFDictionaryRef dict);
249
250 extern const char *DNSScopeToString(mDNSu32 scope);
251
252 // If any event takes more than WatchDogReportingThreshold milliseconds to be processed, we log a warning message
253 // General event categories are:
254 //  o Mach client request initiated / terminated
255 //  o UDS client request
256 //  o Handling UDP packets received from the network
257 //  o Environmental change events:
258 //    - network interface changes
259 //    - sleep/wake
260 //    - keychain changes
261 //  o Name conflict dialog dismissal
262 //  o Reception of Unix signal (e.g. SIGINFO)
263 //  o Idle task processing
264 // If we find that we're getting warnings for any of these categories, and it's not evident
265 // what's causing the problem, we may need to subdivide some categories into finer-grained
266 // sub-categories (e.g. "Idle task processing" covers a pretty broad range of sub-tasks).
267
268 extern int WatchDogReportingThreshold;
269
270 struct CompileTimeAssertionChecks_mDNSMacOSX
271 {
272     // Check our structures are reasonable sizes. Including overly-large buffers, or embedding
273     // other overly-large structures instead of having a pointer to them, can inadvertently
274     // cause structure sizes (and therefore memory usage) to balloon unreasonably.
275     char sizecheck_NetworkInterfaceInfoOSX[(sizeof(NetworkInterfaceInfoOSX) <=  7464) ? 1 : -1];
276     char sizecheck_mDNS_PlatformSupport   [(sizeof(mDNS_PlatformSupport)    <=  1378) ? 1 : -1];
277 };
278
279 extern mDNSInterfaceID AWDLInterfaceID;
280 void initializeD2DPlugins(mDNS *const m);
281 void terminateD2DPlugins(void);
282
283 #ifdef  __cplusplus
284 }
285 #endif
286
287 #endif