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