]> git.saurik.com Git - apple/configd.git/commitdiff
configd-293.4.tar.gz mac-os-x-1063 v293.4
authorApple <opensource@apple.com>
Mon, 29 Mar 2010 18:37:04 +0000 (18:37 +0000)
committerApple <opensource@apple.com>
Mon, 29 Mar 2010 18:37:04 +0000 (18:37 +0000)
24 files changed:
Plugins/ATconfig/Info.plist
Plugins/IPMonitor/Info.plist
Plugins/InterfaceNamer/Info.plist
Plugins/InterfaceNamer/ifnamer.c
Plugins/KernelEventMonitor/Info.plist
Plugins/Kicker/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/SCDNotifierInformViaCallback.c
SystemConfiguration.fproj/SCNetworkConfigurationInternal.h
SystemConfiguration.fproj/SCNetworkConfigurationPrivate.h
SystemConfiguration.fproj/SCNetworkConnection.c
SystemConfiguration.fproj/SCNetworkInterface.c
SystemConfiguration.fproj/SCNetworkReachability.c
scutil.tproj/notifications.c
scutil.tproj/scutil.c
scutil.tproj/scutil.h
scutil.tproj/tests.c

index 0dd645a97c6d4f2f5b255dc7d12d36a1a9d10096..666fd91c5796ec2d00b4f260a93e3b2ef96742c7 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Builtin</key>
        <true/>
        <key>Requires</key>
index 3af58570697d8a8879039546a07996ea465a811b..0f99e3e8b40319725b7f7a5e4c00f9a438bc2d3e 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.IPConfiguration</string>
index c856a4de3f28815ad120a28197ec499d7389c9b0..509fb22e8c778c45d489724198d260615981ad4c 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
 </dict>
 </plist>
index 1637c7abf7cabac24f5bbb33b3cc615c2f18a516..f28450a8af8bedf339c7e1728d865035b0b583cf 100644 (file)
 #include <stdio.h>
 #include <unistd.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
 #include <sys/sockio.h>
 #include <sys/stat.h>
 #include <sys/param.h>
 #include <mach/mach.h>
 #include <net/ethernet.h>
+#include <net/if.h>
 #include <net/if_types.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <SystemConfiguration/SCValidation.h>
 
 #include <IOKit/IOKitLib.h>
+#include <IOKit/IOKitLibPrivate.h>
 #include <IOKit/IOBSD.h>
 #include <IOKit/IOMessage.h>
 #include <IOKit/network/IONetworkController.h>
 #include <IOKit/network/IONetworkInterface.h>
-
-#ifndef        kIOBuiltin
-#define        kIOBuiltin                      "IOBuiltin"
-#endif
+#include <IOKit/usb/USB.h>
 
 #define kIONetworkStackUserCommand     "IONetworkStackUserCommand"
 #define kRegisterInterface             1
 
+#define        kSCNetworkInterfaceInfo         "SCNetworkInterfaceInfo"
 #define        kSCNetworkInterfaceType         "SCNetworkInterfaceType"
 #define        kSCNetworkInterfaceActive       "Active"
 
@@ -537,6 +539,12 @@ createInterfaceDict(SCNetworkInterfaceRef interface)
                                       &kCFTypeDictionaryKeyCallBacks,
                                       &kCFTypeDictionaryValueCallBacks);
 
+    val = _SCNetworkInterfaceCopyInterfaceInfo(interface);
+    if (val != NULL) {
+       CFDictionarySetValue(new_if, CFSTR(kSCNetworkInterfaceInfo), val);
+       CFRelease(val);
+    }
+
     val = _SCNetworkInterfaceGetIOPath(interface);
     if (val != NULL) {
        CFDictionarySetValue(new_if, CFSTR(kIOPathMatchKey), val);
@@ -652,42 +660,252 @@ lookupInterfaceByUnit(CFArrayRef db_list, SCNetworkInterfaceRef interface, CFInd
     return (NULL);
 }
 
+typedef struct {
+    CFDictionaryRef        match_info;
+    CFStringRef                    match_type;
+    CFBooleanRef           match_builtin;
+    CFMutableArrayRef      matches;
+} matchContext, *matchContextRef;
+
 static CFDictionaryRef
-lookupAirPortInterface(CFArrayRef db_list, CFIndex * where)
+thinInterfaceInfo(CFDictionaryRef info)
 {
-    CFIndex    i;
-    CFIndex    n;
+    CFNumberRef        num;
+    int                vid;
 
-    if (db_list == NULL) {
-       return (NULL);
+    if (CFDictionaryGetValueIfPresent(info, CFSTR(kUSBVendorID), (const void **)&num)
+       && isA_CFNumber(num)
+       && CFNumberGetValue(num, kCFNumberIntType, &vid)
+       && (vid == kIOUSBVendorIDAppleComputer)) {
+       CFMutableDictionaryRef  thin;
+
+       // if this is an Apple USB device than we trust that
+       // the non-localized name will be correct.
+       thin = CFDictionaryCreateMutableCopy(NULL, 0, info);
+       CFDictionaryRemoveValue(thin, CFSTR(kUSBProductString));
+       CFDictionaryRemoveValue(thin, CFSTR(kUSBVendorID));
+       CFDictionaryRemoveValue(thin, CFSTR(kUSBProductID));
+       return thin;
+    }
+
+    return CFRetain(info);
+}
+
+static Boolean
+matchInterfaceInfo(CFDictionaryRef known_info, CFDictionaryRef match_info)
+{
+    Boolean match;
+
+    match = _SC_CFEqual(known_info, match_info);
+    if (!match &&
+       isA_CFDictionary(known_info) &&
+       isA_CFDictionary(match_info)) {
+
+       // if not an exact match, try thinning
+       known_info = thinInterfaceInfo(known_info);
+       match_info = thinInterfaceInfo(match_info);
+       match = _SC_CFEqual(known_info, match_info);
+       CFRelease(known_info);
+       CFRelease(match_info);
+    }
+
+    return match;
+}
+
+static void
+matchKnown(const void *value, void *context)
+{
+    CFDictionaryRef    known_dict      = (CFDictionaryRef)value;
+    matchContextRef    match_context   = (matchContextRef)context;
+
+    // match interface type
+    {
+       CFStringRef     known_type;
+
+       known_type = CFDictionaryGetValue(known_dict, CFSTR(kSCNetworkInterfaceType));
+       if (!_SC_CFEqual(known_type, match_context->match_type)) {
+           return;
+       }
+    }
+
+    // match SCNetworkInterfaceInfo
+    {
+       CFDictionaryRef known_info;
+
+       known_info = CFDictionaryGetValue(known_dict, CFSTR(kSCNetworkInterfaceInfo));
+       if (!matchInterfaceInfo(known_info, match_context->match_info)) {
+           return;
+       }
+    }
+
+    // if requested, match [non-]builtin
+    if (match_context->match_builtin != NULL) {
+       CFBooleanRef    known_builtin;
+
+       known_builtin = CFDictionaryGetValue(known_dict, CFSTR(kIOBuiltin));
+       if (!isA_CFBoolean(known_builtin)) {
+           known_builtin = kCFBooleanFalse;
+       }
+       if (!_SC_CFEqual(known_builtin, match_context->match_builtin)) {
+           return;
+       }
+    }
+
+    // if we have a match
+    if (match_context->matches == NULL) {
+       match_context->matches = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+    }
+    CFArrayAppendValue(match_context->matches, known_dict);
+
+    return;
+}
+
+static void
+matchUnnamed(const void *value, void *context)
+{
+    SCNetworkInterfaceRef   known_if       = (SCNetworkInterfaceRef)value;
+    matchContextRef        match_context   = (matchContextRef)context;
+
+    if (match_context->matches == NULL) {
+       return;
+    }
+
+    // match interface type
+    {
+       CFStringRef     known_type;
+
+       known_type = SCNetworkInterfaceGetInterfaceType(known_if);
+       if (!_SC_CFEqual(known_type, match_context->match_type)) {
+           return;
+       }
     }
-    n = CFArrayGetCount(db_list);
-    for (i = 0; i < n; i++) {
-       CFDictionaryRef dict;
-       CFStringRef     if_type;
-
-       dict = CFArrayGetValueAtIndex(db_list, i);
-       if_type = CFDictionaryGetValue(dict, CFSTR(kSCNetworkInterfaceType));
-       if (if_type != NULL) {
-           if (CFEqual(if_type, kSCNetworkInterfaceTypeIEEE80211)) {
-               if (where)
-                   *where = i;
-               return (dict);
-           }
-       } else {
-           CFStringRef path;
 
-           path = CFDictionaryGetValue(dict, CFSTR(kIOPathMatchKey));
-           if ((CFStringFind(path, CFSTR("IO80211Interface")  , 0).location != kCFNotFound) ||
-               (CFStringFind(path, CFSTR("AirPort")           , 0).location != kCFNotFound) ||
-               (CFStringFind(path, CFSTR("AppleWireless80211"), 0).location != kCFNotFound)) {
-               if (where)
-                   *where = i;
-               return (dict);
+    // match SCNetworkInterfaceInfo
+    {
+       CFDictionaryRef known_info;
+       Boolean         match;
+
+       known_info = _SCNetworkInterfaceCopyInterfaceInfo(known_if);
+       match = matchInterfaceInfo(known_info, match_context->match_info);
+       if (known_info != NULL) CFRelease(known_info);
+       if (!match) {
+           return;
+       }
+    }
+
+    // if requested, match [non-]builtin
+    if (match_context->match_builtin != NULL) {
+       CFBooleanRef    known_builtin;
+
+       known_builtin = _SCNetworkInterfaceIsBuiltin(known_if) ? kCFBooleanTrue
+                                                              : kCFBooleanFalse;
+       if (!_SC_CFEqual(known_builtin, match_context->match_builtin)) {
+           return;
+       }
+    }
+
+    // if we have a match
+    CFRelease(match_context->matches);
+    match_context->matches = NULL;
+
+    return;
+}
+
+/*
+ * lookupMatchingInterface
+ *
+ * Looks at the interfaces that have already been [or need to be] named with
+ * the goal of allowing a system using a single network interface/adaptor of
+ * a given type (vendor, model, ...) to not care about the specific adaptor
+ * that is used (i.e. swapping dongle's is OK).  Once a system has had more
+ * than one interface/adaptor connected at the same time than we assume that
+ * the network configuration is being setup for multi-homing that should be
+ * maintained.
+ *
+ * If no matches are found or if more than one match is found, return NULL.
+ * If a single match is found, return the match.
+ */
+static CFDictionaryRef
+lookupMatchingInterface(SCNetworkInterfaceRef  interface,
+                       CFArrayRef              db_list,        // already named
+                       CFArrayRef              if_list,        // to be named
+                       CFIndex                 if_list_index,
+                       CFBooleanRef            builtin)
+{
+    CFStringRef            if_type;
+    CFDictionaryRef match          = NULL;
+    matchContext    match_context;
+
+    if_type = SCNetworkInterfaceGetInterfaceType(interface);
+    if (if_type == NULL) {
+       return NULL;
+    }
+
+    match_context.match_type   = if_type;
+    match_context.match_info   = _SCNetworkInterfaceCopyInterfaceInfo(interface);
+    match_context.match_builtin        = builtin;
+    match_context.matches      = NULL;
+
+    // check for matches to already named interfaces
+    // ... and appends each match that we find to match_context.matches
+    if (db_list != NULL) {
+       CFArrayApplyFunction(db_list,
+                            CFRangeMake(0, CFArrayGetCount(db_list)),
+                            matchKnown,
+                            &match_context);
+    }
+
+    // check for matches to to be named interfaces
+    // ... and CFReleases match_context.matches if we find another network
+    //     interface of the same type that also needs to be named
+    if (if_list != NULL) {
+       CFIndex    if_list_count;
+
+       if_list_count = CFArrayGetCount(if_list);
+       if (if_list_index < if_list_count) {
+           CFArrayApplyFunction(if_list,
+                                CFRangeMake(if_list_index, if_list_count - if_list_index),
+                                matchUnnamed,
+                                &match_context);
+       }
+    }
+
+    // check if we have a single match
+    if (match_context.matches != NULL) {
+       if (CFArrayGetCount(match_context.matches) == 1) {
+           match = CFArrayGetValueAtIndex(match_context.matches, 0);
+       }
+       CFRelease(match_context.matches);
+    }
+
+    if (match != NULL) {
+       Boolean         active  = TRUE;
+       CFStringRef     name;
+
+       name = CFDictionaryGetValue(match, CFSTR(kIOBSDNameKey));
+       if (isA_CFString(name)) {
+           int         sock;
+
+           sock = socket(AF_INET, SOCK_DGRAM, 0);
+           if (sock != -1) {
+               struct ifreq    ifr;
+
+               (void)_SC_cfstring_to_cstring(name, ifr.ifr_name, sizeof(ifr.ifr_name), kCFStringEncodingASCII);
+               if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
+                   // if interface name not currently in-use
+                   active = FALSE;
+               }
+               close(sock);
            }
        }
+
+       if (active) {
+           match = NULL;
+       }
     }
-    return (NULL);
+
+    if (match_context.match_info != NULL) CFRelease(match_context.match_info);
+    return match;
 }
 
 static void
@@ -947,6 +1165,7 @@ nameInterfaces(CFMutableArrayRef if_list)
            }
        } else {
            CFDictionaryRef     dbdict;
+           boolean_t           is_builtin;
            kern_return_t       kr;
 
            dbdict = lookupInterfaceByAddress(S_dblist, interface, NULL);
@@ -957,21 +1176,29 @@ nameInterfaces(CFMutableArrayRef if_list)
                SCLog(S_debug, LOG_INFO,
                      CFSTR(MY_PLUGIN_NAME ": Interface assigned unit %@ (from database)"),
                      unit);
-           } else {
-               CFStringRef     if_type;
+           }
+
+           if ((dbdict == NULL) && !isQuiet()) {
+               // if new interface, wait until quiet before naming
+               addTimestamp(S_state, path);
+               continue;
+           }
 
-               if_type = SCNetworkInterfaceGetInterfaceType(interface);
-               if ((if_type != NULL) &&
-                   CFEqual(if_type, kSCNetworkInterfaceTypeIEEE80211)) {
-                   dbdict = lookupAirPortInterface(S_dblist, NULL);
-                   if (dbdict != NULL) {
-                       unit = CFDictionaryGetValue(dbdict, CFSTR(kIOInterfaceUnit));
-                       CFRetain(unit);
+           is_builtin = _SCNetworkInterfaceIsBuiltin(interface);
 
-                       SCLog(S_debug, LOG_INFO,
-                             CFSTR(MY_PLUGIN_NAME ": Interface assigned unit %@ (updating database)"),
-                             unit);
-                   }
+           if (dbdict == NULL) {
+               dbdict = lookupMatchingInterface(interface,
+                                                S_dblist,
+                                                if_list,
+                                                i + 1,
+                                                is_builtin ? kCFBooleanTrue : kCFBooleanFalse);
+               if (dbdict != NULL) {
+                   unit = CFDictionaryGetValue(dbdict, CFSTR(kIOInterfaceUnit));
+                   CFRetain(unit);
+
+                   SCLog(S_debug, LOG_INFO,
+                         CFSTR(MY_PLUGIN_NAME ": Interface assigned unit %@ (updating database)"),
+                         unit);
                }
            }
 
@@ -986,17 +1213,8 @@ nameInterfaces(CFMutableArrayRef if_list)
            }
 
            if (dbdict == NULL) {
-               boolean_t       is_builtin;
                int             next_unit       = 0;
 
-               if (!isQuiet()) {
-                   // if new interface, wait until quiet before naming
-                   addTimestamp(S_state, path);
-                   continue;
-               }
-
-               is_builtin = _SCNetworkInterfaceIsBuiltin(interface);
-               next_unit = 0;
                if (is_builtin) {
                    // built-in interface, use the reserved slots
                    next_unit = builtinCount(if_list, i, type);
@@ -1025,8 +1243,12 @@ nameInterfaces(CFMutableArrayRef if_list)
            kr = registerInterface(S_connect, path, unit);
            if (kr != KERN_SUCCESS) {
                SCLog(TRUE, LOG_ERR,
-                     CFSTR(MY_PLUGIN_NAME ": failed to name the interface, kr=0x%x"),
-                     kr);
+                     CFSTR(MY_PLUGIN_NAME ": failed to name the interface, kr=0x%x\n"
+                           MY_PLUGIN_NAME ":   path = %@\n"
+                           MY_PLUGIN_NAME ":   unit = %@"),
+                     kr,
+                     path,
+                     unit);
                if (S_debug) {
                    displayInterface(interface);
                }
@@ -1053,6 +1275,17 @@ nameInterfaces(CFMutableArrayRef if_list)
                    CFArraySetValueAtIndex(if_list, i, new_interface);
                    CFRelease(new_interface);
                    interface = new_interface;  // if_list holds the reference
+
+                   if (is_builtin && (S_prev_active_list != NULL)) {
+                       CFIndex where;
+
+                       // update the list of [built-in] interfaces that were previously named
+                       if (lookupInterfaceByUnit(S_prev_active_list, interface, &where) != NULL) {
+                           SCLog(S_debug, LOG_INFO,
+                                 CFSTR(MY_PLUGIN_NAME ":   and updated database (new address)"));
+                           CFArrayRemoveValueAtIndex(S_prev_active_list, where);
+                       }
+                   }
                }
            }
 
@@ -1109,9 +1342,11 @@ updateInterfaces()
                CFIndex n;
 
                n = CFArrayGetCount(S_prev_active_list);
-               SCLog(TRUE, LOG_INFO,
-                     CFSTR(MY_PLUGIN_NAME ": Interface%s not [yet] active"),
-                     (n > 0) ? "s" : "");
+               if (n > 0) {
+                   SCLog(TRUE, LOG_INFO,
+                         CFSTR(MY_PLUGIN_NAME ": Interface%s not [yet] active"),
+                         (n > 1) ? "s" : "");
+               }
                for (i = 0; i < n; i++) {
                    CFDictionaryRef     if_dict;
                    CFStringRef         name;
index 8c5c5949dffdb2fc0c395c43103c272035c8fd69..c3bedc59229f46b3b1989f89241b1c100bdf8365 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
index bdbd2be8e9e328e574a4e3d73eceeaa184acf703..9265031985cd3c4905e0f2a136c52129572789e7 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.ATconfig</string>
index 35c4f29f94d1511f39edb3b6b59d6cb857c7b10d..1a4ab837bfd6e6f477d694e1e46fbc85a165329a 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Requires</key>
        <array>
                <string>com.apple.SystemConfiguration.InterfaceNamer</string>
index f9f67de12884cddf97464853b1454f2fd75d42e2..36851c8db5b6c83cd9949d7fb3bc08057a5f1b6b 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10</string>
+       <string>1.10.2</string>
        <key>Enabled</key>
        <true/>
        <key>Verbose</key>
index 6187ec8b2d9df5fed270720ea7afe59bfcc5b2bb..4dcca2b08ef3f75fe422cd579d54e6cf6c90987a 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Enabled</key>
        <false/>
        <key>Verbose</key>
index 2c86bd5aa5fde68ad4134d3f8fa10f51ccae795b..f812733d3ec9936490bf1a7f5c5d9eac74f8244d 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Builtin</key>
        <true/>
 </dict>
index 20944c848fd1b7745c3e61b196a6014582d28df0..005b73832581563358ecb282332ed487693c2cd8 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>Builtin</key>
        <true/>
        <key>Requires</key>
index 4e173babcf8363efe324a44a625c76b1defd9dc5..f5020026c33c88a507041be408ed43066ff452f1 100644 (file)
        <key>CFBundlePackageType</key>
        <string>BNDL</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFPlugInDynamicRegistration</key>
        <string>NO</string>
        <key>CFPlugInFactories</key>
index 8714e9f28ad96b60b06e7856040848578e8ba7b9..c8bbf8b69a8a94bdcf40c016aee5961ac2475f49 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
-       <string>1.10</string>
+       <string>1.10.2</string>
        <key>CFBundleIdentifier</key>
        <string>com.apple.SystemConfiguration</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10</string>
+       <string>1.10.2</string>
 </dict>
 </plist>
index c1ff9992d1044d7f7959b5535b0fb4e45bc1858c..c8bbf8b69a8a94bdcf40c016aee5961ac2475f49 100644 (file)
@@ -7,7 +7,7 @@
        <key>CFBundleExecutable</key>
        <string>SystemConfiguration</string>
        <key>CFBundleGetInfoString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleIdentifier</key>
        <string>com.apple.SystemConfiguration</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
-       <string>1.10.1</string>
+       <string>1.10.2</string>
 </dict>
 </plist>
index 3e22cc407c8df528fea93b9a51c535d077388d27..f88afec91c2c11f9af7299c2de8c1e516af7ec6c 100644 (file)
@@ -702,9 +702,7 @@ SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue)
        }
 
        if (queue != NULL) {
-               dispatch_queue_attr_t   attr;
-               mach_port_t             mp;
-               long                    res;
+               mach_port_t     mp;
 
                if ((storePrivate->dispatchQueue != NULL) || (storePrivate->rls != NULL)) {
                        _SCErrorSet(kSCStatusInvalidArgument);
@@ -728,25 +726,10 @@ SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue)
                dispatch_retain(storePrivate->dispatchQueue);
 
                /*
-                * create a queue for the mig source, we'll use this queue's context
-                * to carry the store pointer for the callback code.
+                * create a dispatch queue for the mach notifications source, we'll use
+                * this queue's context to carry the store pointer for the callback code.
                 */
-               attr = dispatch_queue_attr_create();
-               res = dispatch_queue_attr_set_finalizer(attr,
-                                                       ^(dispatch_queue_t dq) {
-                                                               SCDynamicStoreRef       store;
-
-                                                               store = (SCDynamicStoreRef)dispatch_get_context(dq);
-                                                               CFRelease(store);
-                                                       });
-               if (res != 0) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore dispatch_queue_attr_set_finalizer() failed"));
-                       dispatch_release(attr);
-                       _SCErrorSet(kSCStatusFailed);
-                       goto cleanup;
-               }
-               storePrivate->callbackQueue = dispatch_queue_create("com.apple.SCDynamicStore.notifications", attr);
-               dispatch_release(attr);
+               storePrivate->callbackQueue = dispatch_queue_create("com.apple.SCDynamicStore.notifications", NULL);
                if (storePrivate->callbackQueue == NULL){
                        SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore dispatch_queue_create() failed"));
                        _SCErrorSet(kSCStatusFailed);
@@ -754,16 +737,27 @@ SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue)
                }
                CFRetain(store);        // Note: will be released when the dispatch queue is released
                dispatch_set_context(storePrivate->callbackQueue, (void *)store);
+               dispatch_set_finalizer_f(storePrivate->callbackQueue, (dispatch_function_t)CFRelease);
 
-               dispatch_suspend(storePrivate->callbackQueue);
+               /*
+                * create a dispatch source for the mach notifications
+                */
                mp = CFMachPortGetPort(storePrivate->callbackPort);
-               storePrivate->callbackSource = dispatch_source_mig_create(mp, sizeof(mach_msg_header_t), NULL, storePrivate->callbackQueue, SCDynamicStoreNotifyMIGCallback);
+               storePrivate->callbackSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
+                                                                     mp,
+                                                                     0,
+                                                                     storePrivate->callbackQueue);
                if (storePrivate->callbackSource == NULL) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore dispatch_source_mig_create() failed"));
+                       SCLog(TRUE, LOG_ERR, CFSTR("SCDynamicStore dispatch_source_create() failed"));
                        _SCErrorSet(kSCStatusFailed);
                        goto cleanup;
                }
-               dispatch_resume(storePrivate->callbackQueue);
+               dispatch_source_set_event_handler(storePrivate->callbackSource, ^{
+                       dispatch_mig_server(storePrivate->callbackSource,
+                                           sizeof(mach_msg_header_t),
+                                           SCDynamicStoreNotifyMIGCallback);
+               });
+               dispatch_resume(storePrivate->callbackSource);
 
                ok = TRUE;
                goto done;
@@ -779,7 +773,11 @@ SCDynamicStoreSetDispatchQueue(SCDynamicStoreRef store, dispatch_queue_t queue)
     cleanup :
 
        if (storePrivate->callbackSource != NULL) {
-               dispatch_cancel(storePrivate->callbackSource);
+               dispatch_source_cancel(storePrivate->callbackSource);
+               if (storePrivate->callbackQueue != dispatch_get_current_queue()) {
+                       // ensure the cancellation has completed
+                       dispatch_sync(storePrivate->callbackQueue, ^{});
+               }
                dispatch_release(storePrivate->callbackSource);
                storePrivate->callbackSource = NULL;
        }
index 55305ed13070e667d501f87bbf95ccc86dd755c9..13ff626c281f007cd30b11a9257be6aead46557e 100644 (file)
@@ -139,6 +139,11 @@ typedef struct {
        Boolean                 modemIsV92;
        CFNumberRef             type;
        CFNumberRef             unit;
+       struct {
+               CFStringRef     name;
+               CFNumberRef     vid;
+               CFNumberRef     pid;
+       } usb;
 
        // misc
        int                     sort_order;             // sort order for this interface
index ec41e4cd11715ae64dd2865688f0f1868eedb96f..63ba8804602c3e97b63706b55ff37410a8ed83d3 100644 (file)
@@ -167,6 +167,15 @@ _SCNetworkInterfaceCreateWithIONetworkInterfaceObject      (io_object_t                    if_obj)         __
 #define        kSCNetworkInterfaceConfigurationActionValuePrompt       CFSTR("Prompt")
 #define        kSCNetworkInterfaceConfigurationActionValueConfigure    CFSTR("Configure")
 
+/*!
+       @function _SCNetworkInterfaceCopyInterfaceInfo
+       @discussion Returns interface details
+       @param interface The network interface.
+       @result A dictionary with details about the network interface.
+ */
+CFDictionaryRef
+_SCNetworkInterfaceCopyInterfaceInfo                   (SCNetworkInterfaceRef          interface)      __OSX_AVAILABLE_STARTING(__MAC_10_6,__IPHONE_3_0);
+
 /*!
        @function _SCNetworkInterfaceGetConfigurationAction
        @discussion Returns a user-notification / auto-configuration action for the interface.
index 2ec298f0dce37124580e456868424879ffde9ba5..01aeb222be7524c05bd868ae2a90e7b8e99d8860 100644 (file)
@@ -1108,41 +1108,35 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef connection,
 
 #if    !TARGET_OS_IPHONE
        if (queue != NULL) {
-               dispatch_queue_attr_t   attr;
-               mach_port_t             mp;
-               long                    res;
+               mach_port_t     mp;
 
                connectionPrivate->dispatchQueue = queue;
                dispatch_retain(connectionPrivate->dispatchQueue);
 
-               attr = dispatch_queue_attr_create();
-               res = dispatch_queue_attr_set_finalizer(attr,
-                                                       ^(dispatch_queue_t dq) {
-                                                               SCNetworkConnectionRef  connection;
-
-                                                               connection = (SCNetworkConnectionRef)dispatch_get_context(dq);
-                                                               CFRelease(connection);
-                                                       });
-               if (res != 0) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConnection dispatch_queue_attr_set_finalizer() failed"));
-                       dispatch_release(attr);
-                       goto fail;
-               }
-               connectionPrivate->callbackQueue = dispatch_queue_create("com.apple.SCNetworkConnection.notifications", attr);
-               dispatch_release(attr);
+               connectionPrivate->callbackQueue = dispatch_queue_create("com.apple.SCNetworkConnection.notifications", NULL);
                if (connectionPrivate->callbackQueue == NULL){
                        SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConnection dispatch_queue_create() failed"));
                        goto fail;
                }
                CFRetain(connection);   // Note: will be released when the dispatch queue is released
                dispatch_set_context(connectionPrivate->callbackQueue, connectionPrivate);
+               dispatch_set_finalizer_f(connectionPrivate->callbackQueue, (dispatch_function_t)CFRelease);
 
                mp = CFMachPortGetPort(connectionPrivate->notify_port);
-               connectionPrivate->callbackSource = dispatch_source_mig_create(mp, sizeof(mach_msg_header_t), NULL, connectionPrivate->callbackQueue, SCNetworkConnectionNotifyMIGCallback);
+               connectionPrivate->callbackSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
+                                                                          mp,
+                                                                          0,
+                                                                          connectionPrivate->callbackQueue);
                if (connectionPrivate->callbackSource == NULL) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConnection dispatch_source_mig_create() failed"));
+                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkConnection dispatch_source_create() failed"));
                        goto fail;
                }
+               dispatch_source_set_event_handler(connectionPrivate->callbackSource, ^{
+                       dispatch_mig_server(connectionPrivate->callbackSource,
+                                           sizeof(mach_msg_header_t),
+                                           SCNetworkConnectionNotifyMIGCallback);
+               });
+               dispatch_resume(connectionPrivate->callbackSource);
        } else
 #endif // !TARGET_OS_IPHONE
        {
@@ -1163,7 +1157,7 @@ __SCNetworkConnectionScheduleWithRunLoop(SCNetworkConnectionRef   connection,
     fail :
 
        if (connectionPrivate->callbackSource != NULL) {
-               dispatch_cancel(connectionPrivate->callbackSource);
+               dispatch_source_cancel(connectionPrivate->callbackSource);
                dispatch_release(connectionPrivate->callbackSource);
                connectionPrivate->callbackSource = NULL;
        }
@@ -1219,7 +1213,11 @@ __SCNetworkConnectionUnscheduleFromRunLoop(SCNetworkConnectionRef        connection,
 
 #if    !TARGET_OS_IPHONE
        if (runLoop == NULL) {
-               dispatch_cancel(connectionPrivate->callbackSource);
+               dispatch_source_cancel(connectionPrivate->callbackSource);
+               if (connectionPrivate->callbackQueue != dispatch_get_current_queue()) {
+                       // ensure the cancellation has completed
+                       dispatch_sync(connectionPrivate->callbackQueue, ^{});
+               }
                dispatch_release(connectionPrivate->callbackSource);
                connectionPrivate->callbackSource = NULL;
                dispatch_release(connectionPrivate->callbackQueue);
index 3c687ba3033f2bf47ee74bc45cfe2e63b5c15927..ce21227e8f52b1c76353b62991b30a634914d05e 100644 (file)
@@ -171,6 +171,7 @@ static SCNetworkInterfacePrivate __kSCNetworkInterfaceIPv4      = {
        FALSE,                                  // modemIsV92
        NULL,                                   // type
        NULL,                                   // unit
+       { NULL, 0, 0 },                         // usb { name, vid, pid }
        kSortUnknown,                           // sort_order
 #if    !TARGET_OS_IPHONE
        FALSE,                                  // supportsBond
@@ -324,14 +325,33 @@ __SCNetworkInterfaceCopyDescription(CFTypeRef cf)
        if (interfacePrivate->location != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", location = %@"), interfacePrivate->location);
        }
+       if (interfacePrivate->path != NULL) {
+               CFStringAppendFormat(result, NULL, CFSTR(", path = %@"), interfacePrivate->path);
+       }
        if (interfacePrivate->type != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", type = %@"), interfacePrivate->type);
        }
        if (interfacePrivate->unit != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", unit = %@"), interfacePrivate->unit);
        }
-       if (interfacePrivate->path != NULL) {
-               CFStringAppendFormat(result, NULL, CFSTR(", path = %@"), interfacePrivate->path);
+       if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
+               int     pid;
+               int     vid;
+
+               if (!isA_CFNumber(interfacePrivate->usb.pid) ||
+                   !CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &pid)) {
+                       pid = 0;
+               }
+               if (!isA_CFNumber(interfacePrivate->usb.vid) ||
+                   !CFNumberGetValue(interfacePrivate->usb.vid, kCFNumberIntType, &vid)) {
+                       vid = 0;
+               }
+
+               CFStringAppendFormat(result, NULL, CFSTR(", USB%s%@ vid/pid = 0x%0x/0x%0x"),
+                                    interfacePrivate->usb.name != NULL ? " name = " : "",
+                                    interfacePrivate->usb.name != NULL ? interfacePrivate->usb.name : CFSTR(""),
+                                    interfacePrivate->usb.vid,
+                                    interfacePrivate->usb.pid);
        }
        if (interfacePrivate->configurationAction != NULL) {
                CFStringAppendFormat(result, NULL, CFSTR(", action = %@"), interfacePrivate->configurationAction);
@@ -462,6 +482,15 @@ __SCNetworkInterfaceDeallocate(CFTypeRef cf)
        if (interfacePrivate->unit != NULL)
                CFRelease(interfacePrivate->unit);
 
+       if (interfacePrivate->usb.name != NULL)
+               CFRelease(interfacePrivate->usb.name);
+
+       if (interfacePrivate->usb.pid != NULL)
+               CFRelease(interfacePrivate->usb.pid);
+
+       if (interfacePrivate->usb.vid != NULL)
+               CFRelease(interfacePrivate->usb.vid);
+
 #if    !TARGET_OS_IPHONE
        if (interfacePrivate->bond.interfaces != NULL)
                CFRelease(interfacePrivate->bond.interfaces);
@@ -649,6 +678,9 @@ __SCNetworkInterfaceCreatePrivate(CFAllocatorRef    allocator,
        interfacePrivate->modemIsV92                    = FALSE;
        interfacePrivate->type                          = NULL;
        interfacePrivate->unit                          = NULL;
+       interfacePrivate->usb.name                      = NULL;
+       interfacePrivate->usb.vid                       = NULL;
+       interfacePrivate->usb.pid                       = NULL;
        interfacePrivate->sort_order                    = kSortUnknown;
 #if    !TARGET_OS_IPHONE
        interfacePrivate->supportsBond                  = FALSE;
@@ -1356,6 +1388,36 @@ isBluetoothBuiltin(Boolean *haveController)
 }
 
 
+static void
+processUSBInterface(SCNetworkInterfacePrivateRef       interfacePrivate,
+                   io_registry_entry_t                 interface,
+                   CFDictionaryRef                     interface_dict,
+                   io_registry_entry_t                 controller,
+                   CFDictionaryRef                     controller_dict,
+                   io_registry_entry_t                 bus,
+                   CFDictionaryRef                     bus_dict)
+{
+       // capture USB info
+       interfacePrivate->usb.name = IORegistryEntrySearchCFProperty(interface,
+                                                                    kIOServicePlane,
+                                                                    CFSTR(kUSBProductString),
+                                                                    NULL,
+                                                                    kIORegistryIterateRecursively | kIORegistryIterateParents);
+       interfacePrivate->usb.vid  = IORegistryEntrySearchCFProperty(interface,
+                                                                    kIOServicePlane,
+                                                                    CFSTR(kUSBVendorID),
+                                                                    NULL,
+                                                                    kIORegistryIterateRecursively | kIORegistryIterateParents);
+       interfacePrivate->usb.pid  = IORegistryEntrySearchCFProperty(interface,
+                                                                    kIOServicePlane,
+                                                                    CFSTR(kUSBProductID),
+                                                                    NULL,
+                                                                    kIORegistryIterateRecursively | kIORegistryIterateParents);
+
+       return;
+}
+
+
 #pragma mark -
 #pragma mark Interface enumeration
 
@@ -1409,6 +1471,14 @@ processNetworkInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                                interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
                                interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
                                interfacePrivate->sort_order            = kSortBluetoothPAN;
+                       } else if (IOObjectConformsTo(controller, "AppleUSBEthernetHost")) {
+                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                               interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                               interfacePrivate->sort_order            = kSortTethered;
+                       } else if (IOObjectConformsTo(controller, "AppleUSBCDCECMData")) {
+                               interfacePrivate->interface_type        = kSCNetworkInterfaceTypeEthernet;
+                               interfacePrivate->entity_type           = kSCValNetInterfaceTypeEthernet;
+                               interfacePrivate->sort_order            = kSortWWANEthernet;
                        } else {
                                str = IODictionaryCopyCFStringValue(bus_dict, CFSTR("name"));
                                if ((str != NULL) && CFEqual(str, CFSTR("radio"))) {
@@ -1429,13 +1499,6 @@ processNetworkInterface(SCNetworkInterfacePrivateRef     interfacePrivate,
                                if (str != NULL) CFRelease(str);
                        }
 
-                       // check if WWAN Ethernet
-                       if (IOObjectConformsTo(controller, "AppleUSBEthernetHost")) {
-                               interfacePrivate->sort_order = kSortTethered;
-                       } else if (IOObjectConformsTo(controller, "AppleUSBCDCECMData")) {
-                               interfacePrivate->sort_order = kSortWWANEthernet;
-                       }
-
                        // built-in
                        val = isA_CFBoolean(CFDictionaryGetValue(interface_dict, CFSTR(kIOBuiltin)));
                        if (val == NULL) {
@@ -1509,19 +1572,24 @@ processNetworkInterface(SCNetworkInterfacePrivateRef    interfacePrivate,
                                                }
                                        } else if (CFEqual(provider, CFSTR("IOUSBDevice")) ||
                                                   CFEqual(provider, CFSTR("IOUSBInterface"))) {
+
+                                               processUSBInterface(interfacePrivate,
+                                                                   interface,
+                                                                   interface_dict,
+                                                                   controller,
+                                                                   controller_dict,
+                                                                   bus,
+                                                                   bus_dict);
+
                                                // check if a "Product Name" has been provided
                                                val = IORegistryEntrySearchCFProperty(interface,
                                                                                      kIOServicePlane,
                                                                                      CFSTR(kIOPropertyProductNameKey),
                                                                                      NULL,
                                                                                      kIORegistryIterateRecursively | kIORegistryIterateParents);
-                                               if (val == NULL) {
-                                                       // check if a "USB Product Name" has been provided
-                                                       val = IORegistryEntrySearchCFProperty(interface,
-                                                                                             kIOServicePlane,
-                                                                                             CFSTR(kUSBProductString),
-                                                                                             NULL,
-                                                                                             kIORegistryIterateRecursively | kIORegistryIterateParents);
+                                               if ((val == NULL) && (interfacePrivate->usb.name != NULL)) {
+                                                       // else, use "USB Product Name" if available
+                                                       val = CFRetain(interfacePrivate->usb.name);
                                                }
                                                if (val != NULL) {
                                                        CFStringRef     productName;
@@ -5245,6 +5313,47 @@ SCNetworkInterfaceSetPassword(SCNetworkInterfaceRef              interface,
 #pragma mark SCNetworkInterface [InterfaceNamer] SPIs
 
 
+CFDictionaryRef
+_SCNetworkInterfaceCopyInterfaceInfo(SCNetworkInterfaceRef interface)
+{
+       CFMutableDictionaryRef          info;
+       SCNetworkInterfacePrivateRef    interfacePrivate        = (SCNetworkInterfacePrivateRef)interface;
+       CFStringRef                     name;
+
+       info = CFDictionaryCreateMutable(NULL,
+                                        0,
+                                        &kCFTypeDictionaryKeyCallBacks,
+                                        &kCFTypeDictionaryValueCallBacks);
+
+       // add non-localized interface name
+       name = __SCNetworkInterfaceGetNonLocalizedDisplayName(interface);
+       if (name != NULL) {
+               CFDictionaryAddValue(info, kSCPropUserDefinedName, name);
+       }
+
+       // add USB info
+       if ((interfacePrivate->usb.vid != NULL) || (interfacePrivate->usb.pid != NULL)) {
+               if (interfacePrivate->usb.name != NULL) {
+                       CFDictionaryAddValue(info, CFSTR(kUSBProductString), interfacePrivate->usb.name);
+               }
+               if (interfacePrivate->usb.vid != NULL) {
+                       CFDictionaryAddValue(info, CFSTR(kUSBVendorID), interfacePrivate->usb.vid);
+               }
+               if (interfacePrivate->usb.pid != NULL) {
+                       CFDictionaryAddValue(info, CFSTR(kUSBProductID), interfacePrivate->usb.pid);
+               }
+       }
+
+       if (CFDictionaryGetCount(info) == 0) {
+               // do not return an empty dictionary
+               CFRelease(info);
+               info = NULL;
+       }
+
+       return info;
+}
+
+
 SCNetworkInterfaceRef
 _SCNetworkInterfaceCreateWithIONetworkInterfaceObject(io_object_t if_obj)
 {
@@ -5523,6 +5632,15 @@ __SCNetworkInterfaceCreateCopy(CFAllocatorRef            allocator,
        if (oldPrivate->unit != NULL) {
                newPrivate->unit                = CFRetain(oldPrivate->unit);
        }
+       if (oldPrivate->usb.name != NULL) {
+               newPrivate->usb.name            = CFRetain(oldPrivate->usb.name);
+       }
+       if (oldPrivate->usb.vid != NULL) {
+               newPrivate->usb.vid             = CFRetain(oldPrivate->usb.vid);
+       }
+       if (oldPrivate->usb.pid != NULL) {
+               newPrivate->usb.pid             = CFRetain(oldPrivate->usb.pid);
+       }
        newPrivate->sort_order                  = oldPrivate->sort_order;
 #if    !TARGET_OS_IPHONE
        newPrivate->supportsBond                = oldPrivate->supportsBond;
index 658d9e479778dbccae34c1eac2c8c0b4f294c498..9d8c41e510e85049bb4e3beb0b8f9c1c813f2fe8 100644 (file)
@@ -1910,39 +1910,29 @@ enqueueAsyncDNSQuery(SCNetworkReachabilityRef target, mach_port_t mp)
                                                          NULL);
 #if    !TARGET_OS_IPHONE
        if (targetPrivate->dispatchQueue != NULL) {
-               dispatch_queue_attr_t   attr;
-               long                    res;
-
-               attr = dispatch_queue_attr_create();
-               res = dispatch_queue_attr_set_finalizer(attr,
-                                                       ^(dispatch_queue_t dq) {
-                                                               SCNetworkReachabilityRef        target;
-
-                                                               target = (SCNetworkReachabilityRef)dispatch_get_context(dq);
-                                                               CFRelease(target);
-                                                       });
-               if (res != 0) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkReachability dispatch_queue_attr_set_finalizer() failed"));
-                       dispatch_release(attr);
-                       goto fail;
-               }
-               targetPrivate->asyncDNSQueue = dispatch_queue_create("com.apple.SCNetworkReachabilty.async_DNS_query", attr);
-               dispatch_release(attr);
+               targetPrivate->asyncDNSQueue = dispatch_queue_create("com.apple.SCNetworkReachabilty.async_DNS_query", NULL);
                if (targetPrivate->asyncDNSQueue == NULL) {
                        SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkReachability dispatch_queue_create() failed"));
                        goto fail;
                }
                CFRetain(target);       // Note: will be released when the dispatch queue is released
                dispatch_set_context(targetPrivate->asyncDNSQueue, (void *)target);
-               targetPrivate->asyncDNSSource = dispatch_source_mig_create(mp,
-                                                                          sizeof(mach_msg_header_t),
-                                                                          NULL,
-                                                                          targetPrivate->asyncDNSQueue,
-                                                                          SCNetworkReachabilityNotifyMIGCallback);
+               dispatch_set_finalizer_f(targetPrivate->asyncDNSQueue, (dispatch_function_t)CFRelease);
+
+               targetPrivate->asyncDNSSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV,
+                                                                      mp,
+                                                                      0,
+                                                                      targetPrivate->asyncDNSQueue);
                if (targetPrivate->asyncDNSSource == NULL) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkReachability dispatch_source_mig_create() failed"));
+                       SCLog(TRUE, LOG_ERR, CFSTR("SCNetworkReachability dispatch_source_create() failed"));
                        goto fail;
                }
+               dispatch_source_set_event_handler(targetPrivate->asyncDNSSource, ^{
+                       dispatch_mig_server(targetPrivate->asyncDNSSource,
+                                           sizeof(mach_msg_header_t),
+                                           SCNetworkReachabilityNotifyMIGCallback);
+               });
+               dispatch_resume(targetPrivate->asyncDNSSource);
        } else
 #endif // !TARGET_OS_IPHONE
        if (targetPrivate->rls != NULL) {
@@ -1966,7 +1956,7 @@ enqueueAsyncDNSQuery(SCNetworkReachabilityRef target, mach_port_t mp)
     fail :
 
        if (targetPrivate->asyncDNSSource != NULL) {
-               dispatch_cancel(targetPrivate->asyncDNSSource);
+               dispatch_source_cancel(targetPrivate->asyncDNSSource);
                dispatch_release(targetPrivate->asyncDNSSource);
                targetPrivate->asyncDNSSource = NULL;
        }
@@ -1993,7 +1983,15 @@ dequeueAsyncDNSQuery(SCNetworkReachabilityRef target)
 
 #if    !TARGET_OS_IPHONE
        if (targetPrivate->asyncDNSSource != NULL) {
-               dispatch_cancel(targetPrivate->asyncDNSSource);
+               dispatch_source_cancel(targetPrivate->asyncDNSSource);
+               if (targetPrivate->asyncDNSQueue != dispatch_get_current_queue()) {
+                       // ensure the cancellation has completed
+                       pthread_mutex_unlock(&targetPrivate->lock);
+                       dispatch_sync(targetPrivate->asyncDNSQueue, ^{});
+                       pthread_mutex_lock(&targetPrivate->lock);
+               }
+       }
+       if (targetPrivate->asyncDNSSource != NULL) {
                dispatch_release(targetPrivate->asyncDNSSource);
                targetPrivate->asyncDNSSource = NULL;
        }
@@ -3725,27 +3723,7 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef      target,
                __SCNetworkReachabilityReachabilitySetNotifications(hn_store);
 
 #if    !TARGET_OS_IPHONE
-               dispatch_queue_attr_t   attr;
-               long                    res;
-
-               attr = dispatch_queue_attr_create();
-               res = dispatch_queue_attr_set_finalizer(attr,
-                                                       ^(dispatch_queue_t dq) {
-                                                               SCDynamicStoreRef       hn_store;
-
-                                                               hn_store = (SCDynamicStoreRef)dispatch_get_context(dq);
-                                                               CFRelease(hn_store);
-                                                       });
-               if (res != 0) {
-                       SCLog(TRUE, LOG_ERR, CFSTR("__SCNetworkReachabilityScheduleWithRunLoop dispatch_queue_attr_set_finalizer() failed"));
-                       dispatch_release(attr);
-                       CFRelease(hn_store);
-                       hn_store = NULL;
-                       _SCErrorSet(kSCStatusFailed);
-                       goto done;
-               }
-               hn_dispatchQueue = dispatch_queue_create("com.apple.SCNetworkReachabilty.network_changes", attr);
-               dispatch_release(attr);
+               hn_dispatchQueue = dispatch_queue_create("com.apple.SCNetworkReachabilty.network_changes", NULL);
                if (hn_dispatchQueue == NULL) {
                        SCLog(TRUE, LOG_ERR, CFSTR("__SCNetworkReachabilityScheduleWithRunLoop dispatch_queue_create() failed"));
                        _SCErrorSet(kSCStatusFailed);
@@ -3755,6 +3733,7 @@ __SCNetworkReachabilityScheduleWithRunLoop(SCNetworkReachabilityRef       target,
                }
                CFRetain(hn_store);     // Note: will be released when the dispatch queue is released
                dispatch_set_context(hn_dispatchQueue, (void *)hn_store);
+               dispatch_set_finalizer_f(hn_dispatchQueue, (dispatch_function_t)CFRelease);
 
                ok = SCDynamicStoreSetDispatchQueue(hn_store, hn_dispatchQueue);
                if (!ok) {
index 8bf91c2c234f57cfdf10aa4e754639d0d4b14239..ad195e6bd849e1f2528dc10fdc8a541a0369edf3 100644 (file)
@@ -249,12 +249,23 @@ _watcher(void *arg)
                return NULL;
        }
 
-       notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
-       if (!notifyRls) {
-               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
-               return NULL;
+#if    !TARGET_OS_IPHONE
+       if (doDispatch) {
+               if (!SCDynamicStoreSetDispatchQueue(store, dispatch_get_current_queue())) {
+                       SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
+                       return NULL;
+               }
+               notifyRls = (CFRunLoopSourceRef)kCFNull;
+       } else
+#endif // !TARGET_OS_IPHONE
+       {
+               notifyRls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
+               if (!notifyRls) {
+                       SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
+                       return NULL;
+               }
+               CFRunLoopAddSource(notifyRl, notifyRls, kCFRunLoopDefaultMode);
        }
-       CFRunLoopAddSource(notifyRl, notifyRls, kCFRunLoopDefaultMode);
 
        CFRunLoopRun();
        return NULL;
@@ -479,8 +490,18 @@ void
 do_notify_cancel(int argc, char **argv)
 {
        if (notifyRls) {
-               CFRunLoopSourceInvalidate(notifyRls);
-               CFRelease(notifyRls);
+#if    !TARGET_OS_IPHONE
+               if (doDispatch) {
+                       if (!SCDynamicStoreSetDispatchQueue(store, NULL)) {
+                               SCPrint(TRUE, stdout, CFSTR("  %s\n"), SCErrorString(SCError()));
+                               return;
+                       }
+               } else
+#endif // !TARGET_OS_IPHONE
+               {
+                       CFRunLoopSourceInvalidate(notifyRls);
+                       CFRelease(notifyRls);
+               }
                notifyRls = NULL;
        }
 
index 4e7f3a1b4b10ffb7564440525d91ed7b9399893c..08703da3abab8f2bb9626817d8bf6b5ae0b70202 100644 (file)
@@ -73,6 +73,7 @@
 
 __private_extern__ AuthorizationRef    authorization   = NULL;
 __private_extern__ InputRef            currentInput    = NULL;
+__private_extern__ Boolean             doDispatch      = FALSE;
 __private_extern__ int                 nesting         = 0;
 __private_extern__ CFRunLoopRef                notifyRl        = NULL;
 __private_extern__ CFRunLoopSourceRef  notifyRls       = NULL;
@@ -84,11 +85,13 @@ __private_extern__ CFMutableArrayRef        watchedPatterns = NULL;
 
 static const struct option longopts[] = {
 //     { "debug",              no_argument,            NULL,   'd'     },
+//     { "dispatch",           no_argument,            NULL,   'D'     },
 //     { "verbose",            no_argument,            NULL,   'v'     },
 //     { "SPI",                no_argument,            NULL,   'p'     },
 //     { "check-reachability", required_argument,      NULL,   'r'     },
 //     { "timeout",            required_argument,      NULL,   't'     },
 //     { "wait-key",           required_argument,      NULL,   'w'     },
+//     { "watch-reachability", no_argument,            NULL,   'W'     },
        { "dns",                no_argument,            NULL,   0       },
        { "get",                required_argument,      NULL,   0       },
        { "help",               no_argument,            NULL,   '?'     },
@@ -312,12 +315,15 @@ main(int argc, char * const argv[])
 
        /* process any arguments */
 
-       while ((opt = getopt_long(argc, argv, "dvprt:w:W", longopts, &opti)) != -1)
+       while ((opt = getopt_long(argc, argv, "dDvprt:w:W", longopts, &opti)) != -1)
                switch(opt) {
                case 'd':
                        _sc_debug = TRUE;
                        _sc_log   = FALSE;      /* enable framework logging */
                        break;
+               case 'D':
+                       doDispatch = TRUE;
+                       break;
                case 'v':
                        _sc_verbose = TRUE;
                        _sc_log     = FALSE;    /* enable framework logging */
index 16699f12ade1e6988dd53b0d5a841d9400a60282..75bd7f4d41e191bea0b1ae51fed01c96090aab72 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2005, 2009 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -51,6 +51,7 @@ typedef struct {
 
 extern AuthorizationRef                authorization;
 extern InputRef                        currentInput;
+extern Boolean                 doDispatch;
 extern int                     nesting;
 extern CFRunLoopRef            notifyRl;
 extern CFRunLoopSourceRef      notifyRls;
index d9d316ac55e08b37a3698955914b3c2200a3e165..cc9f95f7f7c0f2b39817c0555dec7853777406ba 100644 (file)
@@ -378,14 +378,24 @@ do_watchReachability(int argc, char **argv)
                exit(1);
        }
 
-       if (!SCNetworkReachabilityScheduleWithRunLoop(target_async, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
-               printf("SCNetworkReachabilityScheduleWithRunLoop() failed: %s\n", SCErrorString(SCError()));
-               exit(1);
+#if    !TARGET_OS_IPHONE
+       if (doDispatch) {
+               if (!SCNetworkReachabilitySetDispatchQueue(target_async, dispatch_get_current_queue())) {
+                       printf("SCNetworkReachabilitySetDispatchQueue() failed: %s\n", SCErrorString(SCError()));
+                       exit(1);
+               }
+       } else
+#endif // !TARGET_OS_IPHONE
+       {
+               if (!SCNetworkReachabilityScheduleWithRunLoop(target_async, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode)) {
+                       printf("SCNetworkReachabilityScheduleWithRunLoop() failed: %s\n", SCErrorString(SCError()));
+                       exit(1);
+               }
        }
 
        // Note: now that we are scheduled on a run loop we can call SCNetworkReachabilityGetFlags()
        //       to get the current status.  For "names", a DNS lookup has already been initiated.
-       SCPrint(TRUE, stdout, CFSTR(" 2: on runloop\n"));
+       SCPrint(TRUE, stdout, CFSTR(" 2: on %s\n"), doDispatch ? "dispatch queue" : "runloop");
        SCPrint(TRUE, stdout, CFSTR("   %@\n"), target_async);
        _printReachability(target_async);
        SCPrint(TRUE, stdout, CFSTR("\n"));