2 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 Change History (most recent first):
28 Revision 1.3 2004/04/15 01:00:05 bradley
29 Removed support for automatically querying for A/AAAA records when resolving names. Platforms
30 without .local name resolving support will need to manually query for A/AAAA records as needed.
32 Revision 1.2 2004/04/09 21:03:14 bradley
33 Changed port numbers to use network byte order for consistency with other platforms.
35 Revision 1.1 2004/01/30 02:35:13 bradley
36 Rendezvous Message Exchange implementation for DNS-SD IPC on Windows.
44 #include "CommonServices.h"
45 #include "DebugServices.h"
48 #include "RMxCommon.h"
50 #include "RMxClient.h"
57 #pragma mark == Constants ==
60 //===========================================================================================================================
62 //===========================================================================================================================
64 #define DEBUG_NAME "[RMxClient] "
67 #pragma mark == Structures ==
70 //===========================================================================================================================
72 //===========================================================================================================================
74 typedef void ( *DNSServiceRefReleaseCallBack
)( DNSServiceRef inRef
);
78 typedef struct _DNSServiceRef_t _DNSServiceRef_t
;
79 struct _DNSServiceRef_t
81 RMxSessionRef session
;
87 struct // EnumerateDomains
89 DNSServiceDomainEnumReply callback
;
95 DNSServiceRegisterReply callback
;
102 DNSServiceBrowseReply callback
;
108 DNSServiceFlags flags
;
109 DNSServiceResolveReply callback
;
113 struct // CreateConnection
115 DNSServiceRegisterRecordReply callback
;
120 struct // QueryRecord
122 DNSServiceQueryRecordReply callback
;
131 typedef struct _DNSRecordRef_t _DNSRecordRef_t
;
132 struct _DNSRecordRef_t
136 DNSServiceRegisterRecordReply callback
;
141 #pragma mark == Prototypes ==
144 //===========================================================================================================================
146 //===========================================================================================================================
150 DEBUG_LOCAL
void RMxClientMessageCallBack( RMxMessage
*inMessage
);
154 DEBUG_LOCAL DNSServiceErrorType
155 DNSServiceCopyPropertyDecodeData_client(
156 DNSPropertyCode inCode
,
159 DNSPropertyData
* outData
);
161 // Domain Enumeration
163 DEBUG_LOCAL
void DNSServiceEnumerateDomainsReply_client( RMxMessage
*inMessage
);
167 DEBUG_LOCAL
void DNSServiceBrowseReply_client( RMxMessage
*inMessage
);
169 DEBUG_LOCAL
void DNSServiceResolveReply_client( RMxMessage
*inMessage
);
171 // Service Registration
173 DEBUG_LOCAL
void DNSServiceRegisterReply_client( RMxMessage
*inMessage
);
177 DEBUG_LOCAL DNSRecordRef
DNSServiceConnectionRecordRemove_client( DNSServiceRef inRef
, DNSRecordRef inRecordRef
);
178 DEBUG_LOCAL
void DNSServiceRegisterRecordReply_client( RMxMessage
*inMessage
);
179 DEBUG_LOCAL
void DNSServiceQueryRecordReply_client( RMxMessage
*inMessage
);
183 #pragma mark == RMx ==
186 //===========================================================================================================================
187 // RMxClientInitialize
188 //===========================================================================================================================
190 OSStatus
RMxClientInitialize( void )
194 // Initialize the lower-level layer and indicate it is running.
196 err
= RMxInitialize();
197 require_noerr( err
, exit
);
199 gRMxState
= kRMxStateRun
;
209 //===========================================================================================================================
211 //===========================================================================================================================
213 void RMxClientFinalize( void )
218 //===========================================================================================================================
219 // RMxClientMessageCallBack
220 //===========================================================================================================================
222 DEBUG_LOCAL
void RMxClientMessageCallBack( RMxMessage
*inMessage
)
226 switch( inMessage
->opcode
)
228 case kRMxOpCodeInvalid
:
229 // The session is closing. We don't delete the DNS-SD object here because the client deletes DNS-SD objects.
232 case kRMxOpCodeEnumerateDomains
:
233 DNSServiceEnumerateDomainsReply_client( inMessage
);
236 case kRMxOpCodeRegister
:
237 DNSServiceRegisterReply_client( inMessage
);
240 case kRMxOpCodeBrowse
:
241 DNSServiceBrowseReply_client( inMessage
);
244 case kRMxOpCodeResolve
:
245 DNSServiceResolveReply_client( inMessage
);
248 case kRMxOpCodeRegisterRecord
:
249 DNSServiceRegisterRecordReply_client( inMessage
);
252 case kRMxOpCodeQueryRecord
:
253 DNSServiceQueryRecordReply_client( inMessage
);
257 dlog( kDebugLevelWarning
, DEBUG_NAME
"message with unknown opcode received (%d)\n", inMessage
->opcode
);
264 #pragma mark == DNS-SD General ==
267 //===========================================================================================================================
268 // DNSServiceRefDeallocate_client
269 //===========================================================================================================================
271 void DNSServiceRefDeallocate_client( DNSServiceRef inRef
)
275 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"Deallocate ref=%#p\n", inRef
);
276 require_action( inRef
, exit
, err
= kDNSServiceErr_BadReference
);
278 // Close the session (if not already closed).
282 inRef
->session
->callback
= NULL
;
283 inRef
->session
->message
.context
= NULL
;
285 err
= RMxSessionClose( inRef
->session
, kEndingErr
);
289 // Release any outstanding individual records.
291 while( inRef
->records
)
295 record
= inRef
->records
;
296 inRef
->records
= record
->next
;
301 // Release the object itself.
309 //===========================================================================================================================
310 // DNSServiceCheckVersion_client
311 //===========================================================================================================================
313 DNSServiceErrorType
DNSServiceCheckVersion_client( const char *inServer
)
315 DNSServiceErrorType err
;
316 RMxSessionRef session
;
318 uint32_t serverCurrentVersion
;
319 uint32_t serverOldestClientVersion
;
320 uint32_t serverOldestServerVersion
;
323 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"CheckVersion\n" );
325 // Open a session to the server and send the request. Specify no thread since we are going to manually read the message.
327 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoThread
, kInvalidSocketRef
, NULL
, NULL
, &session
,
328 kRMxOpCodeCheckVersion
, "www", kRMxCurrentVersion
, kRMxOldestClientVersion
, kRMxOldestServerVersion
);
329 require_noerr( err
, exit
);
331 // Receive the respons, parse it, and check the versions.
333 err
= RMxSessionRecvMessage( session
, kRMxClientTimeout
);
334 require_noerr( err
, exit
);
335 check( session
->message
.recvData
|| ( session
->message
.recvSize
== 0 ) );
337 err
= RMxUnpack( session
->message
.recvData
, session
->message
.recvSize
, "wwww",
338 &errorCode
, &serverCurrentVersion
, &serverOldestClientVersion
, &serverOldestServerVersion
);
339 require_noerr( err
, exit
);
341 err
= RMxCheckVersion( kRMxCurrentVersion
, kRMxOldestClientVersion
, kRMxOldestServerVersion
,
342 serverCurrentVersion
, serverOldestClientVersion
, serverOldestServerVersion
);
343 check( err
== errorCode
);
344 if( ( err
== kNoErr
) && ( errorCode
!= kNoErr
) )
346 dlog( kDebugLevelWarning
, DEBUG_NAME
"client/server disagree on versions\n" );
353 RMxSessionClose( session
, kEndingErr
);
360 #pragma mark == DNS-SD Properties ==
363 //===========================================================================================================================
364 // DNSServiceCopyProperty_client
365 //===========================================================================================================================
367 DNSServiceErrorType
DNSServiceCopyProperty_client( const char *inServer
, DNSPropertyCode inCode
, DNSPropertyData
*outData
)
369 DNSServiceErrorType err
;
370 RMxSessionRef session
;
372 DNSPropertyCode code
;
377 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"CopyProperty server=%s, code='%C'\n", inServer
? inServer
: "<local>", inCode
);
378 require_action( outData
, exit
, err
= kDNSServiceErr_BadParam
);
380 // Open a session to the server and send the request. Specify no thread since we are going to manually read the message.
382 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoThread
, kInvalidSocketRef
, NULL
, NULL
, &session
,
383 kRMxOpCodeCopyProperty
, "w", inCode
);
384 require_noerr( err
, exit
);
386 // Receive the response, parse it, and check the versions.
388 err
= RMxSessionRecvMessage( session
, kRMxClientTimeout
);
389 require_noerr( err
, exit
);
390 check( session
->message
.recvData
|| ( session
->message
.recvSize
== 0 ) );
392 err
= RMxUnpack( session
->message
.recvData
, session
->message
.recvSize
, "wwn", &errorCode
, &code
, &data
, &size
);
393 require_noerr( err
, exit
);
395 require_noerr_quiet( err
, exit
);
397 // Decode the data and fill in the results.
399 err
= DNSServiceCopyPropertyDecodeData_client( code
, data
, size
, outData
);
400 require_noerr( err
, exit
);
405 RMxSessionClose( session
, kEndingErr
);
410 //===========================================================================================================================
411 // DNSServiceCopyProperty_client
412 //===========================================================================================================================
414 DEBUG_LOCAL DNSServiceErrorType
415 DNSServiceCopyPropertyDecodeData_client(
416 DNSPropertyCode inCode
,
419 DNSPropertyData
* outData
)
427 case kDNSPropertyCodeVersion
:
428 outData
->u
.version
.clientCurrentVersion
= kRMxCurrentVersion
;
429 outData
->u
.version
.clientOldestServerVersion
= kRMxOldestServerVersion
;
431 err
= RMxUnpack( inData
, inSize
, "www",
432 &outData
->u
.version
.serverCurrentVersion
, &outData
->u
.version
.serverOldestClientVersion
, NULL
);
433 require_noerr( err
, exit
);
437 dlog( kDebugLevelError
, DEBUG_NAME
"CopyPropertyDecodeData unknown property code (%C)\n", inCode
);
438 err
= kDNSServiceErr_Unsupported
;
441 err
= kDNSServiceErr_NoError
;
447 //===========================================================================================================================
448 // DNSServiceReleaseProperty_client
449 //===========================================================================================================================
451 DNSServiceErrorType
DNSServiceReleaseProperty_client( DNSPropertyData
*inData
)
455 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"ReleaseProperty\n" );
456 require_action( inData
, exit
, err
= kDNSServiceErr_BadParam
);
458 switch( inData
->code
)
460 case kDNSPropertyCodeVersion
:
461 // Data is embedded directly in the structure so there is nothing to release.
465 dlog( kDebugLevelError
, DEBUG_NAME
"ReleaseProperty unknown property code (%C)\n", inData
->code
);
466 err
= kDNSServiceErr_Unsupported
;
469 err
= kDNSServiceErr_NoError
;
477 #pragma mark == DNS-SD Domain Enumeration ==
480 //===========================================================================================================================
481 // DNSServiceEnumerateDomains_client
482 //===========================================================================================================================
485 DNSServiceEnumerateDomains_client(
486 DNSServiceRef
* outRef
,
487 const char * inServer
,
488 const DNSServiceFlags inFlags
,
489 const uint32_t inInterfaceIndex
,
490 const DNSServiceDomainEnumReply inCallBack
,
493 DNSServiceErrorType err
;
497 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"EnumerateDomains flags=0x%08X, ifi=%d, server=%s\n",
498 inFlags
, inInterfaceIndex
, inServer
? inServer
: "<local>" );
499 require_action( outRef
, exit
, err
= kDNSServiceErr_BadParam
);
500 require_action( ( inFlags
== kDNSServiceFlagsBrowseDomains
) ||
501 ( inFlags
== kDNSServiceFlagsRegistrationDomains
),
502 exit
, err
= kDNSServiceErr_BadFlags
);
503 require_action( inCallBack
, exit
, err
= kDNSServiceErr_BadParam
);
505 obj
= (DNSServiceRef
) calloc( 1, sizeof( *obj
) );
506 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
508 obj
->context
= inContext
;
509 obj
->u
.domain
.callback
= inCallBack
;
511 // Open a session to the server and send the request.
513 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoClose
, kInvalidSocketRef
, RMxClientMessageCallBack
, obj
,
514 &obj
->session
, kRMxOpCodeEnumerateDomains
, "ww", inFlags
, inInterfaceIndex
);
515 require_noerr( err
, exit
);
525 DNSServiceRefDeallocate_client( obj
);
530 //===========================================================================================================================
531 // DNSServiceEnumerateDomainsReply_client
532 //===========================================================================================================================
534 DEBUG_LOCAL
void DNSServiceEnumerateDomainsReply_client( RMxMessage
*inMessage
)
538 DNSServiceFlags flags
;
539 uint32_t interfaceIndex
;
540 DNSServiceErrorType errorCode
;
544 obj
= (DNSServiceRef
) inMessage
->context
;
547 err
= inMessage
->status
;
550 err
= RMxUnpack( inMessage
->recvData
, inMessage
->recvSize
, "wwws", &flags
, &interfaceIndex
, &errorCode
, &domain
, NULL
);
554 dlog( kDebugLevelTrace
, DEBUG_NAME
"EnumerateDomains reply flags=0x%08X, ifi=%d, err=%d, domain=\"%s\"\n",
555 flags
, interfaceIndex
, errorCode
, domain
);
557 obj
->u
.domain
.callback( obj
, flags
, interfaceIndex
, errorCode
, domain
, obj
->context
);
562 obj
->u
.domain
.callback( obj
, 0, 0, err
, "", obj
->context
);
568 #pragma mark == DNS-SD Service Registration ==
571 //===========================================================================================================================
572 // DNSServiceRegister_direct
573 //===========================================================================================================================
576 DNSServiceRegister_client(
577 DNSServiceRef
* outRef
,
578 const char * inServer
,
579 DNSServiceFlags inFlags
,
580 uint32_t inInterfaceIndex
,
583 const char * inDomain
,
588 DNSServiceRegisterReply inCallBack
,
591 DNSServiceErrorType err
;
595 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
596 "Resolve flags=0x%08X, ifi=%d, name=\"%s\", type=\"%s\", domain=\"%s\", host=\"%s\", port=%d, txtSize=%d\n",
597 inFlags
, inInterfaceIndex
, inName
? inName
: "<default>", inType
, inDomain
? inDomain
: "<default>", inHost
,
598 ntohs( inPort
), inTXTSize
);
599 require_action( outRef
, exit
, err
= kDNSServiceErr_BadReference
);
600 require_action( ( inFlags
== 0 ) || ( inFlags
== kDNSServiceFlagsNoAutoRename
), exit
, err
= kDNSServiceErr_BadFlags
);
601 require_action( inType
, exit
, err
= kDNSServiceErr_BadParam
);
602 require_action( inTXT
|| ( inTXTSize
== 0 ), exit
, err
= kDNSServiceErr_BadParam
);
603 require_action( inCallBack
, exit
, err
= kDNSServiceErr_BadParam
);
605 obj
= (DNSServiceRef
) calloc( 1, sizeof( *obj
) );
606 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
608 obj
->context
= inContext
;
609 obj
->u
.reg
.callback
= inCallBack
;
611 // Open a session to the server and send the request.
613 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoClose
, kInvalidSocketRef
, RMxClientMessageCallBack
, obj
,
614 &obj
->session
, kRMxOpCodeRegister
, "wwsssshn", inFlags
, inInterfaceIndex
, inName
? inName
: "", inType
,
615 inDomain
? inDomain
: "", inHost
, inPort
, inTXTSize
, inTXT
);
616 require_noerr( err
, exit
);
626 DNSServiceRefDeallocate_client( obj
);
631 //===========================================================================================================================
632 // DNSServiceRegisterReply_client
633 //===========================================================================================================================
635 DEBUG_LOCAL
void DNSServiceRegisterReply_client( RMxMessage
*inMessage
)
639 DNSServiceFlags flags
;
640 DNSServiceErrorType errorCode
;
646 obj
= (DNSServiceRef
) inMessage
->context
;
649 err
= inMessage
->status
;
652 err
= RMxUnpack( inMessage
->recvData
, inMessage
->recvSize
, "wwsss",
653 &flags
, &errorCode
, &name
, NULL
, &type
, NULL
, &domain
, NULL
);
657 dlog( kDebugLevelTrace
, DEBUG_NAME
"Register reply flags=0x%08X, err=%d, name=\"%s\", type=\"%s\", domain=\"%s\"\n",
658 flags
, errorCode
, name
, type
, domain
);
660 obj
->u
.reg
.callback( obj
, flags
, errorCode
, name
, type
, domain
, obj
->context
);
665 obj
->u
.reg
.callback( obj
, 0, err
, "", "", "", obj
->context
);
669 //===========================================================================================================================
670 // DNSServiceAddRecord_client
671 //===========================================================================================================================
674 DNSServiceAddRecord_client(
676 DNSRecordRef
* outRecordRef
,
677 DNSServiceFlags inFlags
,
679 uint16_t inRDataSize
,
680 const void * inRData
,
683 DNSServiceErrorType err
;
688 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"AddRecord flags=0x%08X, rrType=%d, rrDataSize=%d, ttl=%d\n",
689 inFlags
, inRRType
, inRDataSize
, inTTL
);
690 require_action( inRef
, exit
, err
= kDNSServiceErr_BadReference
);
691 require_action( inRef
->session
, exit
, err
= kDNSServiceErr_NotInitialized
);
692 require_action( outRecordRef
, exit
, err
= kDNSServiceErr_BadParam
);
693 require_action( inFlags
== 0, exit
, err
= kDNSServiceErr_BadFlags
);
694 require_action( inRData
&& ( inRDataSize
> 0 ), exit
, err
= kDNSServiceErr_BadParam
);
696 // Allocate and initialize the object.
698 obj
= (DNSRecordRef
) calloc( 1, sizeof( *obj
) );
699 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
701 // Send the message. Use an ID that should be unique for the session and avoid the reserved ID.
703 obj
->id
= ++inRef
->u
.reg
.lastID
;
704 if( obj
->id
== kDNSRecordIndexDefaultTXT
)
706 obj
->id
= ++inRef
->u
.reg
.lastID
;
709 err
= RMxSessionSendMessage( inRef
->session
, kRMxOpCodeAddRecord
, kNoErr
, "wwhnw",
710 obj
->id
, inFlags
, inRRType
, inRDataSize
, inRData
, inTTL
);
711 require_noerr( err
, exit
);
727 //===========================================================================================================================
728 // DNSServiceUpdateRecord_client
729 //===========================================================================================================================
732 DNSServiceUpdateRecord_client(
734 DNSRecordRef inRecordRef
,
735 DNSServiceFlags inFlags
,
736 uint16_t inRDataSize
,
737 const void * inRData
,
740 DNSServiceErrorType err
;
743 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"UpdateRecord flags=0x%08X, rrDataSize=%d, ttl=%d\n", inFlags
, inRDataSize
, inTTL
);
744 require_action( inRef
, exit
, err
= kDNSServiceErr_BadReference
);
745 require_action( inRef
->session
, exit
, err
= kDNSServiceErr_NotInitialized
);
746 require_action( inFlags
== 0, exit
, err
= kDNSServiceErr_BadFlags
);
747 require_action( inRData
&& ( inRDataSize
> 0 ), exit
, err
= kDNSServiceErr_BadParam
);
749 err
= RMxSessionSendMessage( inRef
->session
, kRMxOpCodeUpdateRecord
, kNoErr
, "wwnw",
750 inRecordRef
? inRecordRef
->id
: kDNSRecordIndexDefaultTXT
, inFlags
, inRDataSize
, inRData
, inTTL
);
751 require_noerr( err
, exit
);
758 //===========================================================================================================================
759 // DNSServiceRemoveRecord_client
760 //===========================================================================================================================
762 DNSServiceErrorType
DNSServiceRemoveRecord_client( DNSServiceRef inRef
, DNSRecordRef inRecordRef
, DNSServiceFlags inFlags
)
764 DNSServiceErrorType err
;
767 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"RemoveRecord flags=0x%08X\n", inFlags
);
768 require_action( inRef
, exit
, err
= kDNSServiceErr_BadReference
);
769 require_action( inRef
->session
, exit
, err
= kDNSServiceErr_NotInitialized
);
770 require_action( inRecordRef
, exit
, err
= kDNSServiceErr_BadReference
);
771 require_action( inFlags
== 0, exit
, err
= kDNSServiceErr_BadFlags
);
773 err
= RMxSessionSendMessage( inRef
->session
, kRMxOpCodeRemoveRecord
, kNoErr
, "ww", inRecordRef
->id
, inFlags
);
774 DNSServiceConnectionRecordRemove_client( inRef
, inRecordRef
);
776 require_noerr( err
, exit
);
785 #pragma mark == DNS-SD Service Discovery ==
788 //===========================================================================================================================
789 // DNSServiceBrowse_direct
790 //===========================================================================================================================
793 DNSServiceBrowse_client(
794 DNSServiceRef
* outRef
,
795 const char * inServer
,
796 DNSServiceFlags inFlags
,
797 uint32_t inInterfaceIndex
,
799 const char * inDomain
,
800 DNSServiceBrowseReply inCallBack
,
803 DNSServiceErrorType err
;
807 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"Browse flags=0x%08X, ifi=%d, type=\"%s\", domain=\"%s\"\n",
808 inFlags
, inInterfaceIndex
, inType
, inDomain
? inDomain
: "<default>" );
809 require_action( outRef
, exit
, err
= kDNSServiceErr_BadReference
);
810 require_action( inFlags
== 0, exit
, err
= kDNSServiceErr_BadFlags
);
811 require_action( inType
, exit
, err
= kDNSServiceErr_BadParam
);
812 require_action( inCallBack
, exit
, err
= kDNSServiceErr_BadParam
);
814 obj
= (DNSServiceRef
) calloc( 1, sizeof( *obj
) );
815 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
817 obj
->context
= inContext
;
818 obj
->u
.browse
.callback
= inCallBack
;
820 // Open a session to the server and send the request.
822 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoClose
, kInvalidSocketRef
, RMxClientMessageCallBack
, obj
,
823 &obj
->session
, kRMxOpCodeBrowse
, "wwss", inFlags
, inInterfaceIndex
, inType
, inDomain
? inDomain
: "" );
824 require_noerr( err
, exit
);
834 DNSServiceRefDeallocate_client( obj
);
839 //===========================================================================================================================
840 // DNSServiceBrowseReply_client
841 //===========================================================================================================================
843 DEBUG_LOCAL
void DNSServiceBrowseReply_client( RMxMessage
*inMessage
)
847 DNSServiceFlags flags
;
848 uint32_t interfaceIndex
;
849 DNSServiceErrorType errorCode
;
855 obj
= (DNSServiceRef
) inMessage
->context
;
858 err
= inMessage
->status
;
861 err
= RMxUnpack( inMessage
->recvData
, inMessage
->recvSize
, "wwwsss",
862 &flags
, &interfaceIndex
, &errorCode
, &name
, NULL
, &type
, NULL
, &domain
, NULL
);
866 dlog( kDebugLevelTrace
, DEBUG_NAME
867 "Browse reply flags=0x%08X, ifi=%d, err=%d, name=\"%s\", type=\"%s\", domain=\"%s\"\n",
868 flags
, interfaceIndex
, errorCode
, name
, type
, domain
);
870 obj
->u
.browse
.callback( obj
, flags
, interfaceIndex
, errorCode
, name
, type
, domain
, obj
->context
);
875 obj
->u
.browse
.callback( obj
, 0, 0, err
, "", "", "", obj
->context
);
883 //===========================================================================================================================
884 // DNSServiceResolve_direct
885 //===========================================================================================================================
888 DNSServiceResolve_client(
889 DNSServiceRef
* outRef
,
890 const char * inServer
,
891 DNSServiceFlags inFlags
,
892 uint32_t inInterfaceIndex
,
895 const char * inDomain
,
896 DNSServiceResolveReply inCallBack
,
899 DNSServiceErrorType err
;
903 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"Resolve flags=0x%08X, ifi=%d, name=\"%s\", type=\"%s\", domain=\"%s\"\n",
904 inFlags
, inInterfaceIndex
, inName
, inType
, inDomain
? inDomain
: "<default>" );
905 require_action( outRef
, exit
, err
= kDNSServiceErr_BadReference
);
906 require_action( inFlags
== 0, exit
, err
= kDNSServiceErr_BadFlags
);
907 require_action( inName
, exit
, err
= kDNSServiceErr_BadParam
);
908 require_action( inType
, exit
, err
= kDNSServiceErr_BadParam
);
909 require_action( inCallBack
, exit
, err
= kDNSServiceErr_BadParam
);
911 obj
= (DNSServiceRef
) calloc( 1, sizeof( *obj
) );
912 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
914 obj
->context
= inContext
;
915 obj
->u
.resolve
.flags
= inFlags
;
916 obj
->u
.resolve
.callback
= inCallBack
;
918 // Open a session to the server and send the request.
920 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoClose
, kInvalidSocketRef
, RMxClientMessageCallBack
, obj
,
921 &obj
->session
, kRMxOpCodeResolve
, "wwsss", inFlags
, inInterfaceIndex
, inName
, inType
, inDomain
? inDomain
: "" );
922 require_noerr( err
, exit
);
932 DNSServiceRefDeallocate_client( obj
);
937 //===========================================================================================================================
938 // DNSServiceResolveReply_client
939 //===========================================================================================================================
941 DEBUG_LOCAL
void DNSServiceResolveReply_client( RMxMessage
*inMessage
)
945 DNSServiceFlags flags
;
946 uint32_t interfaceIndex
;
947 DNSServiceErrorType errorCode
;
955 obj
= (DNSServiceRef
) inMessage
->context
;
958 err
= inMessage
->status
;
961 err
= RMxUnpack( inMessage
->recvData
, inMessage
->recvSize
, "wwwsshn",
962 &flags
, &interfaceIndex
, &errorCode
, &name
, NULL
, &host
, NULL
, &port
, &txt
, &txtSize
);
966 dlog( kDebugLevelTrace
, DEBUG_NAME
967 "Resolve reply flags=0x%08X, ifi=%d, err=%d, name=\"%s\", host=\"%s\", port=%d, txtSize=%d\n",
968 flags
, interfaceIndex
, errorCode
, name
, host
, ntohs( port
), (int) txtSize
);
970 obj
->u
.resolve
.callback( obj
, flags
, interfaceIndex
, errorCode
, name
, host
, port
, (uint16_t) txtSize
, txt
,
976 obj
->u
.resolve
.callback( obj
, 0, 0, err
, "", "", 0, 0, NULL
, obj
->context
);
982 #pragma mark == DNS-SD Special Purpose ==
985 //===========================================================================================================================
986 // DNSServiceCreateConnection_client
987 //===========================================================================================================================
989 DNSServiceErrorType
DNSServiceCreateConnection_client( DNSServiceRef
*outRef
, const char *inServer
)
991 DNSServiceErrorType err
;
995 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"CreateConnection (server=\"%s\")\n", inServer
? inServer
: "<local>" );
996 require_action( outRef
, exit
, err
= kDNSServiceErr_BadReference
);
998 obj
= (DNSServiceRef
) calloc( 1, sizeof( *obj
) );
999 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
1001 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoClose
, kInvalidSocketRef
, RMxClientMessageCallBack
, obj
,
1002 &obj
->session
, kRMxOpCodeCreateConnection
, "" );
1003 require_noerr( err
, exit
);
1011 DNSServiceRefDeallocate_client( obj
);
1016 //===========================================================================================================================
1017 // DNSServiceConnectionRecordRemove_client
1019 // Warning: Assumes the RMx lock is held (or is not needed due to a single thread having exclusive access).
1020 //===========================================================================================================================
1022 DEBUG_LOCAL DNSRecordRef
DNSServiceConnectionRecordRemove_client( DNSServiceRef inRef
, DNSRecordRef inRecordRef
)
1026 for( p
= &inRef
->records
; *p
; p
= &( *p
)->next
)
1028 if( *p
== inRecordRef
)
1036 *p
= inRecordRef
->next
;
1038 return( inRecordRef
);
1041 //===========================================================================================================================
1042 // DNSServiceRegisterRecord_client
1043 //===========================================================================================================================
1046 DNSServiceRegisterRecord_client(
1047 DNSServiceRef inRef
,
1048 DNSRecordRef
* outRecordRef
,
1049 DNSServiceFlags inFlags
,
1050 uint32_t inInterfaceIndex
,
1051 const char * inName
,
1054 uint16_t inRDataSize
,
1055 const void * inRData
,
1057 DNSServiceRegisterRecordReply inCallBack
,
1060 DNSServiceErrorType err
;
1063 DEBUG_UNUSED( inContext
);
1067 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
1068 "RegisterRecord flags=0x%08X, ifi=%d, name=\"%s\" rrType=0x%04X, rrClass=0x%04X, rDataSize=%d, ttl=%d\n",
1069 inFlags
, inInterfaceIndex
, inName
, inRRType
, inRRClass
, inRDataSize
, inTTL
);
1070 require_action( inRef
, exit
, err
= kDNSServiceErr_BadReference
);
1071 require_action( inRef
->session
, exit
, err
= kDNSServiceErr_NotInitialized
);
1072 require_action( outRecordRef
, exit
, err
= kDNSServiceErr_BadParam
);
1073 require_action( ( inFlags
== kDNSServiceFlagsShared
) || ( inFlags
== kDNSServiceFlagsUnique
),
1074 exit
, err
= kDNSServiceErr_BadFlags
);
1075 require_action( inName
, exit
, err
= kDNSServiceErr_BadParam
);
1076 require_action( inRData
&& ( inRDataSize
> 0 ), exit
, err
= kDNSServiceErr_BadParam
);
1077 require_action( inCallBack
, exit
, err
= kDNSServiceErr_BadFlags
);
1079 // Allocate and initialize the object.
1081 obj
= (DNSRecordRef
) calloc( 1, sizeof( *obj
) );
1082 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
1084 obj
->callback
= inCallBack
;
1085 obj
->context
= inContext
;
1087 // Set up a unique ID for the session, avoiding the reserved ID 0, add the record, then send the message.
1089 obj
->id
= ++inRef
->u
.connection
.lastID
;
1090 if( obj
->id
== kDNSRecordIndexDefaultTXT
)
1092 obj
->id
= ++inRef
->u
.connection
.lastID
;
1094 obj
->next
= inRef
->records
;
1095 inRef
->records
= obj
;
1097 err
= RMxSessionSendMessage( inRef
->session
, kRMxOpCodeRegisterRecord
, kNoErr
, "wwwshhnw",
1098 obj
->id
, inFlags
, inInterfaceIndex
, inName
, inRRType
, inRRClass
, inRDataSize
, inRData
, inTTL
);
1099 require_noerr( err
, exit
);
1103 *outRecordRef
= obj
;
1109 DNSServiceConnectionRecordRemove_client( inRef
, obj
);
1116 //===========================================================================================================================
1117 // DNSServiceRegisterRecordReply_client
1118 //===========================================================================================================================
1120 DEBUG_LOCAL
void DNSServiceRegisterRecordReply_client( RMxMessage
*inMessage
)
1124 DNSServiceFlags flags
;
1125 DNSServiceErrorType errorCode
;
1127 DNSRecordRef record
;
1130 obj
= (DNSServiceRef
) inMessage
->context
;
1134 err
= inMessage
->status
;
1137 err
= RMxUnpack( inMessage
->recvData
, inMessage
->recvSize
, "www", &flags
, &errorCode
, &id
);
1142 for( record
= obj
->records
; record
; record
= record
->next
)
1144 if( record
->id
== id
)
1152 dlog( kDebugLevelError
, DEBUG_NAME
"RegisterRecord reply with unknown record ID (%d)\n", id
);
1157 dlog( kDebugLevelTrace
, DEBUG_NAME
"RegisterRecord reply id=%d, flags=0x%08X, err=%d\n", id
, flags
, errorCode
);
1159 record
->callback( obj
, record
, flags
, errorCode
, record
->context
);
1168 record
->callback( obj
, NULL
, 0, err
, NULL
);
1173 //===========================================================================================================================
1174 // DNSServiceQueryRecord_client
1175 //===========================================================================================================================
1178 DNSServiceQueryRecord_client(
1179 DNSServiceRef
* outRef
,
1180 const char * inServer
,
1181 DNSServiceFlags inFlags
,
1182 uint32_t inInterfaceIndex
,
1183 const char * inName
,
1186 DNSServiceQueryRecordReply inCallBack
,
1189 DNSServiceErrorType err
;
1193 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"QueryRecord flags=0x%08X, ifi=%d, name=\"%s\", rrType=%d, rrClass=%d\n",
1194 inFlags
, inInterfaceIndex
, inName
, inRRType
, inRRClass
);
1195 require_action( outRef
, exit
, err
= kDNSServiceErr_BadReference
);
1196 require_action( inFlags
== 0, exit
, err
= kDNSServiceErr_BadFlags
);
1197 require_action( inName
, exit
, err
= kDNSServiceErr_BadParam
);
1198 require_action( inCallBack
, exit
, err
= kDNSServiceErr_BadFlags
);
1200 obj
= (DNSServiceRef
) calloc( 1, sizeof( *obj
) );
1201 require_action( obj
, exit
, err
= kDNSServiceErr_NoMemory
);
1203 obj
->context
= inContext
;
1204 obj
->u
.query
.callback
= inCallBack
;
1206 // Open a session to the server and send the request.
1208 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoClose
, kInvalidSocketRef
, RMxClientMessageCallBack
, obj
,
1209 &obj
->session
, kRMxOpCodeQueryRecord
, "wwshh", inFlags
, inInterfaceIndex
, inName
, inRRType
, inRRClass
);
1210 require_noerr( err
, exit
);
1220 DNSServiceRefDeallocate_client( obj
);
1225 //===========================================================================================================================
1226 // DNSServiceQueryRecordReply_client
1227 //===========================================================================================================================
1229 DEBUG_LOCAL
void DNSServiceQueryRecordReply_client( RMxMessage
*inMessage
)
1233 DNSServiceFlags flags
;
1234 uint32_t interfaceIndex
;
1235 DNSServiceErrorType errorCode
;
1244 obj
= (DNSServiceRef
) inMessage
->context
;
1247 err
= inMessage
->status
;
1250 err
= RMxUnpack( inMessage
->recvData
, inMessage
->recvSize
, "wwwshhnw",
1251 &flags
, &interfaceIndex
, &errorCode
, &name
, NULL
, &rrType
, &rrClass
, &rData
, &rDataSize
, &ttl
);
1255 dlog( kDebugLevelTrace
, DEBUG_NAME
1256 "QueryRecord reply flags=0x%08X, ifi=%d, err=%d, name=\"%s\", rrType=%d, rrClass=%d, rDataSize=%d, ttl=%d\n",
1257 flags
, interfaceIndex
, errorCode
, name
, rrType
, rrClass
, rDataSize
, ttl
);
1259 obj
->u
.query
.callback( obj
, flags
, interfaceIndex
, errorCode
, name
, rrType
, rrClass
, (uint16_t) rDataSize
, rData
,
1260 ttl
, obj
->context
);
1265 obj
->u
.query
.callback( obj
, 0, 0, err
, "", 0, 0, 0, NULL
, 0, obj
->context
);
1269 //===========================================================================================================================
1270 // DNSServiceReconfirmRecord_client
1271 //===========================================================================================================================
1274 DNSServiceReconfirmRecord_client(
1275 const char * inServer
,
1276 DNSServiceFlags inFlags
,
1277 uint32_t inInterfaceIndex
,
1278 const char * inName
,
1281 uint16_t inRDataSize
,
1282 const void * inRData
)
1284 DNSServiceErrorType err
;
1286 dlog( kDebugLevelTrace
, "\n" DEBUG_NAME
"ReconfirmRecord flags=0x%08X, ifi=%d, name=\"%s\", rrType=%d, rrClass=%d\n",
1287 inFlags
, inInterfaceIndex
, inName
, inRRType
, inRRClass
);
1288 require_action( inFlags
== 0, exit
, err
= kDNSServiceErr_BadFlags
);
1289 require_action( inName
, exit
, err
= kDNSServiceErr_BadParam
);
1290 require_action( inRData
&& ( inRDataSize
> 0 ), exit
, err
= kDNSServiceErr_BadParam
);
1292 err
= RMxSessionOpen( inServer
, kRMxSessionFlagsNoClose
, kInvalidSocketRef
, NULL
, NULL
, NULL
,
1293 kRMxOpCodeReconfirmRecord
, "wwshhn", inFlags
, inInterfaceIndex
, inName
, inRRType
, inRRClass
, inRDataSize
, inRData
);
1294 require_noerr( err
, exit
);