Created
August 2, 2016 14:53
-
-
Save agentk/99fd9a3732aac169b17ae390d411ddb7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
enum HostResult { | |
case success([String]) | |
case failure(String) | |
var description: String { | |
switch self { | |
case let .success(addresses): return "\(addresses)" | |
case let .failure(error): return "\(error)" | |
} | |
} | |
} | |
// https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFStreamConstants/index.html#//apple_ref/doc/constant_group/CFStream_Error_Domain_Constants_CFHost_ | |
extension CFStreamError { | |
var description: String { | |
switch (domain, error) { | |
case (CFIndex(kCFStreamErrorDomainNetDB), EAI_NONAME): | |
return "NetDB error: hostname nor servname provided, or not known" | |
default: | |
return "error \(error) domain \(domain)" | |
} | |
} | |
} | |
func stringForIPAddress(address: NSData) -> String? { | |
var hostBuf = Array<Int8>(repeating: 0, count: Int(NI_MAXHOST)) | |
if getnameinfo( | |
UnsafePointer<sockaddr>(address.bytes), socklen_t(address.length), | |
&hostBuf, socklen_t(hostBuf.count), | |
nil, 0, | |
NI_NUMERICHOST | NI_NUMERICSERV) != 0 { | |
return nil | |
} | |
return String(cString: hostBuf) | |
} | |
func lookupAddresses(name: String) -> HostResult { | |
let host = CFHostCreateWithName(kCFAllocatorDefault, name).takeRetainedValue() | |
var error = CFStreamError() | |
let didStart = CFHostStartInfoResolution(host, .addresses, &error) | |
if error.error != 0 { | |
return .failure("😡 \(error.description)") | |
} | |
if !didStart { | |
return .failure("❌ Failed to start info resolution") | |
} | |
var resolved = DarwinBoolean(false) | |
guard let dataArray = (CFHostGetAddressing(host, &resolved)?.takeUnretainedValue() as [AnyObject]?) as? [NSData] else { | |
return .failure("💣 Error getting addresses") | |
} | |
return .success(dataArray.flatMap { stringForIPAddress(address: $0) }) | |
} | |
// --------------------------------------- | |
lookupAddresses(name: "localhost") // -> ["::1", "127.0.0.1"] | |
lookupAddresses(name: "google.com") // -> ["216.58.220.142"] | |
lookupAddresses(name: "facebook.com") // -> ["69.171.230.68"] | |
lookupAddresses(name: "v6.google.com") // -> "😡 NetDB error: hostname nor servname provided, or not known" | |
lookupAddresses(name: "v6.vvv.facebook.com") // -> "😡 NetDB error: hostname nor servname provided, or not known" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment