]> git.saurik.com Git - apple/configd.git/blob - SystemConfiguration.fproj/SCNetworkReachabilityInternal.h
configd-699.1.5.tar.gz
[apple/configd.git] / SystemConfiguration.fproj / SCNetworkReachabilityInternal.h
1 /*
2 * Copyright (c) 2003-2014 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 #include <xpc/xpc.h>
41
42
43
44
45 #pragma mark -
46 #pragma mark SCNetworkReachability
47
48
49 #define kSCNetworkReachabilityFlagsFirstResolvePending (1<<31)
50
51
52
53 #define kSCNetworkReachabilityFlagsMask 0x00ffffff // top 8-bits reserved for implementation
54
55
56 typedef enum {
57 NO = 0,
58 YES,
59 UNKNOWN
60 } lazyBoolean;
61
62
63 typedef enum {
64 // by-address SCNetworkReachability targets
65 reachabilityTypeAddress,
66 reachabilityTypeAddressPair,
67 // by-name SCNetworkReachability targets
68 reachabilityTypeName,
69 reachabilityTypePTR
70 } ReachabilityAddressType;
71
72 #define isReachabilityTypeAddress(type) (type < reachabilityTypeName)
73 #define isReachabilityTypeName(type) (type >= reachabilityTypeName)
74
75
76 typedef struct {
77 uint64_t cycle;
78 SCNetworkReachabilityFlags flags;
79 unsigned int if_index;
80 char if_name[IFNAMSIZ];
81 Boolean sleeping;
82 } ReachabilityInfo;
83
84
85 typedef struct {
86
87 /* base CFType information */
88 CFRuntimeBase cfBase;
89
90 /* lock */
91 pthread_mutex_t lock;
92
93 /* logging */
94 Boolean quiet;
95
96 /* address type */
97 ReachabilityAddressType type;
98
99 /* target host name */
100 const char *name;
101 Boolean needResolve;
102 CFArrayRef resolvedAddresses; /* CFArray[CFData] or CFArray[CFString] */
103 int resolvedError;
104 SCNetworkReachabilityFlags resolverFlags;
105
106 /* [scoped routing] interface constraints */
107 unsigned int if_index;
108 char if_name[IFNAMSIZ];
109
110 /* local & remote addresses */
111 struct sockaddr *localAddress;
112 struct sockaddr *remoteAddress;
113
114 /* current reachability flags */
115 uint64_t cycle;
116 ReachabilityInfo info;
117 ReachabilityInfo last_notify;
118
119 /* run loop source, callout, context, rl scheduling info */
120 Boolean scheduled;
121 CFRunLoopSourceRef rls;
122 SCNetworkReachabilityCallBack rlsFunction;
123 SCNetworkReachabilityContext rlsContext;
124 CFMutableArrayRef rlList;
125 unsigned int pending; // 0 == no notifications queued, else # to be delivered
126
127 dispatch_group_t dispatchGroup;
128 dispatch_queue_t dispatchQueue; // SCNetworkReachabilitySetDispatchQueue
129
130 /* [async] DNS query info */
131 Boolean haveDNS;
132 struct timeval dnsQueryStart;
133 struct timeval dnsQueryEnd;
134
135 /* [async] processing info */
136 struct timeval last_dns;
137 struct timeval last_network;
138 #if !TARGET_OS_IPHONE
139 struct timeval last_power;
140 #endif // !TARGET_OS_IPHONE
141 struct timeval last_push;
142
143 /* on demand info */
144 Boolean onDemandBypass;
145 CFStringRef onDemandName;
146 CFStringRef onDemandRemoteAddress;
147 SCNetworkReachabilityRef onDemandServer;
148 CFStringRef onDemandServiceID;
149
150
151 union {
152 uint32_t dnsFlags;
153 struct {
154 Boolean dnsActive :1; // if DNSServiceGetAddrInfo active
155
156 Boolean dnsHaveError :1; // error during query
157 Boolean dnsHaveV4 :1; // have IPv4 (A) reply
158 Boolean dnsHaveV6 :1; // have IPv6 (AAAA) reply
159 Boolean dnsHavePTR :1; // have PTR reply
160 Boolean dnsHaveTimeout:1; // no replies (A, AAAA, or PTR)
161 };
162 };
163 CFArrayRef dnsAddresses; // CFArray[CFData]
164 Boolean dnsBlocked; // if DNS query blocked
165 int dnsError;
166 int dnsFailures; // # of unexpected DNSServiceXXX errors
167 int dnsGeneration;
168 DNSServiceRef dnsTarget;
169 Boolean dnsNoAddressesSinceLastTimeout;
170
171 /* SCNetworkReachability server "client" info */
172 Boolean serverActive;
173 Boolean serverBypass;
174 Boolean serverScheduled;
175 ReachabilityInfo serverInfo;
176
177 /* SCNetworkReachability server "server" info */
178 CFDataRef serverDigest;
179 dispatch_group_t serverGroup;
180 Boolean serverInfoValid;
181 unsigned int serverSyncQueryActive; // 0 == no [sync] query active, else # waiting on group
182 dispatch_queue_t serverQueue;
183 unsigned int serverReferences; // how many [client] targets
184 CFMutableDictionaryRef serverWatchers; // [client_id/target_id] watchers
185
186 Boolean useNEVPN;
187 uid_t uid;
188 void *nePolicyResult;
189 Boolean serverBypassForVPN; // if serverBypassForVPN, only use client mode
190
191 Boolean resolverBypass; // set this flag to bypass resolving the name
192
193
194
195 /* logging */
196 char log_prefix[32];
197
198 } SCNetworkReachabilityPrivate, *SCNetworkReachabilityPrivateRef;
199
200
201
202 // ------------------------------------------------------------
203
204 #pragma mark -
205 #pragma mark [XPC] Reachability Server
206
207
208 #define REACH_SERVER_VERSION 20110323
209
210 #if !TARGET_IPHONE_SIMULATOR
211 #define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability"
212 #else // !TARGET_IPHONE_SIMULATOR
213 #define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability_sim"
214 #endif // !TARGET_IPHONE_SIMULATOR
215
216 // ------------------------------------------------------------
217
218
219 #pragma mark -
220 #pragma mark [XPC] Reachability Server (client->server request)
221
222
223 #define REACH_CLIENT_PROC_NAME "proc_name" // string
224 #define REACH_CLIENT_TARGET_ID "target_id" // uint64
225
226 #define REACH_REQUEST "request_op" // int64
227
228 enum {
229 REACH_REQUEST_CREATE = 0x0001,
230 REACH_REQUEST_REMOVE,
231 REACH_REQUEST_SCHEDULE,
232 REACH_REQUEST_STATUS,
233 REACH_REQUEST_UNSCHEDULE,
234 REACH_REQUEST_SNAPSHOT = 0x0101,
235 };
236
237 #define REACH_TARGET_NAME "name" // string
238
239 #define REACH_TARGET_LOCAL_ADDR "local_address" // data (struct sockaddr)
240 #define REACH_TARGET_REMOTE_ADDR "remote_address" // data (struct sockaddr)
241
242 #define REACH_TARGET_PTR_ADDR "ptr_address" // data (struct sockaddr)
243
244 #define REACH_TARGET_IF_INDEX "if_index" // int64
245 #define REACH_TARGET_IF_NAME "if_name" // string
246 #define REACH_TARGET_ONDEMAND_BYPASS "ondemand_bypass" // bool
247 #define REACH_TARGET_RESOLVER_BYPASS "resolver_bypass" // bool
248
249
250 #define REACH_REQUEST_REPLY "reply" // int64
251 #define REACH_REQUEST_REPLY_DETAIL "reply_detail" // string
252
253 enum {
254 REACH_REQUEST_REPLY_OK = 0x0000,
255 REACH_REQUEST_REPLY_FAILED,
256 REACH_REQUEST_REPLY_UNKNOWN,
257 };
258
259
260 // ------------------------------------------------------------
261
262
263 #pragma mark -
264 #pragma mark [XPC] Reachability Server (server->client request)
265
266
267 #define MESSAGE_NOTIFY "notify_op" // int64
268
269 enum {
270 MESSAGE_REACHABILITY_STATUS = 0x1001,
271 };
272
273 #define REACH_STATUS_CYCLE "cycle" // uint64
274 #define REACH_STATUS_DNS_FLAGS "dns_flags" // uint64
275 #define REACH_STATUS_FLAGS "flags" // uint64
276 #define REACH_STATUS_IF_INDEX "if_index" // uint64
277 #define REACH_STATUS_IF_NAME "if_name" // data (char if_name[IFNAMSIZ])
278 #define REACH_STATUS_RESOLVED_ADDRESSES "resolved_addresses" // array[data]
279 #define REACH_STATUS_RESOLVED_ERROR "resolved_error" // int64
280 #define REACH_STATUS_SLEEPING "sleeping" // bool
281
282
283 // ------------------------------------------------------------
284
285
286 __BEGIN_DECLS
287
288 CFStringRef
289 _SCNetworkReachabilityCopyTargetDescription (SCNetworkReachabilityRef target);
290
291 CFStringRef
292 _SCNetworkReachabilityCopyTargetFlags (SCNetworkReachabilityRef target);
293
294 void
295 __SCNetworkReachabilityUpdate (SCNetworkReachabilityRef target);
296
297 void
298 __SCNetworkReachabilityUpdateConcurrent (SCNetworkReachabilityRef target);
299
300 dispatch_queue_t
301 __SCNetworkReachability_concurrent_queue (void);
302
303 #pragma mark -
304 #pragma mark [XPC] Reachability Server (client APIs)
305
306 Boolean
307 _SCNetworkReachabilityServer_snapshot (void);
308
309 Boolean
310 __SCNetworkReachabilityServer_targetAdd (SCNetworkReachabilityRef target);
311
312 void
313 __SCNetworkReachabilityServer_targetRemove (SCNetworkReachabilityRef target);
314
315 Boolean
316 __SCNetworkReachabilityServer_targetSchedule (SCNetworkReachabilityRef target);
317
318 Boolean
319 __SCNetworkReachabilityServer_targetStatus (SCNetworkReachabilityRef target);
320
321 Boolean
322 __SCNetworkReachabilityServer_targetUnschedule (SCNetworkReachabilityRef target);
323
324
325 Boolean
326 __SC_checkResolverReachabilityInternal (SCDynamicStoreRef *storeP,
327 SCNetworkReachabilityFlags *flags,
328 Boolean *haveDNS,
329 const char *nodename,
330 uint32_t *resolver_if_index,
331 int *dns_config_index);
332
333 static __inline__ void
334 __SCNetworkReachabilityPrintFlags(SCNetworkReachabilityFlags flags)
335 {
336 if (flags != 0) {
337 if (flags & kSCNetworkReachabilityFlagsReachable) {
338 SCPrint(TRUE, stdout, CFSTR("Reachable"));
339 flags &= ~kSCNetworkReachabilityFlagsReachable;
340 SCPrint(flags != 0, stdout, CFSTR(","));
341 }
342 if (flags & kSCNetworkReachabilityFlagsTransientConnection) {
343 SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
344 flags &= ~kSCNetworkReachabilityFlagsTransientConnection;
345 SCPrint(flags != 0, stdout, CFSTR(","));
346 }
347 if (flags & kSCNetworkReachabilityFlagsConnectionRequired) {
348 SCPrint(TRUE, stdout, CFSTR("Connection Required"));
349 flags &= ~kSCNetworkReachabilityFlagsConnectionRequired;
350 SCPrint(flags != 0, stdout, CFSTR(","));
351 }
352 if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) {
353 SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Traffic"));
354 flags &= ~kSCNetworkReachabilityFlagsConnectionOnTraffic;
355 SCPrint(flags != 0, stdout, CFSTR(","));
356 }
357 if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) {
358 SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Demand"));
359 flags &= ~kSCNetworkReachabilityFlagsConnectionOnDemand;
360 SCPrint(flags != 0, stdout, CFSTR(","));
361 }
362 if (flags & kSCNetworkReachabilityFlagsInterventionRequired) {
363 SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
364 flags &= ~kSCNetworkReachabilityFlagsInterventionRequired;
365 SCPrint(flags != 0, stdout, CFSTR(","));
366 }
367 if (flags & kSCNetworkReachabilityFlagsIsLocalAddress) {
368 SCPrint(TRUE, stdout, CFSTR("Local Address"));
369 flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress;
370 SCPrint(flags != 0, stdout, CFSTR(","));
371 }
372 if (flags & kSCNetworkReachabilityFlagsIsDirect) {
373 SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
374 flags &= ~kSCNetworkReachabilityFlagsIsDirect;
375 SCPrint(flags != 0, stdout, CFSTR(","));
376 }
377 #if TARGET_OS_IPHONE
378 if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
379 SCPrint(TRUE, stdout, CFSTR("WWAN"));
380 flags &= ~kSCNetworkReachabilityFlagsIsWWAN;
381 SCPrint(flags != 0, stdout, CFSTR(","));
382 }
383 #endif // TARGET_OS_IPHONE
384 if (flags != 0) {
385 SCPrint(TRUE, stdout, CFSTR("0x%08x"), flags);
386 }
387 } else {
388 SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
389 }
390
391 return;
392 }
393
394
395 __END_DECLS
396
397 #endif // _SCNETWORKREACHABILITYINTERNAL_H