Search code examples
iosreachability

How to interpret null getting returned from SCNetworkReachabilityCreateWithName?


We have this method in our code that returns a SCNetworkReachabilityRef using SCNetworkReachabilityCreateWithName:

- (SCNetworkReachabilityRef)cCreateReachabilityRefWithCStr:(const char *)host {
    return SCNetworkReachabilityCreateWithName(NULL, host);
}

At times we get back NULL for the reachability reference. What does the NULL return mean?

The Apple doc SCNetworkReachability Reference does not discuss NULL returns from these methods. But the Classes/Reachability.m file in the Reachability sample code accounts for the fact that SCNetworkReachabilityCreateWithName can return NULL, but without comment as to why.

So what does the NULL return mean and how am I to handle that?


Solution

  • In response to a similar query on the iOS Developer Forums What does a NULL return from SCNetworkReachabilityCreateWithName mean? (link is only accessible to iOS Developer Program members), someone from Apple Developer Support noted that, as far as he knew, there are only three reasons that SCNetworkReachabilityCreateWithName might return NULL:

    1. nodename is NULL (kSCStatusInvalidArgument);
    2. nodename is empty (kSCStatusInvalidArgument); or
    3. memory allocation problems (does not set a kSCStatusXxx).

    He also noted that the reachability APIs are in Darwin, and that the Darwin implementation is close to the implementation on both OS X and iOS. The code SCNetworkReachability.c from Darwin seems to confirm his take that the above three reasons are the only ways in which SCNetworkReachabilityCreateWithName returns NULL.

    I also learned that the System Configuration Reference contains information about detecting and interpreting errors generated by calling SCxxx functions, specifically things like SCError() and SCErrorString().

    I deliberately caused a NULL return from SCNetworkReachabilityCreateWithName by passing "" and NULL as names and then tried SCError and SCErrorString (referenced from the System Configuration Reference) and lo and behold I did some meaningful extra information:

    reachtest1[9274:11303] isReachableWithName: entry: name: ""
    reachtest1[9274:11303] SCNetworkReachabilityCreateWithName returned NULL!
    reachtest1[9274:11303] SCError: 1002 SCErrorString: Invalid argument
    
    reachtest1[9274:11303] isReachableWithName: entry: name: (null)
    reachtest1[9274:11303] SCNetworkReachabilityCreateWithName returned NULL!
    reachtest1[9274:11303] SCError: 1002 SCErrorString: Invalid argument
    

    This accounts for NULL getting returned from two of the three cases from the Darwin code.

    There's also a way to get a CFErrorRef using SCCopyLastError() which might actually have even more info in it. In addition to the aforementioned System Configuration Reference, see the CFError Reference.

    Given all this I'd say the first two cases wouldn't be retry-able since passing a NULL or zero-length host name is a progam logic error. The third memory-related case might be retry-able.