]> git.saurik.com Git - apple/configd.git/commitdiff
configd-395.10.tar.gz mac-os-x-1073 v395.10
authorApple <opensource@apple.com>
Thu, 2 Feb 2012 16:15:31 +0000 (16:15 +0000)
committerApple <opensource@apple.com>
Thu, 2 Feb 2012 16:15:31 +0000 (16:15 +0000)
18 files changed:
Makefile
Plugins/IPMonitor/Info.plist
Plugins/InterfaceNamer/Info.plist
Plugins/KernelEventMonitor/Info.plist
Plugins/LinkConfiguration/Info.plist
Plugins/Logger/Info-Embedded.plist
Plugins/Logger/Info.plist
Plugins/NetworkIdentification/Info.plist
Plugins/PreferencesMonitor/Info.plist
SCMonitor/Info.plist
SystemConfiguration.fproj/Info-Embedded.plist
SystemConfiguration.fproj/Info.plist
SystemConfiguration.fproj/SCNetworkReachability.c
SystemConfiguration.fproj/SCPrivate.h
SystemConfiguration.fproj/dy_framework.c
SystemConfiguration.fproj/dy_framework.h
SystemConfiguration.fproj/helper/SCHelper_server.c
configd.tproj/session.c

index d65e12954b6db1f40173fb7f469dc7735949230d..1102fd323d14e62541b3e00e2059c381effb117d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -39,3 +39,21 @@ snow :
          -release $(shell cat /usr/share/buildit/.releaseName) \
          -othercflags "\"$(SNOW_CFLAGS)\""                     \
 
+#----------------------------------------------------------------------
+#
+# Build for Lion, SULionXXX, ...
+#
+#----------------------------------------------------------------------
+
+LION_CFLAGS=
+
+lion :
+       /usr/local/bin/buildit .                                \
+         -noinstallsrc -noinstallhdrs -noverify -nosum         \
+         -arch i386 -arch x86_64                               \
+         -target All                                           \
+         -project ${PROJECT}-${VERSION}                        \
+         -configuration Debug                                  \
+         -release $(shell cat /usr/share/buildit/.releaseName) \
+         -othercflags "$(LION_CFLAGS)"                         \
+
index 52c80f5d1d5501eb26904131425ea3722fd10607..a29cf26a7b6450f9cb45ab3951a27342b282a7b0 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 244ec1a8c9a27423777c4923ea4f0755413fe64b..ee235fc2cfd83623a87c9e7ac586200853b06594 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 024f0382d8cce8d50293635070aaf72bc156cf1e..146c74e22ded83803c6f897b5f067d3bed0f6c20 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 21adc60cba2cd59bb35f7e7327d6a089c8ea3dbd..8655cee22dfb4214e3c3e58372ca50cc372c377d 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index db9e6298b7162881f416140c8c6f5496b38335ab..c0eed0446701e6326ea3e42c3d237884430ecae0 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index b8c904d0fb2d8889a150dcbdf02c0462d06a30cb..1f56695fe0cf0f861682e9c31d1f74b43fd9c192 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index db066bda0c25c55aa6e3ae4ba7ab59af4e9e14c7..b025a55333234eb8701c4587c25537918c00dce0 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 59113e547c27368c35349babde65949230edde88..609f4eb01fc11936d70bce03a38fd49886307f6d 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 1889870fd12212bac5a6e2487bcfe47a5f8ad347..5a07d4d0b06403040bc5f684f29adae92d71cd92 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 9112621d5c5121ab8c6a3e7a21ed1ff82a70546b..40e892977f03826998d1bea2a2c86c338ff19973 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 9112621d5c5121ab8c6a3e7a21ed1ff82a70546b..40e892977f03826998d1bea2a2c86c338ff19973 100644 (file)
@@ -17,7 +17,7 @@
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.11.1</string>
+       <string>1.11.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index 7cc048c36831f9a8993f0646127690c563dbba6f..4b6ebd09aeccc651903cb3a6fa6680d7f02b0847 100644 (file)
@@ -86,6 +86,8 @@
 #endif // ((__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070) || (__IPHONE_OS_VERSION_MIN_REQUIRED >= 40000)) && !TARGET_IPHONE_SIMULATOR && !TARGET_OS_EMBEDDED_OTHER
 
 
+
+
 #ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
 /* Libinfo SPI */
 mach_port_t
@@ -104,6 +106,9 @@ _getaddrinfo_interface_async_call(const char                        *nodename,
 #define        N_QUICK 64
 
 
+typedef        enum { NO = 0, YES, UNKNOWN }   lazyBoolean;
+
+
 typedef enum {
        reachabilityTypeAddress,
        reachabilityTypeAddressPair,
@@ -111,6 +116,14 @@ typedef enum {
 } addressType;
 
 
+// how long (minimum time, us) to wait before retrying DNS query after EAI_NONAME
+#define EAI_NONAME_RETRY_DELAY_USEC    250000
+
+// how long (maximum time, us) after DNS configuration change we accept EAI_NONAME
+// without question.
+#define EAI_NONAME_RETRY_LIMIT_USEC    2500000
+
+
 static CFStringRef     __SCNetworkReachabilityCopyDescription  (CFTypeRef cf);
 static void            __SCNetworkReachabilityDeallocate       (CFTypeRef cf);
 static void            rlsPerform(void *info);
@@ -185,6 +198,12 @@ typedef struct {
        CFMachPortRef                   dnsPort;
        CFRunLoopSourceRef              dnsRLS;
        struct timeval                  dnsQueryStart;
+       struct timeval                  dnsQueryEnd;
+       dispatch_source_t               dnsRetry;               // != NULL if DNS retry request queued
+       int                             dnsRetryCount;          // number of retry attempts
+
+       /* [async] processing info */
+       struct timeval                  last_dns;
 
        /* on demand info */
        Boolean                         onDemandBypass;
@@ -193,6 +212,7 @@ typedef struct {
        SCNetworkReachabilityRef        onDemandServer;
        CFStringRef                     onDemandServiceID;
 
+
        /* logging */
        char                            log_prefix[32];
 
@@ -221,6 +241,9 @@ static const ReachabilityInfo       NOT_REPORTED    = { 0xFFFFFFFF, 0,      FALSE };
 static int                     rtm_seq         = 0;
 
 
+static const struct timeval    TIME_ZERO       = { 0, 0 };
+
+
 #if    !TARGET_OS_IPHONE
 /*
  * Power capabilities (sleep/wake)
@@ -263,22 +286,37 @@ isA_SCNetworkReachability(CFTypeRef obj)
 
 
 static void
-__log_query_time(SCNetworkReachabilityRef target, Boolean found, Boolean async, struct timeval *start)
+__dns_query_start(struct timeval       *dnsQueryStart,
+                 struct timeval        *dnsQueryEnd)
+{
+       (void) gettimeofday(dnsQueryStart, NULL);
+       *dnsQueryEnd = TIME_ZERO;
+
+       return;
+}
+
+
+static void
+__dns_query_end(SCNetworkReachabilityRef       target,
+               Boolean                         found,
+               Boolean                         async,
+               struct timeval                  *dnsQueryStart,
+               struct timeval                  *dnsQueryEnd)
 {
-       struct timeval                  dnsQueryComplete;
        struct timeval                  dnsQueryElapsed;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
+       (void) gettimeofday(dnsQueryEnd, NULL);
+
        if (!_sc_debug) {
                return;
        }
 
-       if (start->tv_sec == 0) {
+       if (dnsQueryStart->tv_sec == 0) {
                return;
        }
 
-       (void) gettimeofday(&dnsQueryComplete, NULL);
-       timersub(&dnsQueryComplete, start, &dnsQueryElapsed);
+       timersub(dnsQueryEnd, dnsQueryStart, &dnsQueryElapsed);
        SCLog(TRUE, LOG_INFO,
              CFSTR("%s%ssync DNS complete%s (query time = %d.%3.3d)"),
              targetPrivate->log_prefix,
@@ -294,13 +332,23 @@ __log_query_time(SCNetworkReachabilityRef target, Boolean found, Boolean async,
 static __inline__ Boolean
 __reach_equal(ReachabilityInfo *r1, ReachabilityInfo *r2)
 {
-       if ((r1->flags    == r2->flags   ) &&
-           (r1->if_index == r2->if_index) &&
-           (r1->sleeping == r2->sleeping)) {
-               return TRUE;
+       if (r1->flags != r2->flags) {
+               // if the reachability flags changed
+               return FALSE;
        }
 
-       return FALSE;
+       if (r1->if_index != r2->if_index) {
+               // if the target interface changed
+               return FALSE;
+       }
+
+       if ((r1->sleeping != r2->sleeping) && !r2->sleeping) {
+               // if our sleep/wake status changed and if we
+               // are no longer sleeping
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
 
@@ -1712,6 +1760,9 @@ __SCNetworkReachabilityDeallocate(CFTypeRef cf)
 {
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)cf;
 
+       SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%srelease"),
+             targetPrivate->log_prefix);
+
        /* release resources */
 
        pthread_mutex_destroy(&targetPrivate->lock);
@@ -1759,6 +1810,56 @@ static void
 __SCNetworkReachabilityInitialize(void)
 {
        __kSCNetworkReachabilityTypeID = _CFRuntimeRegisterClass(&__SCNetworkReachabilityClass);
+
+       // provide a way to enable SCNetworkReachability logging without
+       // having to set _sc_debug=1.
+       if (getenv("REACH_LOGGING") != NULL) {
+               _sc_debug = TRUE;
+       }
+
+       return;
+}
+
+
+/*
+ * __SCNetworkReachabilityPerformInline
+ *
+ * Calls rlsPerform()
+ * - caller must be holding a reference to the target
+ * - caller must *not* be holding the target lock
+ */
+static __inline__ void
+__SCNetworkReachabilityPerformInline(SCNetworkReachabilityRef target, Boolean needResolve)
+{
+       dispatch_queue_t                queue;
+       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
+
+       pthread_mutex_lock(&targetPrivate->lock);
+
+       if (needResolve) {
+               // allow the DNS query to be [re-]started
+               targetPrivate->needResolve = TRUE;
+       }
+
+       queue = targetPrivate->dispatchQueue;
+       if (queue != NULL) {
+               dispatch_retain(queue);
+
+               pthread_mutex_unlock(&targetPrivate->lock);
+
+               dispatch_sync(queue, ^{
+                       rlsPerform((void *)target);
+                       dispatch_release(queue);
+               });
+       } else {
+               if (targetPrivate->rls != NULL) {
+                       CFRunLoopSourceSignal(targetPrivate->rls);
+                       _SC_signalRunLoop(target, targetPrivate->rls, targetPrivate->rlList);
+               }
+
+               pthread_mutex_unlock(&targetPrivate->lock);
+       }
+
        return;
 }
 
@@ -1837,6 +1938,12 @@ __SCNetworkReachabilityCreatePrivate(CFAllocatorRef      allocator)
        targetPrivate->dnsMP                            = MACH_PORT_NULL;
        targetPrivate->dnsPort                          = NULL;
        targetPrivate->dnsRLS                           = NULL;
+       targetPrivate->dnsQueryStart                    = TIME_ZERO;
+       targetPrivate->dnsQueryEnd                      = TIME_ZERO;
+       targetPrivate->dnsRetry                         = NULL;
+       targetPrivate->dnsRetryCount                    = 0;
+
+       targetPrivate->last_dns                         = TIME_ZERO;
 
        targetPrivate->onDemandBypass                   = FALSE;
        targetPrivate->onDemandName                     = NULL;
@@ -1844,6 +1951,7 @@ __SCNetworkReachabilityCreatePrivate(CFAllocatorRef       allocator)
        targetPrivate->onDemandServer                   = NULL;
        targetPrivate->onDemandServiceID                = NULL;
 
+
        targetPrivate->log_prefix[0] = '\0';
        if (_sc_log > 0) {
                snprintf(targetPrivate->log_prefix,
@@ -1926,6 +2034,10 @@ SCNetworkReachabilityCreateWithAddress(CFAllocatorRef            allocator,
        targetPrivate->remoteAddress = CFAllocatorAllocate(NULL, address->sa_len, 0);
        bcopy(address, targetPrivate->remoteAddress, address->sa_len);
 
+       SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%screate w/address %@"),
+             targetPrivate->log_prefix,
+             targetPrivate);
+
        return (SCNetworkReachabilityRef)targetPrivate;
 }
 
@@ -1975,6 +2087,10 @@ SCNetworkReachabilityCreateWithAddressPair(CFAllocatorRef                allocator,
                bcopy(remoteAddress, targetPrivate->remoteAddress, remoteAddress->sa_len);
        }
 
+       SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%screate w/address pair %@"),
+             targetPrivate->log_prefix,
+             targetPrivate);
+
        return (SCNetworkReachabilityRef)targetPrivate;
 }
 
@@ -2037,10 +2153,16 @@ SCNetworkReachabilityCreateWithName(CFAllocatorRef      allocator,
        targetPrivate->needResolve = TRUE;
        targetPrivate->info.flags |= kSCNetworkReachabilityFlagsFirstResolvePending;
 
+       SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%screate w/name %@"),
+             targetPrivate->log_prefix,
+             targetPrivate);
+
        return (SCNetworkReachabilityRef)targetPrivate;
 }
 
 
+
+
 SCNetworkReachabilityRef
 SCNetworkReachabilityCreateWithOptions(CFAllocatorRef  allocator,
                                       CFDictionaryRef  options)
@@ -2117,6 +2239,7 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef     allocator,
                return NULL;
        }
 
+
        if ((nodename != NULL) || (servname != NULL)) {
                const char      *name;
 
@@ -2167,10 +2290,15 @@ SCNetworkReachabilityCreateWithOptions(CFAllocatorRef   allocator,
                }
        }
 
+
        if (bypass != NULL) {
                targetPrivate->onDemandBypass = CFBooleanGetValue(bypass);
        }
 
+       SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%s    + options %@"),
+             targetPrivate->log_prefix,
+             targetPrivate);
+
        return (SCNetworkReachabilityRef)targetPrivate;
 }
 
@@ -2279,10 +2407,11 @@ __SCNetworkReachabilityCallbackSetResolvedAddress(int32_t status, struct addrinf
        SCNetworkReachabilityRef        target          = (SCNetworkReachabilityRef)context;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
-       __log_query_time(target,
-                        ((status == 0) && (res != NULL)),      // if successful query
-                        TRUE,                                  // async
-                        &targetPrivate->dnsQueryStart);        // start time
+       __dns_query_end(target,
+                       ((status == 0) && (res != NULL)),       // if successful query
+                       TRUE,                                   // async
+                       &targetPrivate->dnsQueryStart,          // start time
+                       &targetPrivate->dnsQueryEnd);           // end time
 
        __SCNetworkReachabilitySetResolvedAddress(status, res, target);
        return;
@@ -3129,7 +3258,7 @@ startAsyncDNSQuery(SCNetworkReachabilityRef target) {
        Boolean                         ok;
        SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
 
-       (void) gettimeofday(&targetPrivate->dnsQueryStart, NULL);
+       __dns_query_start(&targetPrivate->dnsQueryStart, &targetPrivate->dnsQueryEnd);
 
 #ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
        if (targetPrivate->if_index == 0) {
@@ -3164,6 +3293,63 @@ startAsyncDNSQuery(SCNetworkReachabilityRef target) {
 }
 
 
+#pragma mark -
+
+
+static Boolean
+enqueueAsyncDNSRetry(SCNetworkReachabilityRef  target)
+{
+       int64_t                         delay;
+       dispatch_source_t               source;
+       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
+
+       source = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
+                                       0,
+                                       0,
+                                       dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
+       if (source == NULL) {
+               SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkReachability retry dispatch_source_create() failed"));
+               return FALSE;
+       }
+
+       // retain the target ... and release it when the [timer] source is released
+       CFRetain(target);
+       dispatch_set_context(source, (void *)target);
+       dispatch_set_finalizer_f(source, (dispatch_function_t)CFRelease);
+
+       dispatch_source_set_event_handler(source, ^(void) {
+               __SCNetworkReachabilityPerformInline(target, TRUE);
+       });
+
+       // start a one-shot timer
+       delay = targetPrivate->dnsRetryCount * EAI_NONAME_RETRY_DELAY_USEC * NSEC_PER_USEC;
+       dispatch_source_set_timer(source,
+                                 dispatch_time(DISPATCH_TIME_NOW, delay),      // start
+                                 0,                                            // interval
+                                 10 * NSEC_PER_MSEC);                          // leeway
+
+       targetPrivate->dnsRetry = source;
+       dispatch_resume(source);
+
+       return TRUE;
+}
+
+
+static void
+dequeueAsyncDNSRetry(SCNetworkReachabilityRef  target)
+{
+       SCNetworkReachabilityPrivateRef targetPrivate   = (SCNetworkReachabilityPrivateRef)target;
+
+       if (targetPrivate->dnsRetry != NULL) {
+               dispatch_source_cancel(targetPrivate->dnsRetry);
+               dispatch_release(targetPrivate->dnsRetry);
+               targetPrivate->dnsRetry = NULL;
+       }
+
+       return;
+}
+
+
 #pragma mark -
 #pragma mark OnDemand
 
@@ -3540,6 +3726,7 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef  store_info,
 
                case reachabilityTypeName : {
                        struct timeval                  dnsQueryStart;
+                       struct timeval                  dnsQueryEnd;
                        int                             error;
                        SCNetworkReachabilityFlags      ns_flags;
                        struct addrinfo                 *res;
@@ -3550,9 +3737,115 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef        store_info,
                                if (!async) {
                                        /* if not an async request */
                                        goto checkResolvedAddress;
-                               } else if ((targetPrivate->dnsPort == NULL) && !targetPrivate->needResolve) {
-                                       /* if async request, no query active, and no query needed */
-                                       goto checkResolvedAddress;
+                               } else if ((targetPrivate->dnsMP == MACH_PORT_NULL) && !targetPrivate->needResolve) {
+                                       struct timeval          elapsed;
+                                       const struct timeval    retry_limit     = { EAI_NONAME_RETRY_LIMIT_USEC / USEC_PER_SEC,
+                                                                                   EAI_NONAME_RETRY_LIMIT_USEC % USEC_PER_SEC };
+
+                                       /*
+                                        * if this is an async request (i.e. someone is watching the reachability
+                                        * of this target), if no query active, and if no query is needed
+                                        */
+
+                                       if ((error != EAI_NONAME)
+#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
+                                           && (error != EAI_NODATA)
+#endif
+                                          ) {
+                                               /* if not "host not found" */
+                                               goto checkResolvedAddress;
+                                       }
+
+                                       /*
+                                        * if our last DNS query returned EAI_NONAME then we
+                                        * "may" want to retry.
+                                        *
+                                        * Specifically, if the [DNS] configuration was updated a while
+                                        * back then we'll trust the EAI_NONAME reply. Otherwise, we
+                                        * want to try again to ensure that we didn't get caught in a
+                                        * race between the time when the configuration was changed and
+                                        * when mDNSResponder is really ready to handle the query.
+                                        *
+                                        * Retry handling details :
+                                        *
+                                        * Compare the time when the DNS configuration was last changed and
+                                        * when our DNS reply was started (->last_dns vs ->dnsQueryStart).
+                                        *
+                                        * Expected: 0 < last_dns (t1) < dnsQueryStart (t2)
+                                        *
+                                        * last  start  end   description                        action
+                                        * ====  =====  ====  =================================  ========
+                                        *  0     N/A    N/A  no change, query error             no retry
+                                        *  0     N/A    N/A  no change, query complete          no retry
+                                        *  N/A   N/A    0    changed, query in-flight or error  no retry
+                                        *  t1 >  t2          query started, then [DNS] changed  no retry
+                                        *  t1 == t2          changed & query started together   no retry
+                                        *  t1 <  t2          changed, then query started        retry
+                                        */
+
+                                       if (!timerisset(&targetPrivate->last_dns)) {
+                                               /*
+                                                * if we have not yet seen a DNS configuration
+                                                * change
+                                                */
+                                               goto checkResolvedAddress;
+                                       }
+
+                                       if (!timerisset(&targetPrivate->dnsQueryEnd)) {
+                                               /*
+                                                * if no query end time (new request in flight)
+                                                */
+                                               goto checkResolvedAddress;
+                                       }
+
+                                       if (timercmp(&targetPrivate->last_dns,
+                                                    &targetPrivate->dnsQueryStart,
+                                                    >=)) {
+                                               /*
+                                                * if our DNS query started and then, a
+                                                * short time later, the DNS configuration
+                                                * was changed we don't need to retry
+                                                * because we will be re-issuing (and not
+                                                * retrying) the query.
+                                                */
+                                               goto checkResolvedAddress;
+                                       }
+
+                                       timersub(&targetPrivate->dnsQueryStart,
+                                                &targetPrivate->last_dns,
+                                                &elapsed);
+                                       if (timercmp(&elapsed, &retry_limit, >)) {
+                                               /*
+                                                * if the DNS query started after mDNSResponder
+                                                * had a chance to apply the last configuration
+                                                * then we should trust the EAI_NONAME reply.
+                                                */
+                                               goto checkResolvedAddress;
+                                       }
+
+                                       /* retry the DNS query */
+
+                                       if (targetPrivate->dnsRetry != NULL) {
+                                               // no need to schedule if we already have a
+                                               // retry query in flight
+                                               break;
+                                       }
+
+                                       targetPrivate->dnsRetryCount++;
+
+                                       SCLog(_sc_debug, LOG_INFO,
+                                             CFSTR("%sretry [%d] DNS query for %s%s%s%s%s"),
+                                             targetPrivate->log_prefix,
+                                             targetPrivate->dnsRetryCount,
+                                             targetPrivate->name != NULL ? "name = " : "",
+                                             targetPrivate->name != NULL ? targetPrivate->name : "",
+                                             targetPrivate->name != NULL && targetPrivate->serv != NULL ? ", " : "",
+                                             targetPrivate->serv != NULL ? "serv = " : "",
+                                             targetPrivate->serv != NULL ? targetPrivate->serv : "");
+
+                                       enqueueAsyncDNSRetry(target);
+
+                                       break;
                                }
                        }
 
@@ -3637,6 +3930,11 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef store_info,
                                        break;
                                }
 
+                               if (targetPrivate->dnsRetry != NULL) {
+                                       /* if we already have a "retry" queued */
+                                       break;
+                               }
+
                                SCLog(_sc_debug, LOG_INFO,
                                      CFSTR("%sstart DNS query for %s%s%s%s%s"),
                                      targetPrivate->log_prefix,
@@ -3671,9 +3969,7 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef  store_info,
                         * OK, all of the DNS name servers are available.  Let's
                         * resolve the nodename into an address.
                         */
-                       if (_sc_debug) {
-                               (void) gettimeofday(&dnsQueryStart, NULL);
-                       }
+                       __dns_query_start(&dnsQueryStart, &dnsQueryEnd);
 
 #ifdef HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
                        if (targetPrivate->if_index == 0) {
@@ -3692,10 +3988,11 @@ __SCNetworkReachabilityGetFlags(ReachabilityStoreInfoRef        store_info,
                        }
 #endif // HAVE_GETADDRINFO_INTERFACE_ASYNC_CALL
 
-                       __log_query_time(target,
+                       __dns_query_end(target,
                                         ((error == 0) && (res != NULL)),       // if successful query
                                         FALSE,                                 // sync
-                                        &dnsQueryStart);                       // start time
+                                        &dnsQueryStart,                        // start time
+                                        &dnsQueryEnd);                         // end time
 
                        __SCNetworkReachabilitySetResolvedAddress(error, res, target);
 
@@ -3986,11 +4283,15 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef  store,
                                     CFArrayRef         changedKeys,
                                     void               *info)
 {
+#if    !TARGET_OS_IPHONE
+       Boolean                 cpuStatusChanged        = FALSE;
+#endif // !TARGET_OS_IPHONE
        Boolean                 dnsConfigChanged        = FALSE;
        CFIndex                 i;
        CFStringRef             key;
        CFIndex                 nChanges                = CFArrayGetCount(changedKeys);
        CFIndex                 nTargets;
+       struct timeval          now;
 #if    !TARGET_OS_IPHONE
        Boolean                 powerStatusChanged      = FALSE;
 #endif // !TARGET_OS_IPHONE
@@ -4011,6 +4312,9 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef    store,
                goto done;
        }
 
+       /* grab the current time */
+       (void)gettimeofday(&now, NULL);
+
 #if    !TARGET_OS_IPHONE
        key = SCDynamicStoreKeyCreate(NULL, CFSTR("%@%@"),
                                      kSCDynamicStoreDomainState,
@@ -4022,7 +4326,24 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef   store,
                if (num != NULL) {
                        if (isA_CFNumber(num) &&
                            CFNumberGetValue(num, kCFNumberSInt32Type, &power_capabilities)) {
+                               static Boolean  haveCPU_old     = TRUE;
+                               Boolean         haveCPU_new;
+
                                powerStatusChanged = TRUE;
+
+                               haveCPU_new = (power_capabilities & kIOPMSystemPowerStateCapabilityCPU) != 0;
+                               if ((haveCPU_old != haveCPU_new) && haveCPU_new) {
+                                       /*
+                                        * if the power state now shows CPU availability
+                                        * then we will assume that the DNS configuration
+                                        * has changed.  This will force us to re-issue
+                                        * our DNS queries since mDNSResponder does not
+                                        * attempt to resolve names when "sleeping".
+                                        */
+                                       cpuStatusChanged = TRUE;
+                                       dnsConfigChanged = TRUE;
+                               }
+                               haveCPU_old = haveCPU_new;
                        }
 
                        CFRelease(num);
@@ -4040,13 +4361,35 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef  store,
        CFRelease(key);
 
        if (_sc_debug) {
-               int             changes = 0;
-               const char      *str;
+               unsigned int            changes                 = 0;
+               static const char       *change_strings[]       = {
+                       // with no "power" status change
+                       "",
+                       "network ",
+                       "DNS ",
+                       "network and DNS ",
+#if    !TARGET_OS_IPHONE
+                       // with "power" status change
+                       "power ",
+                       "network and power ",
+                       "DNS and power ",
+                       "network, DNS, and power ",
+
+                       // with no "power" status change (including CPU "on")
+                       "power* ",
+                       "network and power* ",
+                       "DNS and power* ",
+                       "network, DNS, and power* ",
+#endif // !TARGET_OS_IPHONE
+               };
 
 #if    !TARGET_OS_IPHONE
                #define PWR     4
                if (powerStatusChanged) {
                        changes |= PWR;
+                       if (cpuStatusChanged) {
+                               changes += PWR;
+                       }
                        nChanges -= 1;
                }
 #endif // !TARGET_OS_IPHONE
@@ -4062,21 +4405,9 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef   store,
                        changes |= NET;
                }
 
-               switch (changes) {
-                       case 0           : str = "";                            break;
-                       case NET         : str = "network ";                    break;
-                       case DNS         : str = "DNS ";                        break;
-                       case DNS|NET     : str = "network and DNS ";            break;
-#if    !TARGET_OS_IPHONE
-                       case PWR         : str = "power ";                      break;
-                       case PWR|NET     : str = "network and power ";          break;
-                       case PWR|DNS     : str = "DNS and power ";              break;
-                       case PWR|DNS|NET : str = "network, DNS, and power ";    break;
-#endif // !TARGET_OS_IPHONE
-                       default : str = "??? ";
-               }
-
-               SCLog(TRUE, LOG_INFO, CFSTR("process %sconfiguration change"), str);
+               SCLog(TRUE, LOG_INFO,
+                     CFSTR("process %sconfiguration change"),
+                     change_strings[changes]);
        }
 
        initReachabilityStoreInfo(&store_info);
@@ -4090,6 +4421,11 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef   store,
 
                pthread_mutex_lock(&targetPrivate->lock);
 
+               if (dnsConfigChanged) {
+                       targetPrivate->last_dns = now;
+                       targetPrivate->dnsRetryCount = 0;
+               }
+
                if (targetPrivate->type == reachabilityTypeName) {
                        Boolean         dnsChanged      = dnsConfigChanged;
 
@@ -4147,6 +4483,11 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef   store,
                                        getaddrinfo_async_cancel(mp);
                                }
 
+                               if (targetPrivate->dnsRetry != NULL) {
+                                       /* cancel the outstanding DNS retry */
+                                       dequeueAsyncDNSRetry(target);
+                               }
+
                                /* schedule request to resolve the name again */
                                targetPrivate->needResolve = TRUE;
                        }
@@ -4168,7 +4509,15 @@ __SCNetworkReachabilityHandleChanges(SCDynamicStoreRef   store,
 
 
 #if    !TARGET_OS_IPHONE
-static __inline__ Boolean
+
+static Boolean
+darkWakeNotify(SCNetworkReachabilityRef target)
+{
+       return FALSE;
+}
+
+
+static Boolean
 systemIsAwake(IOPMSystemPowerStateCapabilities power_capabilities)
 {
 
@@ -4194,6 +4543,7 @@ systemIsAwake(IOPMSystemPowerStateCapabilities power_capabilities)
 
        return TRUE;
 }
+
 #endif // !TARGET_OS_IPHONE
 
 
@@ -4216,6 +4566,11 @@ rlsPerform(void *info)
 
        pthread_mutex_lock(&targetPrivate->lock);
 
+       if (targetPrivate->dnsRetry != NULL) {
+               // cancel DNS retry
+               dequeueAsyncDNSRetry(target);
+       }
+
        if (!targetPrivate->scheduled) {
                // if not currently scheduled
                pthread_mutex_unlock(&targetPrivate->lock);
@@ -4248,21 +4603,38 @@ rlsPerform(void *info)
                         * don't report the change if the new reachability flags are
                         * the same or "better"
                         */
-                       defer = TRUE;
+                       defer = !darkWakeNotify(target);
                } else if (__reach_equal(&targetPrivate->last_notify, &reach_info)) {
-                       /* if we have already posted this change */
-                       defer = TRUE;
+                       /*
+                        * if we have already posted this change
+                        */
+                       defer = !darkWakeNotify(target);
                }
        }
 #endif // !TARGET_OS_IPHONE
 
        if (__reach_equal(&targetPrivate->info, &reach_info)) {
-               SCLog(_sc_debug, LOG_INFO,
-                     CFSTR("%sflags/interface match (now 0x%08x/%hu%s)"),
-                     targetPrivate->log_prefix,
-                     reach_info.flags,
-                     reach_info.if_index,
-                     reach_info.sleeping ? "*" : "");
+               if (_sc_debug) {
+                       if (targetPrivate->info.sleeping == reach_info.sleeping) {
+                               SCLog(TRUE, LOG_INFO,
+                                     CFSTR("%sflags/interface match (now 0x%08x/%hu%s)"),
+                                     targetPrivate->log_prefix,
+                                     reach_info.flags,
+                                     reach_info.if_index,
+                                     reach_info.sleeping ? ", z" : "");
+                       } else {
+                               SCLog(TRUE, LOG_INFO,
+                                     CFSTR("%sflags/interface equiv (was 0x%08x/%hu%s, now 0x%08x/%hu%s)"),
+                                     targetPrivate->log_prefix,
+                                     targetPrivate->info.flags,
+                                     targetPrivate->info.if_index,
+                                     targetPrivate->info.sleeping ? ", z" : "",
+                                     reach_info.flags,
+                                     reach_info.if_index,
+                                     reach_info.sleeping ? ", z" : "");
+                       }
+
+               }
                pthread_mutex_unlock(&targetPrivate->lock);
                return;
        }
@@ -4272,21 +4644,21 @@ rlsPerform(void *info)
              targetPrivate->log_prefix,
              targetPrivate->info.flags,
              targetPrivate->info.if_index,
-             targetPrivate->info.sleeping ? "*" : "",
+             targetPrivate->info.sleeping ? ", z" : "",
              reach_info.flags,
              reach_info.if_index,
-             reach_info.sleeping ? "*" : "",
+             reach_info.sleeping ? ", z" : "",
              defer ? ", deferred" : "");
 
-       /* update flags / interface */
-       targetPrivate->info = reach_info;
-
        /* as needed, defer the notification */
        if (defer) {
                pthread_mutex_unlock(&targetPrivate->lock);
                return;
        }
 
+       /* update flags / interface */
+       targetPrivate->info = reach_info;
+
        /* save last notification info */
        targetPrivate->last_notify = reach_info;
 
@@ -4504,6 +4876,9 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef       target,
                __SCNetworkReachabilityScheduleWithRunLoop(targetPrivate->onDemandServer, runLoop, runLoopMode, queue, TRUE);
        }
 
+       SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%sscheduled"),
+             targetPrivate->log_prefix);
+
        ok = TRUE;
 
     done :
@@ -4595,6 +4970,11 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef    target,
                        dequeueAsyncDNSQuery(target);
                        getaddrinfo_async_cancel(mp);
                }
+
+               if (targetPrivate->dnsRetry != NULL) {
+                       // if we have an outstanding DNS retry
+                       dequeueAsyncDNSRetry(target);
+               }
        }
 
        if (runLoop == NULL) {
@@ -4621,6 +5001,9 @@ __SCNetworkReachabilityUnscheduleFromRunLoop(SCNetworkReachabilityRef     target,
                dns_configuration_unwatch();
        }
 
+       SCLog((_sc_debug && (_sc_log > 0)), LOG_INFO, CFSTR("%sunscheduled"),
+             targetPrivate->log_prefix);
+
        ok = TRUE;
 
     done :
index ba073c4182caab8680a91198e5efe118265491c6..96d5a39054b5ea499557a7788bc62d3bbfa741bf 100644 (file)
@@ -127,6 +127,7 @@ extern int  _sc_log;        /* 0 if SC messages should be written to stdout/stderr,
  */
 #define kSCNetworkReachabilityOptionConnectionOnDemandByPass   CFSTR("ConnectionOnDemandByPass")
 
+
 /*!
        @group
  */
index e35580e1bf85245345681877b4a0c9360d917f34..3bfe8e07c3d0b2c6e7d7ccb37e37b05148433f0f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2008, 2010, 2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -487,6 +487,7 @@ _SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttri
        return dyfunc ? dyfunc(itemRef, attrList, length, data) : -1;
 }
 
+
 __private_extern__ OSStatus
 _SecTrustedApplicationCreateFromPath(const char *path, SecTrustedApplicationRef *app)
 {
index 84e3d10b7b22ebae953965d408034fdc0ee53bb6..e1c928f736f5530f44d6072667d84871440cd17d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2002-2008, 2010, 2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -300,6 +300,7 @@ _SecKeychainItemModifyContent               (
                                        );
 #define SecKeychainItemModifyContent _SecKeychainItemModifyContent
 
+
 OSStatus
 _SecTrustedApplicationCreateFromPath   (
                                        const char                      *path,
index c7efc4cccb845d419119413e1f91bf8e37331172..62957bdd5374744f3a519330975480b23b598452 100644 (file)
@@ -1251,7 +1251,8 @@ copyEntitlement(SCHelperSessionRef session, CFStringRef entitlement)
                        CFIndex         code    = CFErrorGetCode(error);
                        CFStringRef     domain  = CFErrorGetDomain(error);
 
-                       if (!CFEqual(domain, kCFErrorDomainMach) || (code != kIOReturnNotFound)) {
+                       if (!CFEqual(domain, kCFErrorDomainMach) ||
+                           ((code != kIOReturnInvalid) && (code != kIOReturnNotFound))) {
                                // if unexpected error
                                SCLog(TRUE, LOG_ERR,
                                      CFSTR("SecTaskCopyValueForEntitlement(,\"%@\",) failed, error = %@ : %@"),
index ccce9b33c5f8480bedc60e16fca3d37bf0e906dc..1b77827040a48d70aff979cf91a03ef553759075 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, 2003-2005, 2007-2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2001, 2003-2005, 2007-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -391,8 +391,7 @@ hasEntitlement(serverSessionRef session, CFStringRef entitlement)
                              CFSTR("hasEntitlement SecTaskCopyValueForEntitlement() %s, error domain=%@, error code=%lx"),
                              (value == NULL) ? "failed" : "warned",
                              CFErrorGetDomain(error),
-                             CFErrorGetCode(error),
-                             sessionName(session));
+                             CFErrorGetCode(error));
                        CFRelease(error);
                }