Reachability.swift icon indicating copy to clipboard operation
Reachability.swift copied to clipboard

Reachability even with invalid host

Open perlguy99 opened this issue 9 years ago • 4 comments

I was looking at the ReachabilityTests and noticed that, for me at least, I am getting an unexpected result when using an invalid host.

The following code snippet:

        let reachability: Reachability
        let invalidHostName = "invalidhost2342342344.foobar.fubble"

        do {
            try reachability = Reachability(hostname: invalidHostName)
            print (reachability.currentReachabilityStatus)
        } catch {
            XCTAssert(false, "Unable to create reachability")
            return
        }

For me, the print statement is returning "WiFi"

If I run the actual unit tests, I get the "Invalid host name should never be reachable" error.

Is anyone else experiencing this?

Unless I am doing something wrong, this seems like a pretty big issue.

Thank you!

perlguy99 avatar Sep 06 '16 20:09 perlguy99

I am also getting this with my testInvalidHost unit test...

` let invalidHostName = "invalidhost_chachacha"

    guard let reachability = Reachability(hostname: invalidHostName) else {
        XCTAssert(false, "Unable to create reachability")
        return
    }

    let aExpectation = expectation(description: "Check invalid host")
    reachability.whenReachable = { reachability in
        DispatchQueue.main.async {
            XCTAssert(false, "\(invalidHostName) should never be reachable - \(reachability))")
        }
    }

`

XCTAssertTrue failed - invalidhost_chachacha should never be reachable

toddhopkinson avatar Sep 29 '16 00:09 toddhopkinson

Hi there @ashleymills, any update on this? (I have nearly the same unit test as @toddhopkinson.)

mrobert avatar Apr 19 '17 22:04 mrobert

I'm having exactly the same problem. Invalid hosts get reported as ".wifi".

The examples above are pretty much valid for me too, but I'll add mine.

guard let reachability = Reachability(hostname: "invalid.placeontheinternet.com") else {
	completion?(false)
	return
}
reachability.whenReachable = { (status) in
	print("reachable? \(status.connection)")
}
reachability.whenUnreachable = { (status) in
	print("unreachable")
}

do {
	try reachability.startNotifier()
} catch { // notify
	completion?(false)
}

Unfortunately, this is not a failure in this library, it's actually a problem with how SCNReachability (that this framework uses) defines if something is reachable. From Apple documentation:

The SCNetworkReachability programming interface allows an application to determine the status of a system's current network configuration and the reachability of a target host. A remote host is considered reachable when a data packet, sent by an application into the network stack, can leave the local device. Reachability does not guarantee that the data packet will actually be received by the host.

So as you can see, if the host is invalid, it will still be "reachable" for this library (and any other using the SCNNetworkReachability framework), because the packet can leave the device. Only the other end is not answering.

DigitalLeaves avatar Oct 30 '17 13:10 DigitalLeaves

The solution for me, in this case, is having two tests: a "local reachability test" using this library (or any other making use of SCNNetworkReachability) and a "remote reachability test" using a ping in Swify (a plain ping to the host).

Combining the two, you can say if the connection from the device is down (if both tests fail) or the host is invalid, down or otherwise unreachable (local reachability passes but remote one fails).

Hope it helps!

DigitalLeaves avatar Oct 30 '17 16:10 DigitalLeaves