]> git.saurik.com Git - apple/mdnsresponder.git/blob - mDNSWindows/DNSServices/DNSServiceDiscovery.c
mDNSResponder-58.tar.gz
[apple/mdnsresponder.git] / mDNSWindows / DNSServices / DNSServiceDiscovery.c
1 /*
2 * Copyright (c) 2002-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22
23 Change History (most recent first):
24
25 $Log: DNSServiceDiscovery.c,v $
26 Revision 1.2 2003/08/20 07:06:34 bradley
27 Update to APSL 2.0. Updated change history to match other mDNSResponder files.
28
29 Revision 1.1 2003/08/20 06:04:45 bradley
30 Platform-neutral DNSServices-based emulation layer for the Mac OS X DNSServiceDiscovery API.
31
32 */
33
34 #include <stddef.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #if( macintosh || __MACH__ )
39
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43
44 #elif( defined( _MSC_VER ) || defined( __MWERKS__ ) )
45
46 #pragma warning( disable:4054 ) // Disable "type cast : from function pointer to data pointer".
47 #pragma warning( disable:4055 ) // Disable "type cast : from data pointer to function pointer".
48 #pragma warning( disable:4127 ) // Disable "conditional expression is constant" warning for debug macros.
49 #pragma warning( disable:4152 ) // Disable "nonstandard extension, function/data pointer conversion in expression".
50
51 #define WIN32_LEAN_AND_MEAN // Needed to avoid redefinitions by Windows interfaces.
52
53 #include <winsock2.h>
54
55 #endif
56
57 #include "mDNSClientAPI.h"
58 #include "mDNSPlatformFunctions.h"
59 #include "DNSServices.h"
60
61 #include "DNSServiceDiscovery.h"
62
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66
67 #if 0
68 #pragma mark == Constants & Types ==
69 #endif
70
71 //===========================================================================================================================
72 // Constants & Types
73 //===========================================================================================================================
74
75 #define DEBUG_NAME "[DNSServiceDiscovery] "
76
77 typedef enum
78 {
79 kDNSServiceDiscoveryObjectTypeRegistration = 1,
80 kDNSServiceDiscoveryObjectTypeDomainEnumeration = 2,
81 kDNSServiceDiscoveryObjectTypeBrowser = 3,
82 kDNSServiceDiscoveryObjectTypeResolver = 4
83
84 } DNSServiceDiscoveryObjectType;
85
86 typedef struct _dns_service_discovery_t _dns_service_discovery_t;
87 struct _dns_service_discovery_t
88 {
89 DNSServiceDiscoveryObjectType type;
90 void * ref;
91 void * callback;
92 void * context;
93 };
94
95 #if 0
96 #pragma mark == Macros ==
97 #endif
98
99 //===========================================================================================================================
100 // Macros
101 //===========================================================================================================================
102
103 // Emulate Mac OS debugging macros for non-Mac platforms.
104
105 #if( !TARGET_OS_MAC )
106 #define check(assertion)
107 #define check_string( assertion, cstring )
108 #define check_noerr(err)
109 #define check_noerr_string( error, cstring )
110 #define debug_string( cstring )
111 #define require( assertion, label ) do { if( !(assertion) ) goto label; } while(0)
112 #define require_string( assertion, label, string ) require(assertion, label)
113 #define require_quiet( assertion, label ) require( assertion, label )
114 #define require_noerr( error, label ) do { if( (error) != 0 ) goto label; } while(0)
115 #define require_noerr_quiet( assertion, label ) require_noerr( assertion, label )
116 #define require_noerr_action( error, label, action ) do { if( (error) != 0 ) { {action;}; goto label; } } while(0)
117 #define require_noerr_action_quiet( assertion, label, action ) require_noerr_action( assertion, label, action )
118 #define require_action( assertion, label, action ) do { if( !(assertion) ) { {action;}; goto label; } } while(0)
119 #define require_action_quiet( assertion, label, action ) require_action( assertion, label, action )
120 #define require_action_string( assertion, label, action, cstring ) do { if( !(assertion) ) { {action;}; goto label; } } while(0)
121 #endif
122
123 #if 0
124 #pragma mark == Prototypes ==
125 #endif
126
127 //===========================================================================================================================
128 // Prototypes
129 //===========================================================================================================================
130
131 DNS_LOCAL void
132 DNSServiceRegistrationPrivateCallBack(
133 void * inContext,
134 DNSRegistrationRef inRef,
135 DNSStatus inStatusCode,
136 const DNSRegistrationEvent * inEvent );
137
138 DNS_LOCAL void
139 DNSServiceDomainEnumerationPrivateCallBack(
140 void * inContext,
141 DNSBrowserRef inRef,
142 DNSStatus inStatusCode,
143 const DNSBrowserEvent * inEvent );
144
145 DNS_LOCAL void
146 DNSServiceBrowserPrivateCallBack(
147 void * inContext,
148 DNSBrowserRef inRef,
149 DNSStatus inStatusCode,
150 const DNSBrowserEvent * inEvent );
151
152 DNS_LOCAL void
153 DNSServiceResolverPrivateCallBack(
154 void * inContext,
155 DNSResolverRef inRef,
156 DNSStatus inStatusCode,
157 const DNSResolverEvent * inEvent );
158
159 #if 0
160 #pragma mark -
161 #endif
162
163 //===========================================================================================================================
164 // DNSServiceRegistrationCreate
165 //===========================================================================================================================
166
167 dns_service_discovery_ref
168 DNSServiceRegistrationCreate(
169 const char * inName,
170 const char * inType,
171 const char * inDomain,
172 uint16_t inPort,
173 const char * inTextRecord,
174 DNSServiceRegistrationReply inCallBack,
175 void * inContext )
176 {
177 DNSStatus err;
178 dns_service_discovery_ref result;
179 dns_service_discovery_ref obj;
180 void * txt;
181 size_t txtSize;
182 DNSRegistrationRef registration;
183
184 result = NULL;
185 txt = NULL;
186 txtSize = 0;
187
188 // Allocate and initialize the object.
189
190 obj = (dns_service_discovery_ref) malloc( sizeof( *obj ) );
191 require_action( obj, exit, err = kDNSNoMemoryErr );
192
193 obj->type = kDNSServiceDiscoveryObjectTypeRegistration;
194 obj->ref = NULL;
195 obj->callback = inCallBack;
196 obj->context = inContext;
197
198 // Create the underlying registration. Build a \001-escaped text record if needed.
199
200 if( inTextRecord )
201 {
202 err = DNSDynamicTextRecordBuildEscaped( inTextRecord, &txt, &txtSize );
203 require_noerr( err, exit );
204 }
205
206 err = DNSRegistrationCreate( kDNSRegistrationFlagPreFormattedTextRecord, inName, inType, inDomain, inPort, txt,
207 (DNSCount) txtSize, NULL, NULL, DNSServiceRegistrationPrivateCallBack, obj, &registration );
208 require_noerr( err, exit );
209 obj->ref = registration;
210
211 // Success!
212
213 result = obj;
214 obj = NULL;
215
216 exit:
217 if( txt )
218 {
219 DNSDynamicTextRecordRelease( txt );
220 }
221 if( obj )
222 {
223 DNSServiceDiscoveryDeallocate( obj );
224 }
225 return( result );
226 }
227
228 //===========================================================================================================================
229 // DNSServiceRegistrationPrivateCallBack
230 //===========================================================================================================================
231
232 DNS_LOCAL void
233 DNSServiceRegistrationPrivateCallBack(
234 void * inContext,
235 DNSRegistrationRef inRef,
236 DNSStatus inStatusCode,
237 const DNSRegistrationEvent * inEvent )
238 {
239 dns_service_discovery_ref obj;
240 DNSServiceRegistrationReply callback;
241
242 DNS_UNUSED( inRef );
243 DNS_UNUSED( inStatusCode );
244
245 check( inContext );
246 obj = (dns_service_discovery_ref) inContext;
247 check( obj->callback );
248 callback = (DNSServiceRegistrationReply) obj->callback;
249
250 switch( inEvent->type )
251 {
252 case kDNSRegistrationEventTypeRegistered:
253 debugf( DEBUG_NAME "name registered and active\n" );
254
255 if( callback )
256 {
257 callback( kDNSServiceDiscoveryNoError, obj->context );
258 }
259 break;
260
261 case kDNSRegistrationEventTypeNameCollision:
262 debugf( DEBUG_NAME "name in use, please choose another name\n" );
263
264 if( callback )
265 {
266 callback( kDNSServiceDiscoveryNameConflict, obj->context );
267 }
268 break;
269
270 default:
271 break;
272 }
273 }
274
275 //===========================================================================================================================
276 // DNSServiceRegistrationAddRecord
277 //===========================================================================================================================
278
279 DNSRecordReference
280 DNSServiceRegistrationAddRecord(
281 dns_service_discovery_ref inRef,
282 uint16_t inRRType,
283 uint16_t inRDLength,
284 const char * inRData,
285 uint32_t inTTL )
286 {
287 DNS_UNUSED( inRef );
288 DNS_UNUSED( inRRType );
289 DNS_UNUSED( inRDLength );
290 DNS_UNUSED( inRData );
291 DNS_UNUSED( inTTL );
292
293 debugf( DEBUG_NAME "DNSServiceRegistrationAddRecord is currently not supported\n" );
294 return( 0 );
295 }
296
297 //===========================================================================================================================
298 // DNSServiceRegistrationUpdateRecord
299 //===========================================================================================================================
300
301 DNSServiceRegistrationReplyErrorType
302 DNSServiceRegistrationUpdateRecord(
303 dns_service_discovery_ref inRef,
304 DNSRecordReference inRecordRef,
305 uint16_t inRDLength,
306 const char * inRData,
307 uint32_t inTTL )
308 {
309 DNS_UNUSED( inRef );
310 DNS_UNUSED( inRecordRef );
311 DNS_UNUSED( inRDLength );
312 DNS_UNUSED( inRData );
313 DNS_UNUSED( inTTL );
314
315 debugf( DEBUG_NAME "DNSServiceRegistrationUpdateRecord is currently not supported\n" );
316 return( kDNSServiceDiscoveryUnsupportedErr );
317 }
318
319 //===========================================================================================================================
320 // DNSServiceRegistrationRemoveRecord
321 //===========================================================================================================================
322
323 DNSServiceRegistrationReplyErrorType
324 DNSServiceRegistrationRemoveRecord(
325 dns_service_discovery_ref inRef,
326 DNSRecordReference inRecordRef )
327 {
328 DNS_UNUSED( inRef );
329 DNS_UNUSED( inRecordRef );
330
331 debugf( DEBUG_NAME "DNSServiceRegistrationRemoveRecord is currently not supported\n" );
332 return( kDNSServiceDiscoveryUnsupportedErr );
333 }
334
335 //===========================================================================================================================
336 // DNSServiceDomainEnumerationCreate
337 //===========================================================================================================================
338
339 dns_service_discovery_ref
340 DNSServiceDomainEnumerationCreate(
341 int inRegistrationDomains,
342 DNSServiceDomainEnumerationReply inCallBack,
343 void * inContext )
344 {
345 DNSStatus err;
346 dns_service_discovery_ref result;
347 dns_service_discovery_ref obj;
348 DNSBrowserRef browser;
349 DNSBrowserFlags flags;
350
351 result = NULL;
352 browser = NULL;
353
354 // Allocate and initialize the object.
355
356 obj = (dns_service_discovery_ref) malloc( sizeof( *obj ) );
357 require_action( obj, exit, err = kDNSNoMemoryErr );
358
359 obj->type = kDNSServiceDiscoveryObjectTypeDomainEnumeration;
360 obj->ref = NULL;
361 obj->callback = inCallBack;
362 obj->context = inContext;
363
364 // Create the underlying browser and start searching for domains.
365
366 err = DNSBrowserCreate( 0, DNSServiceDomainEnumerationPrivateCallBack, obj, &browser );
367 require_noerr( err, exit );
368 obj->ref = browser;
369
370 if( inRegistrationDomains )
371 {
372 flags = kDNSBrowserFlagRegistrationDomainsOnly;
373 }
374 else
375 {
376 flags = 0;
377 }
378 err = DNSBrowserStartDomainSearch( browser, flags );
379 require_noerr( err, exit );
380
381 // Success!
382
383 result = obj;
384 browser = NULL;
385 obj = NULL;
386
387 exit:
388 if( browser )
389 {
390 DNSBrowserRelease( browser, 0 );
391 }
392 if( obj )
393 {
394 DNSServiceDiscoveryDeallocate( obj );
395 }
396 return( result );
397 }
398
399 //===========================================================================================================================
400 // DNSServiceDomainEnumerationPrivateCallBack
401 //===========================================================================================================================
402
403 DNS_LOCAL void
404 DNSServiceDomainEnumerationPrivateCallBack(
405 void * inContext,
406 DNSBrowserRef inRef,
407 DNSStatus inStatusCode,
408 const DNSBrowserEvent * inEvent )
409 {
410 dns_service_discovery_ref obj;
411 DNSServiceDomainEnumerationReply callback;
412
413 DNS_UNUSED( inRef );
414 DNS_UNUSED( inStatusCode );
415
416 check( inContext );
417 obj = (dns_service_discovery_ref) inContext;
418 check( obj->callback );
419 callback = (DNSServiceDomainEnumerationReply) obj->callback;
420
421 switch( inEvent->type )
422 {
423 case kDNSBrowserEventTypeAddDomain:
424 debugf( DEBUG_NAME "add domain \"%s\"\n", inEvent->data.addDomain.domain );
425
426 if( callback )
427 {
428 callback( DNSServiceDomainEnumerationReplyAddDomain, inEvent->data.addDomain.domain,
429 DNSServiceDiscoverReplyFlagsFinished, obj->context );
430 }
431 break;
432
433 case kDNSBrowserEventTypeAddDefaultDomain:
434 debugf( DEBUG_NAME "add default domain \"%s\"\n", inEvent->data.addDefaultDomain.domain );
435
436 if( callback )
437 {
438 callback( DNSServiceDomainEnumerationReplyAddDomainDefault, inEvent->data.addDefaultDomain.domain,
439 DNSServiceDiscoverReplyFlagsFinished, obj->context );
440 }
441 break;
442
443 case kDNSBrowserEventTypeRemoveDomain:
444 debugf( DEBUG_NAME "add default domain \"%s\"\n", inEvent->data.removeDomain.domain );
445
446 if( callback )
447 {
448 callback( DNSServiceDomainEnumerationReplyRemoveDomain, inEvent->data.removeDomain.domain,
449 DNSServiceDiscoverReplyFlagsFinished, obj->context );
450 }
451 break;
452
453 default:
454 break;
455 }
456 }
457
458 //===========================================================================================================================
459 // DNSServiceBrowserCreate
460 //===========================================================================================================================
461
462 dns_service_discovery_ref
463 DNSServiceBrowserCreate(
464 const char * inType,
465 const char * inDomain,
466 DNSServiceBrowserReply inCallBack,
467 void * inContext )
468 {
469 DNSStatus err;
470 dns_service_discovery_ref result;
471 dns_service_discovery_ref obj;
472 DNSBrowserRef browser;
473
474 result = NULL;
475 browser = NULL;
476
477 // Allocate and initialize the object.
478
479 obj = (dns_service_discovery_ref) malloc( sizeof( *obj ) );
480 require_action( obj, exit, err = kDNSNoMemoryErr );
481
482 obj->type = kDNSServiceDiscoveryObjectTypeBrowser;
483 obj->ref = NULL;
484 obj->callback = inCallBack;
485 obj->context = inContext;
486
487 // Create the underlying browser and start searching for domains.
488
489 err = DNSBrowserCreate( 0, DNSServiceBrowserPrivateCallBack, obj, &browser );
490 require_noerr( err, exit );
491 obj->ref = browser;
492
493 err = DNSBrowserStartServiceSearch( browser, 0, inType, inDomain );
494 require_noerr( err, exit );
495
496 // Success!
497
498 result = obj;
499 browser = NULL;
500 obj = NULL;
501
502 exit:
503 if( browser )
504 {
505 DNSBrowserRelease( browser, 0 );
506 }
507 if( obj )
508 {
509 DNSServiceDiscoveryDeallocate( obj );
510 }
511 return( result );
512 }
513
514 //===========================================================================================================================
515 // DNSServiceBrowserPrivateCallBack
516 //===========================================================================================================================
517
518 DNS_LOCAL void
519 DNSServiceBrowserPrivateCallBack(
520 void * inContext,
521 DNSBrowserRef inRef,
522 DNSStatus inStatusCode,
523 const DNSBrowserEvent * inEvent )
524 {
525 dns_service_discovery_ref obj;
526 DNSServiceBrowserReply callback;
527
528 DNS_UNUSED( inRef );
529 DNS_UNUSED( inStatusCode );
530
531 check( inContext );
532 obj = (dns_service_discovery_ref) inContext;
533 check( obj->callback );
534 callback = (DNSServiceBrowserReply) obj->callback;
535
536 switch( inEvent->type )
537 {
538 case kDNSBrowserEventTypeAddService:
539 debugf( DEBUG_NAME "add service \"%s.%s%s\"\n",
540 inEvent->data.addService.name,
541 inEvent->data.addService.type,
542 inEvent->data.addService.domain );
543
544 if( callback )
545 {
546 callback( DNSServiceBrowserReplyAddInstance,
547 inEvent->data.addService.name,
548 inEvent->data.addService.type,
549 inEvent->data.addService.domain,
550 DNSServiceDiscoverReplyFlagsFinished,
551 obj->context );
552 }
553 break;
554
555 case kDNSBrowserEventTypeRemoveService:
556 debugf( DEBUG_NAME "remove service \"%s.%s%s\"\n",
557 inEvent->data.removeService.name,
558 inEvent->data.removeService.type,
559 inEvent->data.removeService.domain );
560
561 if( callback )
562 {
563 callback( DNSServiceBrowserReplyRemoveInstance,
564 inEvent->data.removeService.name,
565 inEvent->data.removeService.type,
566 inEvent->data.removeService.domain,
567 DNSServiceDiscoverReplyFlagsFinished,
568 obj->context );
569 }
570 break;
571
572 default:
573 break;
574 }
575 }
576
577 //===========================================================================================================================
578 // DNSServiceResolverResolve
579 //===========================================================================================================================
580
581 dns_service_discovery_ref
582 DNSServiceResolverResolve(
583 const char * inName,
584 const char * inType,
585 const char * inDomain,
586 DNSServiceResolverReply inCallBack,
587 void * inContext )
588 {
589 DNSStatus err;
590 dns_service_discovery_ref result;
591 dns_service_discovery_ref obj;
592 DNSResolverRef resolver;
593
594 result = NULL;
595
596 // Allocate and initialize the object.
597
598 obj = (dns_service_discovery_ref) malloc( sizeof( *obj ) );
599 require_action( obj, exit, err = kDNSNoMemoryErr );
600
601 obj->type = kDNSServiceDiscoveryObjectTypeResolver;
602 obj->ref = NULL;
603 obj->callback = inCallBack;
604 obj->context = inContext;
605
606 // Create the underlying resolver and start searching for domains.
607
608 err = DNSResolverCreate( 0, inName, inType, inDomain, DNSServiceResolverPrivateCallBack, obj, NULL, &resolver );
609 require_noerr( err, exit );
610 obj->ref = resolver;
611
612 // Success!
613
614 result = obj;
615 obj = NULL;
616
617 exit:
618 if( obj )
619 {
620 DNSServiceDiscoveryDeallocate( obj );
621 }
622 return( result );
623 }
624
625 //===========================================================================================================================
626 // DNSServiceResolverPrivateCallBack
627 //===========================================================================================================================
628
629 DNS_LOCAL void
630 DNSServiceResolverPrivateCallBack(
631 void * inContext,
632 DNSResolverRef inRef,
633 DNSStatus inStatusCode,
634 const DNSResolverEvent * inEvent )
635 {
636 dns_service_discovery_ref obj;
637 DNSServiceResolverReply callback;
638 struct sockaddr_in interfaceAddr;
639 struct sockaddr_in addr;
640
641 DNS_UNUSED( inRef );
642 DNS_UNUSED( inStatusCode );
643
644 check( inContext );
645 obj = (dns_service_discovery_ref) inContext;
646 check( obj->callback );
647 callback = (DNSServiceResolverReply) obj->callback;
648
649 switch( inEvent->type )
650 {
651 case kDNSResolverEventTypeResolved:
652 debugf( DEBUG_NAME "resolved \"%s.%s%s\"\n",
653 inEvent->data.resolved.name,
654 inEvent->data.resolved.type,
655 inEvent->data.resolved.domain );
656
657 memset( &interfaceAddr, 0, sizeof( interfaceAddr ) );
658 interfaceAddr.sin_family = AF_INET;
659 interfaceAddr.sin_port = 0;
660 interfaceAddr.sin_addr.s_addr = inEvent->data.resolved.interfaceIP.u.ipv4.addr.v32;
661
662 memset( &addr, 0, sizeof( addr ) );
663 addr.sin_family = AF_INET;
664 addr.sin_port = inEvent->data.resolved.address.u.ipv4.port.v16;
665 addr.sin_addr.s_addr = inEvent->data.resolved.address.u.ipv4.addr.v32;
666
667 if( callback )
668 {
669 callback( (struct sockaddr *) &interfaceAddr, (struct sockaddr *) &addr, inEvent->data.resolved.textRecord,
670 DNSServiceDiscoverReplyFlagsFinished, obj->context );
671 }
672 break;
673
674 default:
675 break;
676 }
677 }
678
679 //===========================================================================================================================
680 // DNSServiceDiscoveryMachPort
681 //===========================================================================================================================
682
683 mach_port_t DNSServiceDiscoveryMachPort( dns_service_discovery_ref inRef )
684 {
685 DNS_UNUSED( inRef );
686
687 debugf( DEBUG_NAME "DNSServiceDiscoveryMachPort is not supported\n" );
688 return( 0 );
689 }
690
691 //===========================================================================================================================
692 // DNSServiceDiscoveryDeallocate
693 //===========================================================================================================================
694
695 void DNSServiceDiscoveryDeallocate( dns_service_discovery_ref inRef )
696 {
697 _dns_service_discovery_t * obj;
698 DNSStatus err;
699
700 check( inRef );
701 check( inRef->ref );
702
703 obj = (_dns_service_discovery_t *) inRef;
704 switch( obj->type )
705 {
706 case kDNSServiceDiscoveryObjectTypeRegistration:
707 if( inRef->ref )
708 {
709 err = DNSRegistrationRelease( (DNSRegistrationRef) inRef->ref, 0 );
710 check_noerr( err );
711 }
712 free( inRef );
713 break;
714
715 case kDNSServiceDiscoveryObjectTypeDomainEnumeration:
716 if( inRef->ref )
717 {
718 err = DNSBrowserRelease( (DNSBrowserRef) inRef->ref, 0 );
719 check_noerr( err );
720 }
721 free( inRef );
722 break;
723
724 case kDNSServiceDiscoveryObjectTypeBrowser:
725 if( inRef->ref )
726 {
727 err = DNSBrowserRelease( (DNSBrowserRef) inRef->ref, 0 );
728 check_noerr( err );
729 }
730 free( inRef );
731 break;
732
733 case kDNSServiceDiscoveryObjectTypeResolver:
734 if( inRef->ref )
735 {
736 err = DNSResolverRelease( (DNSResolverRef) inRef->ref, 0 );
737 check_noerr( err );
738 }
739 free( inRef );
740 break;
741
742 default:
743 debugf( DEBUG_NAME "unknown object type (%d)\n", obj->type );
744 break;
745 }
746 }
747
748 //===========================================================================================================================
749 // DNSServiceDiscovery_handleReply
750 //===========================================================================================================================
751
752 void DNSServiceDiscovery_handleReply( void *inReplyMessage )
753 {
754 DNS_UNUSED( inReplyMessage );
755
756 debugf( DEBUG_NAME "DNSServiceDiscovery_handleReply is not supported\n" );
757 }
758
759 #ifdef __cplusplus
760 }
761 #endif