]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCNetworkReachabilityInternal.h
69ad3af5685c2020e7436f161757629daade55fe
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkReachabilityInternal.h
1 /*
2 * Copyright (c) 2003-2013 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #ifndef _SCNETWORKREACHABILITYINTERNAL_H
25 #define _SCNETWORKREACHABILITYINTERNAL_H
26
27 #include <Availability.h>
28 #include <TargetConditionals.h>
29 #include <sys/cdefs.h>
30 #include <CoreFoundation/CoreFoundation.h>
31 #include <CoreFoundation/CFRuntime.h>
32 #include <SystemConfiguration/SystemConfiguration.h>
33 #include <SystemConfiguration/SCPrivate.h>
34 #include <dispatch/dispatch.h>
35
36 #include <dns_sd.h>
37 #include <netdb.h>
38 #include <sys/socket.h>
39 #include <net/if.h>
40
41 #if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000))
42 #define HAVE_REACHABILITY_SERVER
43 #include <xpc/xpc.h>
44 #endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000))
45
46 #if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
47 #define HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
48 #endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
49
50 #if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
51 #define HAVE_IPSEC_STATUS
52 #define HAVE_VPN_STATUS
53 #endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
54
55
56
57 #if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
58 #define USE_DNSSERVICEGETADDRINFO
59 #endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080/*FIXME*/) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
60
61
62 #pragma mark -
63 #pragma mark SCNetworkReachability
64
65
66 #define kSCNetworkReachabilityFlagsFirstResolvePending (1<<31)
67
68
69
70 #define kSCNetworkReachabilityFlagsMask 0x00ffffff // top 8-bits reserved for implementation
71
72
73 typedef enum {
74 NO = 0,
75 YES,
76 UNKNOWN
77 } lazyBoolean;
78
79
80 typedef enum {
81 reachabilityTypeAddress,
82 reachabilityTypeAddressPair,
83 reachabilityTypeName
84 } ReachabilityAddressType;
85
86
87 typedef struct {
88 uint64_t cycle;
89 SCNetworkReachabilityFlags flags;
90 unsigned int if_index;
91 char if_name[IFNAMSIZ];
92 Boolean sleeping;
93 } ReachabilityInfo;
94
95
96 typedef struct {
97
98 /* base CFType information */
99 CFRuntimeBase cfBase;
100
101 /* lock */
102 pthread_mutex_t lock;
103
104 /* address type */
105 ReachabilityAddressType type;
106
107 /* target host name */
108 const char *name;
109 Boolean needResolve;
110 CFArrayRef resolvedAddresses; /* CFArray[CFData] */
111 int resolvedError;
112 SCNetworkReachabilityFlags resolverFlags;
113
114 /* [scoped routing] interface constraints */
115 unsigned int if_index;
116 char if_name[IFNAMSIZ];
117
118 /* local & remote addresses */
119 struct sockaddr *localAddress;
120 struct sockaddr *remoteAddress;
121
122 /* current reachability flags */
123 uint64_t cycle;
124 ReachabilityInfo info;
125 ReachabilityInfo last_notify;
126
127 /* run loop source, callout, context, rl scheduling info */
128 Boolean scheduled;
129 CFRunLoopSourceRef rls;
130 SCNetworkReachabilityCallBack rlsFunction;
131 SCNetworkReachabilityContext rlsContext;
132 CFMutableArrayRef rlList;
133
134 dispatch_group_t dispatchGroup;
135 dispatch_queue_t dispatchQueue; // SCNetworkReachabilitySetDispatchQueue
136
137 /* [async] DNS query info */
138 Boolean haveDNS;
139 mach_port_t dnsMP; // != MACH_PORT_NULL (if active)
140 CFMachPortRef dnsPort; // for CFRunLoop queries
141 CFRunLoopSourceRef dnsRLS; // for CFRunLoop queries
142 dispatch_source_t dnsSource; // for dispatch queries
143 struct timeval dnsQueryStart;
144 struct timeval dnsQueryEnd;
145
146 /* [async] processing info */
147 struct timeval last_dns;
148 struct timeval last_network;
149 #if !TARGET_OS_IPHONE
150 struct timeval last_power;
151 #endif // !TARGET_OS_IPHONE
152 struct timeval last_push;
153
154 /* on demand info */
155 Boolean onDemandBypass;
156 CFStringRef onDemandName;
157 CFStringRef onDemandRemoteAddress;
158 SCNetworkReachabilityRef onDemandServer;
159 CFStringRef onDemandServiceID;
160
161
162 union {
163 uint32_t dnsFlags;
164 struct {
165 Boolean dnsActive :1; // if DNSServiceGetAddrInfo active
166
167 Boolean dnsHaveError :1; // error during query
168 Boolean dnsHaveV4 :1; // have IPv4 (A) reply
169 Boolean dnsHaveV6 :1; // have IPv6 (AAAA) reply
170 Boolean dnsHaveTimeout:1; // no replies (A and/or AAAA)
171 };
172 };
173 CFArrayRef dnsAddresses; // CFArray[CFData]
174 Boolean dnsBlocked; // if DNS query blocked
175 int dnsError;
176 DNSServiceRef dnsMain;
177 DNSServiceRef dnsTarget;
178
179 #ifdef HAVE_REACHABILITY_SERVER
180 /* SCNetworkReachability server "client" info */
181 Boolean serverActive;
182 Boolean serverBypass;
183 Boolean serverScheduled;
184 ReachabilityInfo serverInfo;
185
186 /* SCNetworkReachability server "server" info */
187 CFDataRef serverDigest;
188 dispatch_group_t serverGroup;
189 Boolean serverInfoValid;
190 unsigned int serverSyncQueryActive; // 0 == no [sync] query active, else # waiting on group
191 dispatch_queue_t serverQueue;
192 unsigned int serverReferences; // how many [client] targets
193 CFMutableDictionaryRef serverWatchers; // [client_id/target_id] watchers
194
195 Boolean useVPNAppLayer; // if App-Layer VPN, only use client mode
196 #endif // HAVE_REACHABILITY_SERVER
197 Boolean resolverBypass; // set this flag to bypass resolving the name
198
199
200
201 /* logging */
202 char log_prefix[32];
203
204 } SCNetworkReachabilityPrivate, *SCNetworkReachabilityPrivateRef;
205
206
207 #ifdef HAVE_REACHABILITY_SERVER
208
209 // ------------------------------------------------------------
210
211 #pragma mark -
212 #pragma mark [XPC] Reachability Server
213
214
215 #define REACH_SERVER_VERSION 20110323
216
217 #if !TARGET_IPHONE_SIMULATOR
218 #define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability"
219 #else // !TARGET_IPHONE_SIMULATOR
220 #define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability_sim"
221 #endif // !TARGET_IPHONE_SIMULATOR
222
223 // ------------------------------------------------------------
224
225
226 #pragma mark -
227 #pragma mark [XPC] Reachability Server (client->server request)
228
229
230 #define REACH_CLIENT_PROC_NAME "proc_name" // string
231 #define REACH_CLIENT_TARGET_ID "target_id" // uint64
232
233 #define REACH_REQUEST "request_op" // int64
234
235 enum {
236 REACH_REQUEST_CREATE = 0x0001,
237 REACH_REQUEST_REMOVE,
238 REACH_REQUEST_SCHEDULE,
239 REACH_REQUEST_STATUS,
240 REACH_REQUEST_UNSCHEDULE,
241 REACH_REQUEST_SNAPSHOT = 0x0101,
242 };
243
244 #define REACH_TARGET_NAME "name" // string
245 #define REACH_TARGET_IF_INDEX "if_index" // int64
246 #define REACH_TARGET_IF_NAME "if_name" // string
247 #define REACH_TARGET_LOCAL_ADDR "local_address" // data (struct sockaddr)
248 #define REACH_TARGET_REMOTE_ADDR "remote_address" // data (struct sockaddr)
249 #define REACH_TARGET_ONDEMAND_BYPASS "ondemand_bypass" // bool
250 #define REACH_TARGET_RESOLVER_BYPASS "resolver_bypass" // bool
251
252
253 #define REACH_REQUEST_REPLY "reply" // int64
254 #define REACH_REQUEST_REPLY_DETAIL "reply_detail" // string
255
256 enum {
257 REACH_REQUEST_REPLY_OK = 0x0000,
258 REACH_REQUEST_REPLY_FAILED,
259 REACH_REQUEST_REPLY_UNKNOWN,
260 };
261
262
263 // ------------------------------------------------------------
264
265
266 #pragma mark -
267 #pragma mark [XPC] Reachability Server (server->client request)
268
269
270 #define MESSAGE_NOTIFY "notify_op" // int64
271
272 enum {
273 MESSAGE_REACHABILITY_STATUS = 0x1001,
274 };
275
276 #define REACH_STATUS_CYCLE "cycle" // uint64
277 #define REACH_STATUS_FLAGS "flags" // uint64
278 #define REACH_STATUS_IF_INDEX "if_index" // uint64
279 #define REACH_STATUS_IF_NAME "if_name" // data (char if_name[IFNAMSIZ])
280 #define REACH_STATUS_RESOLVED_ADDRESSES "resolved_addresses" // array[data]
281 #define REACH_STATUS_RESOLVED_ERROR "resolved_error" // int64
282 #define REACH_STATUS_SLEEPING "sleeping" // bool
283
284
285 // ------------------------------------------------------------
286
287 #endif // HAVE_REACHABILITY_SERVER
288
289
290 __BEGIN_DECLS
291
292 CFStringRef
293 _SCNetworkReachabilityCopyTargetDescription (SCNetworkReachabilityRef target);
294
295 CFStringRef
296 _SCNetworkReachabilityCopyTargetFlags (SCNetworkReachabilityRef target);
297
298 void
299 __SCNetworkReachabilityPerform (SCNetworkReachabilityRef target);
300
301 void
302 __SCNetworkReachabilityPerformConcurrent (SCNetworkReachabilityRef target);
303
304 #ifdef HAVE_REACHABILITY_SERVER
305
306 dispatch_queue_t
307 __SCNetworkReachability_concurrent_queue (void);
308
309 #pragma mark -
310 #pragma mark [XPC] Reachability Server (client APIs)
311
312 Boolean
313 _SCNetworkReachabilityServer_snapshot (void);
314
315 Boolean
316 __SCNetworkReachabilityServer_targetAdd (SCNetworkReachabilityRef target);
317
318 void
319 __SCNetworkReachabilityServer_targetRemove (SCNetworkReachabilityRef target);
320
321 Boolean
322 __SCNetworkReachabilityServer_targetSchedule (SCNetworkReachabilityRef target);
323
324 Boolean
325 __SCNetworkReachabilityServer_targetStatus (SCNetworkReachabilityRef target);
326
327 Boolean
328 __SCNetworkReachabilityServer_targetUnschedule (SCNetworkReachabilityRef target);
329
330
331 Boolean
332 __SC_checkResolverReachabilityInternal (SCDynamicStoreRef *storeP,
333 SCNetworkReachabilityFlags *flags,
334 Boolean *haveDNS,
335 const char *nodename,
336 uint32_t *resolver_if_index,
337 int *dns_config_index);
338
339 #endif // HAVE_REACHABILITY_SERVER
340
341 static __inline__ void
342 __SCNetworkReachabilityPrintFlags(SCNetworkReachabilityFlags flags)
343 {
344 if (flags != 0) {
345 if (flags & kSCNetworkReachabilityFlagsReachable) {
346 SCPrint(TRUE, stdout, CFSTR("Reachable"));
347 flags &= ~kSCNetworkReachabilityFlagsReachable;
348 SCPrint(flags != 0, stdout, CFSTR(","));
349 }
350 if (flags & kSCNetworkReachabilityFlagsTransientConnection) {
351 SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
352 flags &= ~kSCNetworkReachabilityFlagsTransientConnection;
353 SCPrint(flags != 0, stdout, CFSTR(","));
354 }
355 if (flags & kSCNetworkReachabilityFlagsConnectionRequired) {
356 SCPrint(TRUE, stdout, CFSTR("Connection Required"));
357 flags &= ~kSCNetworkReachabilityFlagsConnectionRequired;
358 SCPrint(flags != 0, stdout, CFSTR(","));
359 }
360 if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) {
361 SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Traffic"));
362 flags &= ~kSCNetworkReachabilityFlagsConnectionOnTraffic;
363 SCPrint(flags != 0, stdout, CFSTR(","));
364 }
365 if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) {
366 SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Demand"));
367 flags &= ~kSCNetworkReachabilityFlagsConnectionOnDemand;
368 SCPrint(flags != 0, stdout, CFSTR(","));
369 }
370 if (flags & kSCNetworkReachabilityFlagsInterventionRequired) {
371 SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
372 flags &= ~kSCNetworkReachabilityFlagsInterventionRequired;
373 SCPrint(flags != 0, stdout, CFSTR(","));
374 }
375 if (flags & kSCNetworkReachabilityFlagsIsLocalAddress) {
376 SCPrint(TRUE, stdout, CFSTR("Local Address"));
377 flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress;
378 SCPrint(flags != 0, stdout, CFSTR(","));
379 }
380 if (flags & kSCNetworkReachabilityFlagsIsDirect) {
381 SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
382 flags &= ~kSCNetworkReachabilityFlagsIsDirect;
383 SCPrint(flags != 0, stdout, CFSTR(","));
384 }
385 #if TARGET_OS_IPHONE
386 if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
387 SCPrint(TRUE, stdout, CFSTR("WWAN"));
388 flags &= ~kSCNetworkReachabilityFlagsIsWWAN;
389 SCPrint(flags != 0, stdout, CFSTR(","));
390 }
391 #endif // TARGET_OS_IPHONE
392 if (flags != 0) {
393 SCPrint(TRUE, stdout, CFSTR("0x%08x"), flags);
394 }
395 } else {
396 SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
397 }
398
399 return;
400 }
401
402
403 __END_DECLS
404
405 #endif // _SCNETWORKREACHABILITYINTERNAL_H