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