Bonjour/MYBonjourQuery.m
author Jens Alfke <jens@mooseyard.com>
Tue Jul 21 15:06:15 2009 -0700 (2009-07-21)
changeset 62 8713f2d6a4c5
parent 31 1d6924779df7
permissions -rw-r--r--
Added -[MYBonjourRegistration updateTXTRecord]
     1 //
     2 //  MYBonjourQuery.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 "MYBonjourQuery.h"
    10 #import "MYBonjourService.h"
    11 #import "Test.h"
    12 #import "Logging.h"
    13 #import "ExceptionUtils.h"
    14 #import <dns_sd.h>
    15 
    16 
    17 static NSString* kRecordTypeNames[] = {
    18     @"0",
    19     @"A", //         = 1,      /* Host address. */
    20     @"NS", //        = 2,      /* Authoritative server. */
    21     @"MD", //        = 3,      /* Mail destination. */
    22     @"MF", //        = 4,      /* Mail forwarder. */
    23     @"CNAME", //     = 5,      /* Canonical name. */
    24     @"SOA", //       = 6,      /* Start of authority zone. */
    25     @"MB", //        = 7,      /* Mailbox domain name. */
    26     @"MG", //        = 8,      /* Mail group member. */
    27     @"MR", //        = 9,      /* Mail rename name. */
    28     @"NULL", //      = 10,     /* Null resource record. */
    29     @"WKS", //       = 11,     /* Well known service. */
    30     @"PTR", //       = 12,     /* Domain name pointer. */
    31     @"HINFO", //     = 13,     /* Host information. */
    32     @"MINFO", //     = 14,     /* Mailbox information. */
    33     @"MX", //        = 15,     /* Mail routing information. */
    34     @"TXT" //       = 16,     /* One or more text strings (NOT "zero or more..."). */
    35     // this isn't a complete list; it just includes the most common ones.
    36     // For the full list, see the "kDNSServiceType_..." constants in <dns_sd.h>.
    37 };
    38 
    39 @interface MYBonjourQuery ()
    40 @property (copy) NSData *recordData;
    41 @end
    42 
    43 
    44 @implementation MYBonjourQuery
    45 
    46 
    47 - (id) initWithBonjourService: (MYBonjourService*)service recordType: (uint16_t)recordType;
    48 {
    49     self = [super init];
    50     if (self) {
    51         _bonjourService = service;
    52         _recordType = recordType;
    53     }
    54     return self;
    55 }
    56 
    57 - (void) dealloc
    58 {
    59     [_recordData release];
    60     [super dealloc];
    61 }
    62 
    63 
    64 - (NSString*) description
    65 {
    66     NSString *typeName;
    67     if (_recordType <= 16)
    68         typeName = kRecordTypeNames[_recordType];
    69     else
    70         typeName = $sprintf(@"%u", _recordType);
    71     return $sprintf(@"%@[%@ /%@]", self.class, _bonjourService.name, typeName);
    72 }
    73 
    74 
    75 @synthesize recordData=_recordData;
    76 
    77 
    78 - (void) priv_gotRecordBytes: (const void *)rdata
    79                       length: (uint16_t)rdlen
    80                         type: (uint16_t)rrtype
    81                          ttl: (uint32_t)ttl
    82                        flags: (DNSServiceFlags)flags
    83 {
    84     NSData *data = [NSData dataWithBytes: rdata length: rdlen];
    85     if (!$equal(data,_recordData)) {
    86         if (data.length <= 16)
    87             LogTo(Bonjour,@"%@ = %@", self, data);
    88         else
    89             LogTo(Bonjour,@"%@ = %@...", self, [data subdataWithRange: NSMakeRange(0,16)]);
    90         self.recordData = data;
    91     }
    92     [_bonjourService queryDidUpdate: self];
    93 }
    94 
    95 
    96 static void queryCallback( DNSServiceRef                       DNSServiceRef,
    97                            DNSServiceFlags                     flags,
    98                            uint32_t                            interfaceIndex,
    99                            DNSServiceErrorType                 errorCode,
   100                            const char                          *fullname,
   101                            uint16_t                            rrtype,
   102                            uint16_t                            rrclass,
   103                            uint16_t                            rdlen,
   104                            const void                          *rdata,
   105                            uint32_t                            ttl,
   106                            void                                *context)
   107 {
   108     MYBonjourQuery *query = context;
   109     [query retain];
   110     @try{
   111         //LogTo(Bonjour, @"queryCallback for %@ (err=%i)", context,errorCode);
   112         if (!errorCode)
   113             [query priv_gotRecordBytes: rdata
   114                                 length: rdlen
   115                                   type: rrtype
   116                                    ttl: ttl
   117                                  flags: flags];
   118     }catchAndReport(@"MYBonjourResolver query callback");
   119     [query gotResponse: errorCode];
   120     [query release];
   121 }
   122 
   123 
   124 - (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr {
   125     const char *fullName = _bonjourService.fullName.UTF8String;
   126     if (fullName)
   127         return DNSServiceQueryRecord(sdRefPtr,
   128                                      kDNSServiceFlagsShareConnection, 
   129                                      _bonjourService.interfaceIndex, 
   130                                      fullName,
   131                                      _recordType, kDNSServiceClass_IN, 
   132                                      &queryCallback, self);
   133     else
   134         return kDNSServiceErr_NoSuchName;
   135 }
   136 
   137 
   138 @end
   139 
   140 
   141 /*
   142  Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
   143  
   144  Redistribution and use in source and binary forms, with or without modification, are permitted
   145  provided that the following conditions are met:
   146  
   147  * Redistributions of source code must retain the above copyright notice, this list of conditions
   148  and the following disclaimer.
   149  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
   150  and the following disclaimer in the documentation and/or other materials provided with the
   151  distribution.
   152  
   153  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
   154  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
   155  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
   156  BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   157  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
   158   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   159  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
   160  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   161  */