Bonjour/MYAddressLookup.m
author Dan Preston <danpreston@codechemistry.com>
Tue May 05 15:27:20 2009 -0700 (2009-05-05)
changeset 40 423c134d3205
parent 28 732576fa8a0d
child 43 aab592ac36fc
child 45 8efb48eabd08
permissions -rw-r--r--
Tweaked release to be immediate instead of on autorelease pool.
     1 //
     2 //  MYAddressLookup.m
     3 //  MYNetwork
     4 //
     5 //  Created by Jens Alfke on 4/24/09.
     6 //  Copyright 2009 Jens Alfke. All rights reserved.
     7 //
     8 
     9 #import "MYAddressLookup.h"
    10 #import "IPAddress.h"
    11 #import "ExceptionUtils.h"
    12 #import "Test.h"
    13 #import "Logging.h"
    14 #import <dns_sd.h>
    15 
    16 
    17 @implementation MYAddressLookup
    18 
    19 - (id) initWithHostname: (NSString*)hostname
    20 {
    21     self = [super init];
    22     if (self != nil) {
    23         if (!hostname) {
    24             [self release];
    25             return nil;
    26         }
    27         _hostname = [hostname copy];
    28         _addresses = [[NSMutableArray alloc] init];
    29     }
    30     return self;
    31 }
    32 
    33 - (void) dealloc
    34 {
    35     [_hostname release];
    36     [_addresses release];
    37     [super dealloc];
    38 }
    39 
    40 
    41 - (NSString*) description
    42 {
    43     return $sprintf(@"%@[%@]", self.class,_hostname);
    44 }
    45 
    46 
    47 @synthesize port=_port, interfaceIndex=_interfaceIndex, addresses=_addresses;
    48 
    49 
    50 - (NSTimeInterval) timeToLive {
    51     return MAX(0.0, _expires - CFAbsoluteTimeGetCurrent());
    52 }
    53 
    54 
    55 - (void) priv_resolvedAddress: (const struct sockaddr*)sockaddr
    56                           ttl: (uint32_t)ttl
    57                         flags: (DNSServiceFlags)flags
    58 {
    59     HostAddress *address = [[HostAddress alloc] initWithHostname: _hostname 
    60                                                         sockaddr: sockaddr
    61                                                             port: _port];
    62     if (address) {
    63         if (flags & kDNSServiceFlagsAdd) {
    64             LogTo(DNS,@"%@ got %@ [TTL = %u]", self, address, ttl);
    65             [_addresses addObject: address];
    66         } else {
    67             LogTo(DNS,@"%@ lost %@ [TTL = %u]", self, address, ttl);
    68             [_addresses removeObject: address];
    69         }
    70         [address release];
    71     }
    72     
    73     _expires = CFAbsoluteTimeGetCurrent() + ttl;
    74 }
    75 
    76 
    77 static void lookupCallback(DNSServiceRef                    sdRef,
    78                            DNSServiceFlags                  flags,
    79                            uint32_t                         interfaceIndex,
    80                            DNSServiceErrorType              errorCode,
    81                            const char                       *hostname,
    82                            const struct sockaddr            *address,
    83                            uint32_t                         ttl,
    84                            void                             *context)
    85 {
    86     MYAddressLookup *lookup = context;
    87     @try{
    88         //LogTo(Bonjour, @"lookupCallback for %s (err=%i)", hostname,errorCode);
    89         if (errorCode)
    90             [lookup setError: errorCode];
    91         else
    92             [lookup priv_resolvedAddress: address ttl: ttl flags: flags];
    93     }catchAndReport(@"MYDNSLookup query callback");
    94     [lookup gotResponse: errorCode];
    95 }
    96 
    97 
    98 - (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr {
    99     [_addresses removeAllObjects];
   100     return DNSServiceGetAddrInfo(sdRefPtr,
   101                                  kDNSServiceFlagsShareConnection,
   102                                  _interfaceIndex, 0,
   103                                  _hostname.UTF8String,
   104                                  &lookupCallback, self);
   105 }
   106 
   107 
   108 @end
   109 
   110 
   111 
   112 TestCase(MYDNSLookup) {
   113     EnableLogTo(Bonjour,YES);
   114     EnableLogTo(DNS,YES);
   115     [NSRunLoop currentRunLoop]; // create runloop
   116 
   117     MYAddressLookup *lookup = [[MYAddressLookup alloc] initWithHostname: @"www.apple.com" port: 80];
   118     [lookup start];
   119     
   120     [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 10]];
   121     [lookup release];
   122 }    
   123 
   124 
   125 /*
   126  Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
   127  
   128  Redistribution and use in source and binary forms, with or without modification, are permitted
   129  provided that the following conditions are met:
   130  
   131  * Redistributions of source code must retain the above copyright notice, this list of conditions
   132  and the following disclaimer.
   133  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
   134  and the following disclaimer in the documentation and/or other materials provided with the
   135  distribution.
   136  
   137  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
   138  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
   139  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
   140  BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   141  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
   142   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   143  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
   144  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   145  */