Bonjour/MYBonjourQuery.m
author morrowa@betelgeuse.local
Tue Jun 23 11:44:30 2009 -0700 (2009-06-23)
changeset 51 de59ce19f42e
parent 28 732576fa8a0d
child 61 981f9d604c88
permissions -rw-r--r--
BROKEN COMMIT. Majority of code to handle closing has been added. Listeners do not close correctly.
     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     @try{
   110         //LogTo(Bonjour, @"queryCallback for %@ (err=%i)", context,errorCode);
   111         if (!errorCode)
   112             [query priv_gotRecordBytes: rdata
   113                                 length: rdlen
   114                                   type: rrtype
   115                                    ttl: ttl
   116                                  flags: flags];
   117     }catchAndReport(@"MYBonjourResolver query callback");
   118     [query gotResponse: errorCode];
   119 }
   120 
   121 
   122 - (DNSServiceErrorType) createServiceRef: (DNSServiceRef*)sdRefPtr {
   123     const char *fullName = _bonjourService.fullName.UTF8String;
   124     if (fullName)
   125         return DNSServiceQueryRecord(sdRefPtr,
   126                                      kDNSServiceFlagsShareConnection, 
   127                                      _bonjourService.interfaceIndex, 
   128                                      fullName,
   129                                      _recordType, kDNSServiceClass_IN, 
   130                                      &queryCallback, self);
   131     else
   132         return kDNSServiceErr_NoSuchName;
   133 }
   134 
   135 
   136 @end
   137 
   138 
   139 /*
   140  Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
   141  
   142  Redistribution and use in source and binary forms, with or without modification, are permitted
   143  provided that the following conditions are met:
   144  
   145  * Redistributions of source code must retain the above copyright notice, this list of conditions
   146  and the following disclaimer.
   147  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
   148  and the following disclaimer in the documentation and/or other materials provided with the
   149  distribution.
   150  
   151  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
   152  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
   153  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
   154  BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   155  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
   156   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   157  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
   158  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   159  */