jens@28: // jens@28: // MYBonjourQuery.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 "MYBonjourQuery.h" jens@28: #import "MYBonjourService.h" jens@28: #import "Test.h" jens@28: #import "Logging.h" jens@28: #import "ExceptionUtils.h" jens@28: #import jens@28: jens@28: jens@28: static NSString* kRecordTypeNames[] = { jens@28: @"0", jens@28: @"A", // = 1, /* Host address. */ jens@28: @"NS", // = 2, /* Authoritative server. */ jens@28: @"MD", // = 3, /* Mail destination. */ jens@28: @"MF", // = 4, /* Mail forwarder. */ jens@28: @"CNAME", // = 5, /* Canonical name. */ jens@28: @"SOA", // = 6, /* Start of authority zone. */ jens@28: @"MB", // = 7, /* Mailbox domain name. */ jens@28: @"MG", // = 8, /* Mail group member. */ jens@28: @"MR", // = 9, /* Mail rename name. */ jens@28: @"NULL", // = 10, /* Null resource record. */ jens@28: @"WKS", // = 11, /* Well known service. */ jens@28: @"PTR", // = 12, /* Domain name pointer. */ jens@28: @"HINFO", // = 13, /* Host information. */ jens@28: @"MINFO", // = 14, /* Mailbox information. */ jens@28: @"MX", // = 15, /* Mail routing information. */ jens@28: @"TXT" // = 16, /* One or more text strings (NOT "zero or more..."). */ jens@28: // this isn't a complete list; it just includes the most common ones. jens@28: // For the full list, see the "kDNSServiceType_..." constants in . jens@28: }; jens@28: jens@28: @interface MYBonjourQuery () jens@28: @property (copy) NSData *recordData; jens@28: @end jens@28: jens@28: jens@28: @implementation MYBonjourQuery jens@28: jens@28: jens@28: - (id) initWithBonjourService: (MYBonjourService*)service recordType: (uint16_t)recordType; jens@28: { jens@28: self = [super init]; jens@28: if (self) { jens@28: _bonjourService = service; jens@28: _recordType = recordType; jens@28: } jens@28: return self; jens@28: } jens@28: jens@28: - (void) dealloc jens@28: { jens@28: [_recordData release]; jens@28: [super dealloc]; jens@28: } jens@28: jens@28: jens@28: - (NSString*) description jens@28: { jens@28: NSString *typeName; jens@28: if (_recordType <= 16) jens@28: typeName = kRecordTypeNames[_recordType]; jens@28: else jens@28: typeName = $sprintf(@"%u", _recordType); jens@28: return $sprintf(@"%@[%@ /%@]", self.class, _bonjourService.name, typeName); jens@28: } jens@28: jens@28: jens@28: @synthesize recordData=_recordData; jens@28: jens@28: jens@28: - (void) priv_gotRecordBytes: (const void *)rdata jens@28: length: (uint16_t)rdlen jens@28: type: (uint16_t)rrtype jens@28: ttl: (uint32_t)ttl jens@28: flags: (DNSServiceFlags)flags jens@28: { jens@28: NSData *data = [NSData dataWithBytes: rdata length: rdlen]; jens@28: if (!$equal(data,_recordData)) { jens@28: if (data.length <= 16) jens@28: LogTo(Bonjour,@"%@ = %@", self, data); jens@28: else jens@28: LogTo(Bonjour,@"%@ = %@...", self, [data subdataWithRange: NSMakeRange(0,16)]); jens@28: self.recordData = data; jens@28: } jens@28: [_bonjourService queryDidUpdate: self]; jens@28: } jens@28: jens@28: jens@28: static void queryCallback( DNSServiceRef DNSServiceRef, jens@28: DNSServiceFlags flags, jens@28: uint32_t interfaceIndex, jens@28: DNSServiceErrorType errorCode, jens@28: const char *fullname, jens@28: uint16_t rrtype, jens@28: uint16_t rrclass, jens@28: uint16_t rdlen, jens@28: const void *rdata, jens@28: uint32_t ttl, jens@28: void *context) jens@28: { jens@31: MYBonjourQuery *query = context; jens@28: @try{ jens@28: //LogTo(Bonjour, @"queryCallback for %@ (err=%i)", context,errorCode); jens@31: if (!errorCode) jens@31: [query priv_gotRecordBytes: rdata jens@31: length: rdlen jens@31: type: rrtype jens@31: ttl: ttl jens@31: flags: flags]; jens@28: }catchAndReport(@"MYBonjourResolver query callback"); jens@31: [query gotResponse: errorCode]; jens@28: } jens@28: jens@28: jens@31: - (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr { jens@28: const char *fullName = _bonjourService.fullName.UTF8String; jens@28: if (fullName) jens@31: return DNSServiceQueryRecord(sdRefPtr, jens@31: kDNSServiceFlagsShareConnection, jens@31: _bonjourService.interfaceIndex, jens@31: fullName, jens@31: _recordType, kDNSServiceClass_IN, jens@31: &queryCallback, self); jens@31: else jens@31: return kDNSServiceErr_NoSuchName; jens@28: } jens@28: jens@28: jens@28: @end 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: */