1 /* -*- Mode: C; tab-width: 4; c-file-style: "bsd"; c-basic-offset: 4; fill-column: 108; indent-tabs-mode: nil; -*-
3 * Copyright (c) 2002-2018 Apple Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #ifndef __mDNSMacOSX_h
19 #define __mDNSMacOSX_h
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 #include "mdns_private.h" // for mdns_interface_monitor_t struct
37 //#define MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
38 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
39 #include <dispatch/dispatch.h>
40 #include <dispatch/private.h>
44 #define NO_SECURITYFRAMEWORK 1
45 #define NO_CFUSERNOTIFICATION 1
48 #ifndef NO_SECURITYFRAMEWORK
49 #include <Security/SecureTransport.h>
50 #include <Security/Security.h>
51 #endif /* NO_SECURITYFRAMEWORK */
53 enum mDNSDynamicStoreSetConfigKey
55 kmDNSMulticastConfig
= 1,
58 kmDNSBackToMyMacConfig
,
59 kmDNSSleepProxyServersState
,
63 typedef struct NetworkInterfaceInfoOSX_struct NetworkInterfaceInfoOSX
;
65 typedef void (*KQueueEventCallback
)(int fd
, short filter
, void *context
, mDNSBool encounteredEOF
);
68 KQueueEventCallback KQcallback
;
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
;
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
93 struct UDPSocket_struct
95 KQSocketSet ss
; // First field of KQSocketSet has to be mDNSIPPort -- mDNSCore requires every UDPSocket_struct to begin with mDNSIPPort port
103 handshake_in_progress
,
105 handshake_to_be_closed
108 struct TCPSocket_struct
110 mDNSIPPort port
; // MUST BE FIRST FIELD -- mDNSCore expects every TCPSocket_struct to begin with mDNSIPPort
111 TCPSocketFlags flags
; // MUST BE SECOND FIELD -- mDNSCore expects every TCPSocket_struct have TCPSocketFlags flags after mDNSIPPort
112 TCPConnectionCallback callback
;
115 #ifndef NO_SECURITYFRAMEWORK
116 SSLContextRef tlsContext
;
117 pthread_t handshake_thread
;
118 #endif /* NO_SECURITYFRAMEWORK */
119 domainname
*hostname
;
123 handshakeStatus handshake
;
124 mDNS
*m
; // So we can call KQueueLock from the SSLHandshake thread
128 struct TCPListener_struct
130 TCPAcceptedCallback callback
;
134 mDNSAddr_Type addressType
;
135 TCPSocketFlags socketFlags
;
136 mDNS
*m
; // So we can call KQueueLock from the SSLHandshake thread
139 // Value assiged to 'Exists' to indicate the multicast state of the interface has changed.
140 #define MulticastStateChanged 2
142 struct NetworkInterfaceInfoOSX_struct
144 NetworkInterfaceInfo ifinfo
; // MUST be the first element in this structure
145 NetworkInterfaceInfoOSX
*next
;
147 mDNSu8 Exists
; // 1 = currently exists in getifaddrs list; 0 = doesn't
148 // 2 = exists, but McastTxRx state changed
149 mDNSu8 Flashing
; // Set if interface appeared for less than 60 seconds and then vanished
150 mDNSu8 Occulting
; // Set if interface vanished for less than 60 seconds and then came back
151 mDNSu8 D2DInterface
; // IFEF_LOCALNET_PRIVATE flag indicates we should call
152 // D2D plugin for operations over this interface
153 mDNSs32 AppearanceTime
; // Time this interface appeared most recently in getifaddrs list
154 // i.e. the first time an interface is seen, AppearanceTime is set.
155 // If an interface goes away temporarily and then comes back then
156 // AppearanceTime is updated to the time of the most recent appearance.
157 mDNSs32 LastSeen
; // If Exists==0, last time this interface appeared in getifaddrs list
158 uint32_t ift_family
; // IFRTYPE_FAMILY_XXX
159 unsigned int ifa_flags
;
160 struct in_addr ifa_v4addr
;
161 mDNSu32 scope_id
; // interface index / IPv6 scope ID
162 mDNSEthAddr BSSID
; // BSSID of 802.11 base station, if applicable
164 int BPF_fd
; // -1 uninitialized; -2 requested BPF; -3 failed
165 int BPF_mcfd
; // Socket for our IPv6 ND group membership
167 mDNSBool isAWDL
; // True if this interface has the IFEF_AWDL flag set.
168 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
169 dispatch_source_t BPF_source
;
172 CFRunLoopSourceRef BPF_rls
;
174 NetworkInterfaceInfoOSX
*Registered
; // non-NULL means registered with mDNS Core
177 struct mDNS_PlatformSupport_struct
179 NetworkInterfaceInfoOSX
*InterfaceList
;
180 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER)
181 CFMutableArrayRef InterfaceMonitors
;
183 KQSocketSet permanentsockets
;
184 int num_mcasts
; // Number of multicasts received during this CPU scheduling period (used for CPU limiting)
185 domainlabel userhostlabel
; // The hostlabel as it was set in System Preferences the last time we looked
186 domainlabel usernicelabel
; // The nicelabel as it was set in System Preferences the last time we looked
187 // Following four variables are used for optimization where the helper is not
188 // invoked when not needed. It records the state of what we told helper the
189 // last time we invoked mDNSPreferencesSetName
190 domainlabel prevoldhostlabel
; // Previous m->p->userhostlabel
191 domainlabel prevnewhostlabel
; // Previous m->hostlabel
192 domainlabel prevoldnicelabel
; // Previous m->p->usernicelabel
193 domainlabel prevnewnicelabel
; // Previous m->nicelabel
195 mDNSs32 HostNameConflict
; // Time we experienced conflict on our link-local host name
196 mDNSs32 KeyChainTimer
;
198 SCDynamicStoreRef Store
;
199 CFRunLoopSourceRef StoreRLS
;
200 CFRunLoopSourceRef PMRLS
;
201 int SysEventNotifier
;
202 KQueueEntry SysEventKQueue
;
203 IONotificationPortRef PowerPortRef
;
204 io_connect_t PowerConnection
;
205 io_object_t PowerNotifier
;
206 #ifdef kIOPMAcknowledgmentOptionSystemCapabilityRequirements
207 IOPMConnection IOPMConnection
;
209 IOPMAssertionID IOPMAssertion
;
210 long SleepCookie
; // Cookie we need to pass to IOAllowPowerChange()
212 mDNSs32 RequestReSleep
;
213 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
214 dispatch_source_t timer
;
215 dispatch_source_t custom
;
217 pthread_mutex_t BigMutex
;
219 mDNSs32 BigMutexStartTime
;
220 int WakeKQueueLoopFD
;
221 mDNSu8 v4answers
; // non-zero if we are receiving answers
222 mDNSu8 v6answers
; // for A/AAAA from external DNS servers
223 mDNSs32 DNSTrigger
; // Time the DNSTrigger was given
224 uint64_t LastConfigGeneration
; // DNS configuration generation number
225 #if !MDNSRESPONDER_SUPPORTS(APPLE, QUERIER)
226 mDNSBool if_interface_changed
; // There are some changes that we do not know from LastConfigGeneration, such as
227 // if the interface is expensive/constrained or not. Therefore, we need an additional
228 // field to determine if the interface has changed.
231 TCPSocket TCPProxyV4
;
232 TCPSocket TCPProxyV6
;
233 ProxyCallback
*UDPProxyCallback
;
234 ProxyCallback
*TCPProxyCallback
;
237 extern int OfferSleepProxyService
;
238 extern int DisableSleepProxyClient
;
239 extern int UseInternalSleepProxy
;
240 extern int OSXVers
, iOSVers
;
244 extern void NotifyOfElusiveBug(const char *title
, const char *msg
); // Both strings are UTF-8 text
245 extern void SetDomainSecrets(mDNS
*m
);
246 extern void mDNSMacOSXNetworkChanged(void);
247 extern void mDNSMacOSXSystemBuildNumber(char *HINFO_SWstring
);
248 extern NetworkInterfaceInfoOSX
*IfindexToInterfaceInfoOSX(mDNSInterfaceID ifindex
);
249 extern void mDNSUpdatePacketFilter(const ResourceRecord
*const excludeRecord
);
250 extern void myKQSocketCallBack(int s1
, short filter
, void *context
, mDNSBool encounteredEOF
);
251 extern void mDNSDynamicStoreSetConfig(int key
, const char *subkey
, CFPropertyListRef value
);
252 extern void UpdateDebugState(void);
254 #ifdef MDNSRESPONDER_USES_LIB_DISPATCH_AS_PRIMARY_EVENT_LOOP_MECHANISM
255 extern int KQueueSet(int fd
, u_short flags
, short filter
, KQueueEntry
*const entryRef
);
256 mDNSexport
void TriggerEventCompletion(void);
258 extern int KQueueSet(int fd
, u_short flags
, short filter
, const KQueueEntry
*const entryRef
);
261 // When events are processed on the non-kqueue thread (i.e. CFRunLoop notifications like Sleep/Wake,
262 // Interface changes, Keychain changes, etc.) they must use KQueueLock/KQueueUnlock to lock out the kqueue thread
263 extern void KQueueLock(void);
264 extern void KQueueUnlock(const char* task
);
265 extern void mDNSPlatformCloseFD(KQueueEntry
*kq
, int fd
);
267 extern mDNSBool
DictionaryIsEnabled(CFDictionaryRef dict
);
269 // If any event takes more than WatchDogReportingThreshold milliseconds to be processed, we log a warning message
270 // General event categories are:
271 // o Mach client request initiated / terminated
272 // o UDS client request
273 // o Handling UDP packets received from the network
274 // o Environmental change events:
275 // - network interface changes
277 // - keychain changes
278 // o Name conflict dialog dismissal
279 // o Reception of Unix signal (e.g. SIGINFO)
280 // o Idle task processing
281 // If we find that we're getting warnings for any of these categories, and it's not evident
282 // what's causing the problem, we may need to subdivide some categories into finer-grained
283 // sub-categories (e.g. "Idle task processing" covers a pretty broad range of sub-tasks).
285 extern int WatchDogReportingThreshold
;
287 struct CompileTimeAssertionChecks_mDNSMacOSX
289 // Check our structures are reasonable sizes. Including overly-large buffers, or embedding
290 // other overly-large structures instead of having a pointer to them, can inadvertently
291 // cause structure sizes (and therefore memory usage) to balloon unreasonably.
292 char sizecheck_NetworkInterfaceInfoOSX
[(sizeof(NetworkInterfaceInfoOSX
) <= 8704) ? 1 : -1];
293 char sizecheck_mDNS_PlatformSupport
[(sizeof(mDNS_PlatformSupport
) <= 1378) ? 1 : -1];
296 extern mDNSInterfaceID AWDLInterfaceID
;
297 void initializeD2DPlugins(mDNS
*const m
);
298 void terminateD2DPlugins(void);
300 #if MDNSRESPONDER_SUPPORTS(APPLE, REACHABILITY_TRIGGER)
301 extern void mDNSPlatformUpdateDNSStatus(const DNSQuestion
*q
);
302 extern void mDNSPlatformTriggerDNSRetry(const DNSQuestion
*v4q
, const DNSQuestion
*v6q
);
305 extern mdns_interface_monitor_t
GetInterfaceMonitorForIndex(uint32_t ifIndex
);