Fixed bug which caused PyBLIP to stop sending responses while the connection was closing.
5 // Created by Jens Alfke on 4/24/09.
6 // Copyright 2009 Jens Alfke. All rights reserved.
9 #import "MYAddressLookup.h"
10 #import "MYBonjourService.h"
12 #import "ExceptionUtils.h"
18 @interface MYAddressLookup ()
19 @property (copy) NSString *hostname;
23 @implementation MYAddressLookup
25 - (id) initWithHostname: (NSString*)hostname
33 _hostname = [hostname copy];
34 _addresses = [[NSMutableSet alloc] init];
40 - (id) _initWithBonjourService: (MYBonjourService*)service {
43 _service = [service retain];
44 _addresses = [[NSMutableSet alloc] init];
58 - (NSString*) description
60 return $sprintf(@"%@[%@]", self.class,_hostname);
64 @synthesize hostname=_hostname, port=_port, interfaceIndex=_interfaceIndex, addresses=_addresses;
67 - (NSTimeInterval) timeToLive {
68 return MAX(0.0, _expires - CFAbsoluteTimeGetCurrent());
76 // Service doesn't know its hostname yet; wait till it does:
77 LogTo(DNS,@"MYAddressLookup requesting hostname of %@ ...", _service);
79 return [_service start];
84 // Called by my _service's gotResponse method:
85 - (void) _serviceGotResponse {
87 DNSServiceErrorType err = _service.error;
92 NSString *hostname = _service.hostname;
93 UInt16 port = _service.port;
94 if (port!=_port || !$equal(hostname,_hostname)) {
95 self.hostname = hostname;
104 - (void) priv_resolvedAddress: (const struct sockaddr*)sockaddr
106 flags: (DNSServiceFlags)flags
108 HostAddress *address = [[HostAddress alloc] initWithHostname: _hostname
112 if (flags & kDNSServiceFlagsAdd) {
113 LogTo(DNS,@"%@ got %@ [TTL = %u]", self, address, ttl);
114 kvAddToSet(self, @"addresses", _addresses, address);
116 LogTo(DNS,@"%@ lost %@ [TTL = %u]", self, address, ttl);
117 kvRemoveFromSet(self, @"addresses", _addresses, address);
122 _expires = CFAbsoluteTimeGetCurrent() + ttl;
126 static void lookupCallback(DNSServiceRef sdRef,
127 DNSServiceFlags flags,
128 uint32_t interfaceIndex,
129 DNSServiceErrorType errorCode,
130 const char *hostname,
131 const struct sockaddr *address,
135 MYAddressLookup *lookup = context;
137 LogTo(DNS, @"lookupCallback for %s (err=%i)", hostname,errorCode);
139 [lookup setError: errorCode];
141 [lookup priv_resolvedAddress: address ttl: ttl flags: flags];
142 }catchAndReport(@"MYDNSLookup query callback");
143 [lookup gotResponse: errorCode];
147 - (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr {
149 kvSetSet(self, @"addresses", _addresses, nil);
150 return DNSServiceGetAddrInfo(sdRefPtr,
151 kDNSServiceFlagsShareConnection,
153 kDNSServiceProtocol_IPv4,
154 _hostname.UTF8String,
155 &lookupCallback, self);
163 TestCase(MYDNSLookup) {
164 EnableLogTo(Bonjour,YES);
165 EnableLogTo(DNS,YES);
166 [NSRunLoop currentRunLoop]; // create runloop
168 MYAddressLookup *lookup = [[MYAddressLookup alloc] initWithHostname: @"www.apple.com" port: 80];
171 [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 10]];
177 Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
179 Redistribution and use in source and binary forms, with or without modification, are permitted
180 provided that the following conditions are met:
182 * Redistributions of source code must retain the above copyright notice, this list of conditions
183 and the following disclaimer.
184 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
185 and the following disclaimer in the documentation and/or other materials provided with the
188 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
189 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
190 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
191 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
192 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
193 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
194 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
195 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.