]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSMacOSX/mDNSMacOSX.h
20f7a3216db0cdcf9f8f8fe70a37a153b7644176
[apple/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);
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 } KQSocketSet;
90
91 struct UDPSocket_struct
92 {
93 KQSocketSet ss; // First field of KQSocketSet has to be mDNSIPPort -- mDNSCore requires every UDPSocket_struct to begin with mDNSIPPort port
94 };
95
96 // TCP socket support
97
98 typedef enum
99 {
100 handshake_required,
101 handshake_in_progress,
102 handshake_completed,
103 handshake_to_be_closed
104 } handshakeStatus;
105
106 struct TCPSocket_struct
107 {
108 TCPSocketFlags flags; // MUST BE FIRST FIELD -- mDNSCore expects every TCPSocket_struct to begin with TCPSocketFlags flags
109 TCPConnectionCallback callback;
110 int fd;
111 KQueueEntry *kqEntry;
112 KQSocketSet ss;
113 #ifndef NO_SECURITYFRAMEWORK
114 SSLContextRef tlsContext;
115 pthread_t handshake_thread;
116 #endif /* NO_SECURITYFRAMEWORK */
117 domainname hostname;
118 void *context;
119 mDNSBool setup;
120 mDNSBool connected;
121 handshakeStatus handshake;
122 mDNS *m; // So we can call KQueueLock from the SSLHandshake thread
123 mStatus err;
124 };
125
126 struct NetworkInterfaceInfoOSX_struct
127 {
128 NetworkInterfaceInfo ifinfo; // MUST be the first element in this structure
129 NetworkInterfaceInfoOSX *next;
130 mDNS *m;
131 mDNSu8 Exists; // 1 = currently exists in getifaddrs list; 0 = doesn't
132 // 2 = exists, but McastTxRx state changed
133 mDNSu8 Flashing; // Set if interface appeared for less than 60 seconds and then vanished
134 mDNSu8 Occulting; // Set if interface vanished for less than 60 seconds and then came back
135 mDNSu8 D2DInterface; // IFEF_LOCALNET_PRIVATE flag indicates we should call
136 // D2D plugin for operations over this interface
137 mDNSs32 AppearanceTime; // Time this interface appeared most recently in getifaddrs list
138 // i.e. the first time an interface is seen, AppearanceTime is set.
139 // If an interface goes away temporarily and then comes back then
140 // AppearanceTime is updated to the time of the most recent appearance.
141 mDNSs32 LastSeen; // If Exists==0, last time this interface appeared in getifaddrs list
142 unsigned int ifa_flags;
143 struct in_addr ifa_v4addr;
144 mDNSu32 scope_id; // interface index / IPv6 scope ID
145 mDNSEthAddr BSSID; // BSSID of 802.11 base station, if applicable
146 u_short sa_family;
147 int BPF_fd; // -1 uninitialized; -2 requested BPF; -3 failed
148 int BPF_mcfd; // Socket for our IPv6 ND group membership
149 u_int BPF_len;
150 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
151 dispatch_source_t BPF_source;
152 #else
153 CFSocketRef BPF_cfs;
154 CFRunLoopSourceRef BPF_rls;
155 #endif
156 NetworkInterfaceInfoOSX *Registered; // non-NULL means registered with mDNS Core
157 };
158
159 struct mDNS_PlatformSupport_struct
160 {
161 NetworkInterfaceInfoOSX *InterfaceList;
162 KQSocketSet permanentsockets;
163 int num_mcasts; // Number of multicasts received during this CPU scheduling period (used for CPU limiting)
164 domainlabel userhostlabel; // The hostlabel as it was set in System Preferences the last time we looked
165 domainlabel usernicelabel; // The nicelabel as it was set in System Preferences the last time we looked
166 // Following four variables are used for optimization where the helper is not
167 // invoked when not needed. It records the state of what we told helper the
168 // last time we invoked mDNSPreferencesSetName
169 domainlabel prevoldhostlabel; // Previous m->p->userhostlabel
170 domainlabel prevnewhostlabel; // Previous m->hostlabel
171 domainlabel prevoldnicelabel; // Previous m->p->usernicelabel
172 domainlabel prevnewnicelabel; // Previous m->nicelabel
173 mDNSs32 NotifyUser;
174 mDNSs32 HostNameConflict; // Time we experienced conflict on our link-local host name
175 mDNSs32 KeyChainTimer;
176
177 SCDynamicStoreRef Store;
178 CFRunLoopSourceRef StoreRLS;
179 CFRunLoopSourceRef PMRLS;
180 int SysEventNotifier;
181 KQueueEntry SysEventKQueue;
182 IONotificationPortRef PowerPortRef;
183 io_connect_t PowerConnection;
184 io_object_t PowerNotifier;
185 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
186 IOPMConnection IOPMConnection;
187 #endif
188 IOPMAssertionID IOPMAssertion;
189 long SleepCookie; // Cookie we need to pass to IOAllowPowerChange()
190 long WakeAtUTC;
191 mDNSs32 RequestReSleep;
192 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
193 dispatch_source_t timer;
194 dispatch_source_t custom;
195 #else
196 pthread_mutex_t BigMutex;
197 #endif
198 mDNSs32 BigMutexStartTime;
199 int WakeKQueueLoopFD;
200 mDNSu8 v4answers; // non-zero if we are receiving answers
201 mDNSu8 v6answers; // for A/AAAA from external DNS servers
202 mDNSs32 DNSTrigger; // Time the DNSTrigger was given
203 uint64_t LastConfigGeneration; // DNS configuration generation number
204 UDPSocket UDPProxy;
205 TCPSocket TCPProxy;
206 ProxyCallback *UDPProxyCallback;
207 ProxyCallback *TCPProxyCallback;
208 };
209
210 extern int OfferSleepProxyService;
211 extern int DisableSleepProxyClient;
212 extern int UseInternalSleepProxy;
213 extern int OSXVers, iOSVers;
214
215 extern int KQueueFD;
216
217 extern void NotifyOfElusiveBug(const char *title, const char *msg); // Both strings are UTF-8 text
218 extern void SetDomainSecrets(mDNS *m);
219 extern void mDNSMacOSXNetworkChanged(mDNS *const m);
220 extern void mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring);
221 extern NetworkInterfaceInfoOSX *IfindexToInterfaceInfoOSX(const mDNS *const m, mDNSInterfaceID ifindex);
222 extern void mDNSUpdatePacketFilter(const ResourceRecord *const excludeRecord);
223 extern void myKQSocketCallBack(int s1, short filter, void *context);
224 extern void mDNSDynamicStoreSetConfig(int key, const char *subkey, CFPropertyListRef value);
225 extern void UpdateDebugState(void);
226
227 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
228 extern int KQueueSet(int fd, u_short flags, short filter, KQueueEntry *const entryRef);
229 mDNSexport void TriggerEventCompletion(void);
230 #else
231 extern int KQueueSet(int fd, u_short flags, short filter, const KQueueEntry *const entryRef);
232 #endif
233
234 // When events are processed on the non-kqueue thread (i.e. CFRunLoop notifications like Sleep/Wake,
235 // Interface changes, Keychain changes, etc.) they must use KQueueLock/KQueueUnlock to lock out the kqueue thread
236 extern void KQueueLock(mDNS *const m);
237 extern void KQueueUnlock(mDNS *const m, const char* task);
238 extern void mDNSPlatformCloseFD(KQueueEntry *kq, int fd);
239 extern ssize_t myrecvfrom(const int s, void *const buffer, const size_t max,
240 struct sockaddr *const from, size_t *const fromlen, mDNSAddr *dstaddr, char *ifname, mDNSu8 *ttl);
241
242 extern mDNSBool DictionaryIsEnabled(CFDictionaryRef dict);
243
244 extern void CUPInit(mDNS *const m);
245 extern const char *DNSScopeToString(mDNSu32 scope);
246
247 // If any event takes more than WatchDogReportingThreshold milliseconds to be processed, we log a warning message
248 // General event categories are:
249 // o Mach client request initiated / terminated
250 // o UDS client request
251 // o Handling UDP packets received from the network
252 // o Environmental change events:
253 // - network interface changes
254 // - sleep/wake
255 // - keychain changes
256 // o Name conflict dialog dismissal
257 // o Reception of Unix signal (e.g. SIGINFO)
258 // o Idle task processing
259 // If we find that we're getting warnings for any of these categories, and it's not evident
260 // what's causing the problem, we may need to subdivide some categories into finer-grained
261 // sub-categories (e.g. "Idle task processing" covers a pretty broad range of sub-tasks).
262
263 extern int WatchDogReportingThreshold;
264
265 struct CompileTimeAssertionChecks_mDNSMacOSX
266 {
267 // Check our structures are reasonable sizes. Including overly-large buffers, or embedding
268 // other overly-large structures instead of having a pointer to them, can inadvertently
269 // cause structure sizes (and therefore memory usage) to balloon unreasonably.
270
271 // Checks commented out when sizeof(DNSQuestion) change cascaded into having to change yet another
272 // set of hardcoded size values because these structures contain one or more DNSQuestion
273 // instances.
274 // char sizecheck_NetworkInterfaceInfoOSX[(sizeof(NetworkInterfaceInfoOSX) <= 7084) ? 1 : -1];
275 char sizecheck_mDNS_PlatformSupport [(sizeof(mDNS_PlatformSupport) <= 1378) ? 1 : -1];
276 };
277
278 #ifdef __cplusplus
279 }
280 #endif
281
282 #endif