SCNetworkReachabilityInternal.h [plain text]
#ifndef _SCNETWORKREACHABILITYINTERNAL_H
#define _SCNETWORKREACHABILITYINTERNAL_H
#include <Availability.h>
#include <TargetConditionals.h>
#include <sys/cdefs.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFRuntime.h>
#include <SystemConfiguration/SystemConfiguration.h>
#include <SystemConfiguration/SCPrivate.h>
#include <dispatch/dispatch.h>
#include <dns_sd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <net/if.h>
#if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000))
#define HAVE_REACHABILITY_SERVER
#include <xpc/xpc.h>
#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 50000))
#if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
#define HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
#if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
#define HAVE_IPSEC_STATUS
#define HAVE_VPN_STATUS
#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000))
#if ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
#define USE_DNSSERVICEGETADDRINFO
#endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1080) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 60000))
#pragma mark -
#pragma mark SCNetworkReachability
#define kSCNetworkReachabilityFlagsFirstResolvePending (1<<31)
#define kSCNetworkReachabilityFlagsMask 0x00ffffff // top 8-bits reserved for implementation
typedef enum {
NO = 0,
YES,
UNKNOWN
} lazyBoolean;
typedef enum {
reachabilityTypeAddress,
reachabilityTypeAddressPair,
reachabilityTypeName
} ReachabilityAddressType;
typedef struct {
uint64_t cycle;
SCNetworkReachabilityFlags flags;
unsigned int if_index;
char if_name[IFNAMSIZ];
Boolean sleeping;
} ReachabilityInfo;
typedef struct {
CFRuntimeBase cfBase;
pthread_mutex_t lock;
ReachabilityAddressType type;
const char *name;
Boolean needResolve;
CFArrayRef resolvedAddresses;
int resolvedError;
SCNetworkReachabilityFlags resolverFlags;
unsigned int if_index;
char if_name[IFNAMSIZ];
struct sockaddr *localAddress;
struct sockaddr *remoteAddress;
uint64_t cycle;
ReachabilityInfo info;
ReachabilityInfo last_notify;
Boolean scheduled;
CFRunLoopSourceRef rls;
SCNetworkReachabilityCallBack rlsFunction;
SCNetworkReachabilityContext rlsContext;
CFMutableArrayRef rlList;
dispatch_group_t dispatchGroup;
dispatch_queue_t dispatchQueue;
Boolean haveDNS;
mach_port_t dnsMP; CFMachPortRef dnsPort; CFRunLoopSourceRef dnsRLS; dispatch_source_t dnsSource; struct timeval dnsQueryStart;
struct timeval dnsQueryEnd;
struct timeval last_dns;
struct timeval last_network;
#if !TARGET_OS_IPHONE
struct timeval last_power;
#endif // !TARGET_OS_IPHONE
struct timeval last_push;
Boolean onDemandBypass;
CFStringRef onDemandName;
CFStringRef onDemandRemoteAddress;
SCNetworkReachabilityRef onDemandServer;
CFStringRef onDemandServiceID;
union {
uint32_t dnsFlags;
struct {
Boolean dnsActive :1;
Boolean dnsHaveError :1; Boolean dnsHaveV4 :1; Boolean dnsHaveV6 :1; Boolean dnsHaveTimeout:1; };
};
CFArrayRef dnsAddresses; Boolean dnsBlocked; int dnsError;
DNSServiceRef dnsMain;
DNSServiceRef dnsTarget;
#ifdef HAVE_REACHABILITY_SERVER
Boolean serverActive;
Boolean serverBypass;
Boolean serverScheduled;
ReachabilityInfo serverInfo;
CFDataRef serverDigest;
dispatch_group_t serverGroup;
Boolean serverInfoValid;
unsigned int serverSyncQueryActive; dispatch_queue_t serverQueue;
unsigned int serverReferences; CFMutableDictionaryRef serverWatchers;
Boolean useVPNAppLayer; #endif // HAVE_REACHABILITY_SERVER
Boolean resolverBypass;
char log_prefix[32];
} SCNetworkReachabilityPrivate, *SCNetworkReachabilityPrivateRef;
#ifdef HAVE_REACHABILITY_SERVER
#pragma mark -
#pragma mark [XPC] Reachability Server
#define REACH_SERVER_VERSION 20110323
#if !TARGET_IPHONE_SIMULATOR
#define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability"
#else // !TARGET_IPHONE_SIMULATOR
#define REACH_SERVICE_NAME "com.apple.SystemConfiguration.SCNetworkReachability_sim"
#endif // !TARGET_IPHONE_SIMULATOR
#pragma mark -
#pragma mark [XPC] Reachability Server (client->server request)
#define REACH_CLIENT_PROC_NAME "proc_name" // string
#define REACH_CLIENT_TARGET_ID "target_id" // uint64
#define REACH_REQUEST "request_op" // int64
enum {
REACH_REQUEST_CREATE = 0x0001,
REACH_REQUEST_REMOVE,
REACH_REQUEST_SCHEDULE,
REACH_REQUEST_STATUS,
REACH_REQUEST_UNSCHEDULE,
REACH_REQUEST_SNAPSHOT = 0x0101,
};
#define REACH_TARGET_NAME "name" // string
#define REACH_TARGET_IF_INDEX "if_index" // int64
#define REACH_TARGET_IF_NAME "if_name" // string
#define REACH_TARGET_LOCAL_ADDR "local_address" // data (struct sockaddr)
#define REACH_TARGET_REMOTE_ADDR "remote_address" // data (struct sockaddr)
#define REACH_TARGET_ONDEMAND_BYPASS "ondemand_bypass" // bool
#define REACH_TARGET_RESOLVER_BYPASS "resolver_bypass" // bool
#define REACH_REQUEST_REPLY "reply" // int64
#define REACH_REQUEST_REPLY_DETAIL "reply_detail" // string
enum {
REACH_REQUEST_REPLY_OK = 0x0000,
REACH_REQUEST_REPLY_FAILED,
REACH_REQUEST_REPLY_UNKNOWN,
};
#pragma mark -
#pragma mark [XPC] Reachability Server (server->client request)
#define MESSAGE_NOTIFY "notify_op" // int64
enum {
MESSAGE_REACHABILITY_STATUS = 0x1001,
};
#define REACH_STATUS_CYCLE "cycle" // uint64
#define REACH_STATUS_FLAGS "flags" // uint64
#define REACH_STATUS_IF_INDEX "if_index" // uint64
#define REACH_STATUS_IF_NAME "if_name" // data (char if_name[IFNAMSIZ])
#define REACH_STATUS_RESOLVED_ADDRESSES "resolved_addresses" // array[data]
#define REACH_STATUS_RESOLVED_ERROR "resolved_error" // int64
#define REACH_STATUS_SLEEPING "sleeping" // bool
#endif // HAVE_REACHABILITY_SERVER
__BEGIN_DECLS
CFStringRef
_SCNetworkReachabilityCopyTargetDescription (SCNetworkReachabilityRef target);
CFStringRef
_SCNetworkReachabilityCopyTargetFlags (SCNetworkReachabilityRef target);
void
__SCNetworkReachabilityPerform (SCNetworkReachabilityRef target);
void
__SCNetworkReachabilityPerformConcurrent (SCNetworkReachabilityRef target);
#ifdef HAVE_REACHABILITY_SERVER
dispatch_queue_t
__SCNetworkReachability_concurrent_queue (void);
#pragma mark -
#pragma mark [XPC] Reachability Server (client APIs)
Boolean
_SCNetworkReachabilityServer_snapshot (void);
Boolean
__SCNetworkReachabilityServer_targetAdd (SCNetworkReachabilityRef target);
void
__SCNetworkReachabilityServer_targetRemove (SCNetworkReachabilityRef target);
Boolean
__SCNetworkReachabilityServer_targetSchedule (SCNetworkReachabilityRef target);
Boolean
__SCNetworkReachabilityServer_targetStatus (SCNetworkReachabilityRef target);
Boolean
__SCNetworkReachabilityServer_targetUnschedule (SCNetworkReachabilityRef target);
Boolean
__SC_checkResolverReachabilityInternal (SCDynamicStoreRef *storeP,
SCNetworkReachabilityFlags *flags,
Boolean *haveDNS,
const char *nodename,
uint32_t *resolver_if_index,
int *dns_config_index);
#endif // HAVE_REACHABILITY_SERVER
static __inline__ void
__SCNetworkReachabilityPrintFlags(SCNetworkReachabilityFlags flags)
{
if (flags != 0) {
if (flags & kSCNetworkReachabilityFlagsReachable) {
SCPrint(TRUE, stdout, CFSTR("Reachable"));
flags &= ~kSCNetworkReachabilityFlagsReachable;
SCPrint(flags != 0, stdout, CFSTR(","));
}
if (flags & kSCNetworkReachabilityFlagsTransientConnection) {
SCPrint(TRUE, stdout, CFSTR("Transient Connection"));
flags &= ~kSCNetworkReachabilityFlagsTransientConnection;
SCPrint(flags != 0, stdout, CFSTR(","));
}
if (flags & kSCNetworkReachabilityFlagsConnectionRequired) {
SCPrint(TRUE, stdout, CFSTR("Connection Required"));
flags &= ~kSCNetworkReachabilityFlagsConnectionRequired;
SCPrint(flags != 0, stdout, CFSTR(","));
}
if (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) {
SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Traffic"));
flags &= ~kSCNetworkReachabilityFlagsConnectionOnTraffic;
SCPrint(flags != 0, stdout, CFSTR(","));
}
if (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) {
SCPrint(TRUE, stdout, CFSTR("Automatic Connection On Demand"));
flags &= ~kSCNetworkReachabilityFlagsConnectionOnDemand;
SCPrint(flags != 0, stdout, CFSTR(","));
}
if (flags & kSCNetworkReachabilityFlagsInterventionRequired) {
SCPrint(TRUE, stdout, CFSTR("Intervention Required"));
flags &= ~kSCNetworkReachabilityFlagsInterventionRequired;
SCPrint(flags != 0, stdout, CFSTR(","));
}
if (flags & kSCNetworkReachabilityFlagsIsLocalAddress) {
SCPrint(TRUE, stdout, CFSTR("Local Address"));
flags &= ~kSCNetworkReachabilityFlagsIsLocalAddress;
SCPrint(flags != 0, stdout, CFSTR(","));
}
if (flags & kSCNetworkReachabilityFlagsIsDirect) {
SCPrint(TRUE, stdout, CFSTR("Directly Reachable Address"));
flags &= ~kSCNetworkReachabilityFlagsIsDirect;
SCPrint(flags != 0, stdout, CFSTR(","));
}
#if TARGET_OS_IPHONE
if (flags & kSCNetworkReachabilityFlagsIsWWAN) {
SCPrint(TRUE, stdout, CFSTR("WWAN"));
flags &= ~kSCNetworkReachabilityFlagsIsWWAN;
SCPrint(flags != 0, stdout, CFSTR(","));
}
#endif // TARGET_OS_IPHONE
if (flags != 0) {
SCPrint(TRUE, stdout, CFSTR("0x%08x"), flags);
}
} else {
SCPrint(TRUE, stdout, CFSTR("Not Reachable"));
}
return;
}
__END_DECLS
#endif // _SCNETWORKREACHABILITYINTERNAL_H