jens@28: // jens@28: // MYAddressLookup.m jens@28: // MYNetwork jens@28: // jens@28: // Created by Jens Alfke on 4/24/09. jens@28: // Copyright 2009 Jens Alfke. All rights reserved. jens@28: // jens@28: jens@28: #import "MYAddressLookup.h" jens@28: #import "IPAddress.h" jens@28: #import "ExceptionUtils.h" jens@28: #import "Test.h" jens@28: #import "Logging.h" jens@28: #import jens@28: jens@28: jens@28: @implementation MYAddressLookup jens@28: jens@28: - (id) initWithHostname: (NSString*)hostname jens@28: { jens@28: self = [super init]; jens@28: if (self != nil) { jens@28: if (!hostname) { jens@28: [self release]; jens@28: return nil; jens@28: } jens@28: _hostname = [hostname copy]; jens@45: _addresses = [[NSMutableSet alloc] init]; jens@28: } jens@28: return self; jens@28: } jens@28: jens@28: - (void) dealloc jens@28: { jens@28: [_hostname release]; jens@28: [_addresses release]; jens@28: [super dealloc]; jens@28: } jens@28: jens@28: jens@28: - (NSString*) description jens@28: { jens@28: return $sprintf(@"%@[%@]", self.class,_hostname); jens@28: } jens@28: jens@28: jens@28: @synthesize port=_port, interfaceIndex=_interfaceIndex, addresses=_addresses; jens@28: jens@28: jens@28: - (NSTimeInterval) timeToLive { jens@28: return MAX(0.0, _expires - CFAbsoluteTimeGetCurrent()); jens@28: } jens@28: jens@28: jens@28: - (void) priv_resolvedAddress: (const struct sockaddr*)sockaddr jens@28: ttl: (uint32_t)ttl jens@28: flags: (DNSServiceFlags)flags jens@28: { jens@28: HostAddress *address = [[HostAddress alloc] initWithHostname: _hostname jens@28: sockaddr: sockaddr jens@28: port: _port]; jens@28: if (address) { jens@31: if (flags & kDNSServiceFlagsAdd) { jens@31: LogTo(DNS,@"%@ got %@ [TTL = %u]", self, address, ttl); jens@45: kvAddToSet(self, @"addresses", _addresses, address); jens@31: } else { jens@31: LogTo(DNS,@"%@ lost %@ [TTL = %u]", self, address, ttl); jens@45: kvRemoveFromSet(self, @"addresses", _addresses, address); jens@31: } jens@28: [address release]; jens@28: } jens@28: jens@28: _expires = CFAbsoluteTimeGetCurrent() + ttl; jens@28: } jens@28: jens@28: jens@28: static void lookupCallback(DNSServiceRef sdRef, jens@28: DNSServiceFlags flags, jens@28: uint32_t interfaceIndex, jens@28: DNSServiceErrorType errorCode, jens@28: const char *hostname, jens@28: const struct sockaddr *address, jens@28: uint32_t ttl, jens@28: void *context) jens@28: { jens@28: MYAddressLookup *lookup = context; jens@28: @try{ jens@28: //LogTo(Bonjour, @"lookupCallback for %s (err=%i)", hostname,errorCode); jens@28: if (errorCode) jens@28: [lookup setError: errorCode]; jens@28: else jens@28: [lookup priv_resolvedAddress: address ttl: ttl flags: flags]; jens@28: }catchAndReport(@"MYDNSLookup query callback"); jens@31: [lookup gotResponse: errorCode]; jens@28: } jens@28: jens@28: jens@31: - (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr { jens@45: kvSetSet(self, @"addresses", _addresses, nil); jens@31: return DNSServiceGetAddrInfo(sdRefPtr, jens@31: kDNSServiceFlagsShareConnection, jens@31: _interfaceIndex, 0, jens@31: _hostname.UTF8String, jens@31: &lookupCallback, self); jens@28: } jens@28: jens@28: jens@28: @end jens@28: jens@28: jens@28: jens@28: TestCase(MYDNSLookup) { jens@28: EnableLogTo(Bonjour,YES); jens@28: EnableLogTo(DNS,YES); jens@28: [NSRunLoop currentRunLoop]; // create runloop jens@28: jens@28: MYAddressLookup *lookup = [[MYAddressLookup alloc] initWithHostname: @"www.apple.com" port: 80]; jens@28: [lookup start]; jens@28: jens@28: [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 10]]; jens@28: [lookup release]; jens@28: } jens@31: jens@31: jens@31: /* jens@31: Copyright (c) 2009, Jens Alfke . All rights reserved. jens@31: jens@31: Redistribution and use in source and binary forms, with or without modification, are permitted jens@31: provided that the following conditions are met: jens@31: jens@31: * Redistributions of source code must retain the above copyright notice, this list of conditions jens@31: and the following disclaimer. jens@31: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions jens@31: and the following disclaimer in the documentation and/or other materials provided with the jens@31: distribution. jens@31: jens@31: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR jens@31: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND jens@31: FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI- jens@31: BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES jens@31: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR jens@31: PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN jens@31: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF jens@31: THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jens@31: */