Bonjour/MYAddressLookup.m
changeset 28 732576fa8a0d
child 31 1d6924779df7
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/Bonjour/MYAddressLookup.m	Mon Apr 27 09:03:56 2009 -0700
     1.3 @@ -0,0 +1,122 @@
     1.4 +//
     1.5 +//  MYAddressLookup.m
     1.6 +//  MYNetwork
     1.7 +//
     1.8 +//  Created by Jens Alfke on 4/24/09.
     1.9 +//  Copyright 2009 Jens Alfke. All rights reserved.
    1.10 +//
    1.11 +
    1.12 +#import "MYAddressLookup.h"
    1.13 +#import "IPAddress.h"
    1.14 +#import "ExceptionUtils.h"
    1.15 +#import "Test.h"
    1.16 +#import "Logging.h"
    1.17 +#import <dns_sd.h>
    1.18 +
    1.19 +
    1.20 +@implementation MYAddressLookup
    1.21 +
    1.22 +- (id) initWithHostname: (NSString*)hostname
    1.23 +{
    1.24 +    self = [super init];
    1.25 +    if (self != nil) {
    1.26 +        if (!hostname) {
    1.27 +            [self release];
    1.28 +            return nil;
    1.29 +        }
    1.30 +        _hostname = [hostname copy];
    1.31 +        _addresses = [[NSMutableArray alloc] init];
    1.32 +    }
    1.33 +    return self;
    1.34 +}
    1.35 +
    1.36 +- (void) dealloc
    1.37 +{
    1.38 +    [_hostname release];
    1.39 +    [_addresses release];
    1.40 +    [super dealloc];
    1.41 +}
    1.42 +
    1.43 +
    1.44 +- (NSString*) description
    1.45 +{
    1.46 +    return $sprintf(@"%@[%@]", self.class,_hostname);
    1.47 +}
    1.48 +
    1.49 +
    1.50 +@synthesize port=_port, interfaceIndex=_interfaceIndex, addresses=_addresses;
    1.51 +
    1.52 +
    1.53 +- (NSTimeInterval) timeToLive {
    1.54 +    return MAX(0.0, _expires - CFAbsoluteTimeGetCurrent());
    1.55 +}
    1.56 +
    1.57 +
    1.58 +- (void) priv_resolvedAddress: (const struct sockaddr*)sockaddr
    1.59 +                          ttl: (uint32_t)ttl
    1.60 +                        flags: (DNSServiceFlags)flags
    1.61 +{
    1.62 +    HostAddress *address = [[HostAddress alloc] initWithHostname: _hostname 
    1.63 +                                                        sockaddr: sockaddr
    1.64 +                                                            port: _port];
    1.65 +    if (address) {
    1.66 +        if (flags & kDNSServiceFlagsAdd)
    1.67 +            [_addresses addObject: address];
    1.68 +        else
    1.69 +            [_addresses removeObject: address];
    1.70 +        [address release];
    1.71 +    }
    1.72 +    
    1.73 +    _expires = CFAbsoluteTimeGetCurrent() + ttl;
    1.74 +
    1.75 +    if (!(flags & kDNSServiceFlagsMoreComing))
    1.76 +        LogTo(DNS,@"Got addresses of %@: %@ [TTL = %u]", self, _addresses, ttl);
    1.77 +}
    1.78 +
    1.79 +
    1.80 +static void lookupCallback(DNSServiceRef                    sdRef,
    1.81 +                           DNSServiceFlags                  flags,
    1.82 +                           uint32_t                         interfaceIndex,
    1.83 +                           DNSServiceErrorType              errorCode,
    1.84 +                           const char                       *hostname,
    1.85 +                           const struct sockaddr            *address,
    1.86 +                           uint32_t                         ttl,
    1.87 +                           void                             *context)
    1.88 +{
    1.89 +    MYAddressLookup *lookup = context;
    1.90 +    @try{
    1.91 +        //LogTo(Bonjour, @"lookupCallback for %s (err=%i)", hostname,errorCode);
    1.92 +        if (errorCode)
    1.93 +            [lookup setError: errorCode];
    1.94 +        else
    1.95 +            [lookup priv_resolvedAddress: address ttl: ttl flags: flags];
    1.96 +    }catchAndReport(@"MYDNSLookup query callback");
    1.97 +}
    1.98 +
    1.99 +
   1.100 +- (DNSServiceRef) createServiceRef {
   1.101 +    [_addresses removeAllObjects];
   1.102 +    DNSServiceRef serviceRef = NULL;
   1.103 +    self.error = DNSServiceGetAddrInfo(&serviceRef, 0,
   1.104 +                                       _interfaceIndex, 0,
   1.105 +                                       _hostname.UTF8String,
   1.106 +                                       &lookupCallback, self);
   1.107 +    return serviceRef;
   1.108 +}
   1.109 +
   1.110 +
   1.111 +@end
   1.112 +
   1.113 +
   1.114 +
   1.115 +TestCase(MYDNSLookup) {
   1.116 +    EnableLogTo(Bonjour,YES);
   1.117 +    EnableLogTo(DNS,YES);
   1.118 +    [NSRunLoop currentRunLoop]; // create runloop
   1.119 +
   1.120 +    MYAddressLookup *lookup = [[MYAddressLookup alloc] initWithHostname: @"www.apple.com" port: 80];
   1.121 +    [lookup start];
   1.122 +    
   1.123 +    [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 10]];
   1.124 +    [lookup release];
   1.125 +}