adium-1.4 2636:f8d77bb2192d: Add an observer for both AF_INET (I...
commits at adium.im
commits at adium.im
Sat Oct 24 15:33:00 UTC 2009
details: http://hg.adium.im/adium-1.4/rev/f8d77bb2192d
revision: 2636:f8d77bb2192d
author: Zachary West <zacw at adium.im>
date: Sat Oct 24 11:32:51 2009 -0400
Add an observer for both AF_INET (IPv4) and AF_INET6 (IPv6) DNS records for connection hosts. Fixes #12632.
When we're determining reachability, we consult all entries for a host, instead of the one that changed. We only add one observer for each record type.
diffs (144 lines):
diff -r 08e3f43120bb -r f8d77bb2192d Frameworks/AIUtilities Framework/Source/AIHostReachabilityMonitor.m
--- a/Frameworks/AIUtilities Framework/Source/AIHostReachabilityMonitor.m Tue Oct 20 23:07:17 2009 -0400
+++ b/Frameworks/AIUtilities Framework/Source/AIHostReachabilityMonitor.m Sat Oct 24 11:32:51 2009 -0400
@@ -198,7 +198,7 @@
* @param reachability The SCNetworkReachabilityRef for the host which changed
* @param isReachable YES if the host is now reachable; NO if it is not reachable
*/
-- (void)reachability:(SCNetworkReachabilityRef)reachability changedToReachable:(BOOL)isReachable
+- (void)reachabilityChanged:(SCNetworkReachabilityRef)reachability
{
[hostAndObserverListLock lock];
@@ -207,7 +207,26 @@
NSString *host = [hosts objectAtIndex:i];
id <AIHostReachabilityObserver> observer = [observers objectAtIndex:i];
- if (isReachable) {
+ BOOL anyHostsReachable = NO;
+
+ // If we have multiple host <-> IP links (AAAA record and an A record), we need to check agreement.
+ for (NSUInteger index = 0; index < hosts.count; index++) {
+ if (![host isEqualToString:[hosts objectAtIndex:index]])
+ continue;
+
+ SCNetworkReachabilityRef otherReachability = (SCNetworkReachabilityRef)[reachabilities objectAtIndex:index];
+ SCNetworkConnectionFlags flags;
+
+ if (SCNetworkReachabilityGetFlags(otherReachability, &flags)
+ && (flags & kSCNetworkFlagsReachable)
+ && !(flags & kSCNetworkFlagsConnectionRequired)) {
+ anyHostsReachable = YES;
+ break;
+ }
+ }
+
+ // Return reachability based on any reachability response.
+ if (anyHostsReachable) {
[observer hostReachabilityMonitor:self hostIsReachable:host];
} else {
[observer hostReachabilityMonitor:self hostIsNotReachable:host];
@@ -224,9 +243,6 @@
*/
static void hostReachabilityChangedCallback(SCNetworkReachabilityRef target, SCNetworkConnectionFlags flags, void *info)
{
- BOOL reachable = (flags & kSCNetworkFlagsReachable) &&
- !(flags & kSCNetworkFlagsConnectionRequired);
-
#if CONNECTIVITY_DEBUG
NSLog(@"*** hostReachabilityChangedCallback got flags: %c%c%c%c%c%c%c \n",
(flags & kSCNetworkFlagsTransientConnection) ? 't' : '-',
@@ -237,9 +253,9 @@
(flags & kSCNetworkFlagsIsLocalAddress) ? 'l' : '-',
(flags & kSCNetworkFlagsIsDirect) ? 'd' : '-');
#endif
-
+
AIHostReachabilityMonitor *self = info;
- [self reachability:target changedToReachable:reachable];
+ [self reachabilityChanged:target];
}
/*
@@ -255,8 +271,34 @@
NSString *host = [infoDict objectForKey:@"host"];
if (typeInfo == kCFHostAddresses) {
+ //CFHostGetAddressing returns a CFArrayRef of CFDataRefs which wrap struct sockaddr
CFArrayRef addresses = CFHostGetAddressing(theHost, NULL);
- if (addresses && CFArrayGetCount(addresses)) {
+
+ if (!CFArrayGetCount(addresses)) {
+ /* We were not able to resolve the host name to an IP address. This is most likely because we have no
+ * Internet connection or because the user is attempting to connect to MSN.
+ *
+ * Add to unconfiguredHostsAndObservers so we can try configuring again later.
+ */
+ [self addUnconfiguredHost:host
+ observer:observer];
+ }
+
+ // Only add 1 observer for IPv6 and one for IPv4.
+ BOOL addedIPv4 = NO, addedIPv6 = NO;
+
+ for (NSData *saData in (NSArray *)addresses) {
+ struct sockaddr *remoteAddr = (struct sockaddr *)saData.bytes;
+
+ if ((remoteAddr->sa_family == AF_INET && addedIPv4) || (remoteAddr->sa_family == AF_INET6 && addedIPv6)) {
+ continue;
+ }
+
+ if (remoteAddr->sa_family == AF_INET)
+ addedIPv4 = YES;
+ if (remoteAddr->sa_family == AF_INET6)
+ addedIPv6 = YES;
+
SCNetworkReachabilityRef reachabilityRef;
SCNetworkReachabilityContext reachabilityContext = {
.version = 0,
@@ -267,7 +309,6 @@
};
SCNetworkConnectionFlags flags;
struct sockaddr_in localAddr;
- struct sockaddr *remoteAddr;
/* Create a reachability reference pair with localhost and the remote host */
@@ -277,10 +318,6 @@
localAddr.sin_family = AF_INET;
inet_aton("127.0.0.1", &localAddr.sin_addr);
- //CFHostGetAddressing returns a CFArrayRef of CFDataRefs which wrap struct sockaddr
- CFDataRef saData = (CFDataRef)CFArrayGetValueAtIndex(addresses, 0);
- remoteAddr = (struct sockaddr *)CFDataGetBytePtr(saData);
-
//Create the pair
reachabilityRef = SCNetworkReachabilityCreateWithAddressPair(NULL,
(struct sockaddr *)&localAddr,
@@ -303,9 +340,9 @@
if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags)) {
//We already have valid flags for the reachabilityRef
-#if CONNECTIVITY_DEBUG
+ #if CONNECTIVITY_DEBUG
NSLog(@"Immediate reachability info for %@", reachabilityRef);
-#endif
+ #endif
hostReachabilityChangedCallback(reachabilityRef,
flags,
self);
@@ -335,14 +372,6 @@
NULL);
}
- } else {
- /* We were not able to resolve the host name to an IP address. This is most likely because we have no
- * Internet connection or because the user is attempting to connect to MSN.
- *
- * Add to unconfiguredHostsAndObservers so we can try configuring again later.
- */
- [self addUnconfiguredHost:host
- observer:observer];
}
} else if (typeInfo == kCFHostReachability) {
More information about the commits
mailing list