2 * Copyright (c) 2019-2020 Apple Inc. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * https://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include "dnssd_xpc.h"
19 //======================================================================================================================
20 // MARK: - XPC Dictionary Helper Declarations
23 _dnssd_xpc_dictionary_get_int32(xpc_object_t dict
, const char *key
, bool *out_valid
);
26 _dnssd_xpc_dictionary_get_int64(xpc_object_t dict
, const char *key
, bool *out_valid
);
29 _dnssd_xpc_dictionary_get_int64_limited(xpc_object_t dict
, const char *key
, int64_t min
, int64_t max
, bool *out_valid
);
32 _dnssd_xpc_dictionary_get_uint16(xpc_object_t dict
, const char *key
, bool *out_valid
);
35 _dnssd_xpc_dictionary_get_uint32(xpc_object_t dict
, const char *key
, bool *out_valid
);
38 _dnssd_xpc_dictionary_get_uint64(xpc_object_t dict
, const char *key
, bool *out_valid
);
41 _dnssd_xpc_dictionary_get_uint64_limited(xpc_object_t dict
, const char *key
, uint64_t min
, uint64_t max
,
45 _dnssd_xpc_dictionary_get_value(xpc_object_t dict
, const char *key
, xpc_type_t type
);
47 //======================================================================================================================
48 // MARK: - Top-Level Message Dictionaries
50 #define DNSSD_XPC_MESSAGE_KEY_COMMAND "command"
51 #define DNSSD_XPC_MESSAGE_KEY_ERROR "error"
52 #define DNSSD_XPC_MESSAGE_KEY_ID "id"
53 #define DNSSD_XPC_MESSAGE_KEY_PARAMS "params"
54 #define DNSSD_XPC_MESSAGE_KEY_RESULTS "results"
56 //======================================================================================================================
58 const char * _Nullable
59 dnssd_xpc_message_get_command(xpc_object_t msg
)
61 return xpc_dictionary_get_string(msg
, DNSSD_XPC_MESSAGE_KEY_COMMAND
);
64 //======================================================================================================================
67 dnssd_xpc_message_set_command(xpc_object_t msg
, const char *command
)
69 xpc_dictionary_set_string(msg
, DNSSD_XPC_MESSAGE_KEY_COMMAND
, command
);
72 //======================================================================================================================
75 dnssd_xpc_message_get_error(xpc_object_t msg
, bool *out_valid
)
77 return _dnssd_xpc_dictionary_get_int32(msg
, DNSSD_XPC_MESSAGE_KEY_ERROR
, out_valid
);
80 //======================================================================================================================
83 dnssd_xpc_message_set_error(xpc_object_t msg
, DNSServiceErrorType error
)
85 xpc_dictionary_set_int64(msg
, DNSSD_XPC_MESSAGE_KEY_ERROR
, error
);
88 //======================================================================================================================
91 dnssd_xpc_message_get_id(xpc_object_t msg
, bool *out_valid
)
93 return _dnssd_xpc_dictionary_get_uint64(msg
, DNSSD_XPC_MESSAGE_KEY_ID
, out_valid
);
96 //======================================================================================================================
99 dnssd_xpc_message_set_id(xpc_object_t msg
, uint64_t ident
)
101 xpc_dictionary_set_uint64(msg
, DNSSD_XPC_MESSAGE_KEY_ID
, ident
);
104 //======================================================================================================================
107 dnssd_xpc_message_get_parameters(xpc_object_t msg
)
109 return xpc_dictionary_get_dictionary(msg
, DNSSD_XPC_MESSAGE_KEY_PARAMS
);
112 //======================================================================================================================
115 dnssd_xpc_message_set_parameters(xpc_object_t msg
, xpc_object_t params
)
117 xpc_dictionary_set_value(msg
, DNSSD_XPC_MESSAGE_KEY_PARAMS
, params
);
120 //======================================================================================================================
123 dnssd_xpc_message_get_results(xpc_object_t msg
)
125 return xpc_dictionary_get_array(msg
, DNSSD_XPC_MESSAGE_KEY_RESULTS
);
128 //======================================================================================================================
131 dnssd_xpc_message_set_results(xpc_object_t msg
, xpc_object_t results
)
133 xpc_dictionary_set_value(msg
, DNSSD_XPC_MESSAGE_KEY_RESULTS
, results
);
136 //======================================================================================================================
137 // MARK: - Parameter Dictionaries
139 #define DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID "delegate_id"
140 #define DNSSD_XPC_PARAMETERS_KEY_FLAGS "flags"
141 #define DNSSD_XPC_PARAMETERS_KEY_ACCOUNT_ID "account_id"
142 #define DNSSD_XPC_PARAMETERS_KEY_HOSTNAME "hostname"
143 #define DNSSD_XPC_PARAMETERS_KEY_INTERFACE_INDEX "interface_index"
144 #define DNSSD_XPC_PARAMETERS_KEY_NEED_AUTH_TAGS "need_auth_tags"
145 #define DNSSD_XPC_PARAMETERS_KEY_PROTOCOLS "protocols"
146 #define DNSSD_XPC_PARAMETERS_KEY_NEED_ENCRYPTION "need_encryption"
147 #define DNSSD_XPC_PARAMETERS_KEY_FALLBACK_CONFIG "fallback_config"
148 #define DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS "resolver_uuids"
149 #define DNSSD_XPC_PARAMETERS_KEY_SERVICE_SCHEME "service_scheme"
151 //======================================================================================================================
154 dnssd_xpc_parameters_get_delegate_pid(xpc_object_t params
, bool *out_valid
)
156 return (pid_t
)_dnssd_xpc_dictionary_get_int64(params
, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID
, out_valid
);
159 //======================================================================================================================
162 dnssd_xpc_parameters_set_delegate_pid(xpc_object_t params
, pid_t pid
)
164 xpc_dictionary_set_int64(params
, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID
, pid
);
167 //======================================================================================================================
170 dnssd_xpc_parameters_get_delegate_uuid(xpc_object_t params
)
172 return xpc_dictionary_get_uuid(params
, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID
);
175 //======================================================================================================================
178 dnssd_xpc_parameters_set_delegate_uuid(xpc_object_t params
, uuid_t uuid
)
180 xpc_dictionary_set_uuid(params
, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID
, uuid
);
183 //======================================================================================================================
185 audit_token_t
* _Nullable
186 dnssd_xpc_parameters_get_delegate_audit_token(const xpc_object_t params
, audit_token_t
* const audit_token_storage
)
189 const void * const data
= xpc_dictionary_get_data(params
, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID
, &size
);
190 if (data
&& (size
== sizeof(*audit_token_storage
))) {
191 memcpy(audit_token_storage
, data
, size
);
192 return audit_token_storage
;
198 //======================================================================================================================
201 dnssd_xpc_parameters_set_delegate_audit_token(const xpc_object_t params
, const audit_token_t
* const audit_token
)
203 xpc_dictionary_set_data(params
, DNSSD_XPC_PARAMETERS_KEY_DELEGATE_ID
, audit_token
, sizeof(*audit_token
));
206 //======================================================================================================================
209 dnssd_xpc_parameters_get_flags(xpc_object_t params
, bool *out_valid
)
211 return _dnssd_xpc_dictionary_get_uint32(params
, DNSSD_XPC_PARAMETERS_KEY_FLAGS
, out_valid
);
214 //======================================================================================================================
217 dnssd_xpc_parameters_set_flags(xpc_object_t params
, DNSServiceFlags flags
)
219 xpc_dictionary_set_uint64(params
, DNSSD_XPC_PARAMETERS_KEY_FLAGS
, flags
);
222 //======================================================================================================================
225 dnssd_xpc_parameters_get_account_id(xpc_object_t params
)
227 return xpc_dictionary_get_string(params
, DNSSD_XPC_PARAMETERS_KEY_ACCOUNT_ID
);
230 //======================================================================================================================
233 dnssd_xpc_parameters_set_account_id(xpc_object_t params
, const char *account_id
)
235 xpc_dictionary_set_string(params
, DNSSD_XPC_PARAMETERS_KEY_ACCOUNT_ID
, account_id
);
238 //======================================================================================================================
241 dnssd_xpc_parameters_get_hostname_object(xpc_object_t params
)
243 return _dnssd_xpc_dictionary_get_value(params
, DNSSD_XPC_PARAMETERS_KEY_HOSTNAME
, XPC_TYPE_STRING
);
246 //======================================================================================================================
249 dnssd_xpc_parameters_set_hostname(xpc_object_t params
, const char *hostname
)
251 xpc_dictionary_set_string(params
, DNSSD_XPC_PARAMETERS_KEY_HOSTNAME
, hostname
);
254 //======================================================================================================================
257 dnssd_xpc_parameters_get_interface_index(xpc_object_t params
, bool *out_valid
)
259 return _dnssd_xpc_dictionary_get_uint32(params
, DNSSD_XPC_PARAMETERS_KEY_INTERFACE_INDEX
, out_valid
);
262 //======================================================================================================================
265 dnssd_xpc_parameters_set_interface_index(xpc_object_t params
, uint32_t interface_index
)
267 xpc_dictionary_set_uint64(params
, DNSSD_XPC_PARAMETERS_KEY_INTERFACE_INDEX
, interface_index
);
270 //======================================================================================================================
273 dnssd_xpc_parameters_get_need_authentication_tags(xpc_object_t params
)
275 return xpc_dictionary_get_bool(params
, DNSSD_XPC_PARAMETERS_KEY_NEED_AUTH_TAGS
);
278 //======================================================================================================================
281 dnssd_xpc_parameters_set_need_authentication_tags(xpc_object_t params
, bool need_auth_tags
)
283 xpc_dictionary_set_bool(params
, DNSSD_XPC_PARAMETERS_KEY_NEED_AUTH_TAGS
, need_auth_tags
);
286 //======================================================================================================================
289 dnssd_xpc_parameters_set_need_encrypted_query(xpc_object_t params
, bool need
, _Nullable xpc_object_t fallback_config
)
291 xpc_dictionary_set_bool(params
, DNSSD_XPC_PARAMETERS_KEY_NEED_ENCRYPTION
, need
);
292 if (fallback_config
!= NULL
) {
293 xpc_dictionary_set_value(params
, DNSSD_XPC_PARAMETERS_KEY_FALLBACK_CONFIG
, fallback_config
);
297 //======================================================================================================================
300 dnssd_xpc_parameters_get_need_encrypted_query(xpc_object_t params
)
302 return xpc_dictionary_get_bool(params
, DNSSD_XPC_PARAMETERS_KEY_NEED_ENCRYPTION
);
305 //======================================================================================================================
307 xpc_object_t _Nullable
308 dnssd_xpc_parameters_get_fallback_config(xpc_object_t params
)
310 return xpc_dictionary_get_value(params
, DNSSD_XPC_PARAMETERS_KEY_FALLBACK_CONFIG
);
313 //======================================================================================================================
315 xpc_object_t _Nullable
316 dnssd_xpc_parameters_get_resolver_uuid_array(xpc_object_t params
)
318 return xpc_dictionary_get_value(params
, DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS
);
321 //======================================================================================================================
324 dnssd_xpc_parameters_add_resolver_uuid(xpc_object_t params
, uuid_t _Nonnull uuid
)
326 xpc_object_t resolver_uuid_array
= xpc_dictionary_get_value(params
, DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS
);
327 if (resolver_uuid_array
== NULL
) {
328 resolver_uuid_array
= xpc_array_create(NULL
, 0);
329 xpc_dictionary_set_value(params
, DNSSD_XPC_PARAMETERS_KEY_RESOLVER_UUIDS
, resolver_uuid_array
);
330 xpc_release(resolver_uuid_array
);
332 xpc_array_set_uuid(resolver_uuid_array
, XPC_ARRAY_APPEND
, uuid
);
335 //======================================================================================================================
338 dnssd_xpc_parameters_get_protocols(xpc_object_t params
, bool *out_valid
)
340 return _dnssd_xpc_dictionary_get_uint32(params
, DNSSD_XPC_PARAMETERS_KEY_PROTOCOLS
, out_valid
);
343 //======================================================================================================================
346 dnssd_xpc_parameters_set_protocols(xpc_object_t params
, DNSServiceProtocol protocols
)
348 xpc_dictionary_set_uint64(params
, DNSSD_XPC_PARAMETERS_KEY_PROTOCOLS
, protocols
);
351 //======================================================================================================================
353 const char * _Nullable
354 dnssd_xpc_parameters_get_service_scheme(xpc_object_t params
)
356 return xpc_dictionary_get_string(params
, DNSSD_XPC_PARAMETERS_KEY_SERVICE_SCHEME
);
359 //======================================================================================================================
362 dnssd_xpc_parameters_set_service_scheme(xpc_object_t params
, const char *service_scheme
)
364 xpc_dictionary_set_string(params
, DNSSD_XPC_PARAMETERS_KEY_SERVICE_SCHEME
, service_scheme
);
367 //======================================================================================================================
368 // MARK: - Result Dictionaries
370 #define DNSSD_XPC_RESULT_KEY_AUTH_TAG "auth_tag"
371 #define DNSSD_XPC_RESULT_KEY_CNAME_UPDATE "cname_update"
372 #define DNSSD_XPC_RESULT_KEY_ERROR "error"
373 #define DNSSD_XPC_RESULT_KEY_FLAGS "flags"
374 #define DNSSD_XPC_RESULT_KEY_INTERFACE_INDEX "interface_index"
375 #define DNSSD_XPC_RESULT_KEY_PROVIDER_NAME "provider_name"
376 #define DNSSD_XPC_RESULT_KEY_RECORD_CLASS "rclass"
377 #define DNSSD_XPC_RESULT_KEY_RECORD_DATA "rdata"
378 #define DNSSD_XPC_RESULT_KEY_RECORD_NAME "rname"
379 #define DNSSD_XPC_RESULT_KEY_RECORD_PROTOCOL "rprotocol"
380 #define DNSSD_XPC_RESULT_KEY_RECORD_TYPE "rtype"
382 //======================================================================================================================
385 dnssd_xpc_result_get_authentication_tag_object(xpc_object_t result
)
387 return _dnssd_xpc_dictionary_get_value(result
, DNSSD_XPC_RESULT_KEY_AUTH_TAG
, XPC_TYPE_DATA
);
390 //======================================================================================================================
393 dnssd_xpc_result_set_authentication_tag(xpc_object_t result
, const void *auth_tag_ptr
, size_t auth_tag_len
)
395 xpc_dictionary_set_data(result
, DNSSD_XPC_RESULT_KEY_AUTH_TAG
, auth_tag_ptr
, auth_tag_len
);
398 //======================================================================================================================
401 dnssd_xpc_result_get_error(xpc_object_t result
, bool *out_valid
)
403 return _dnssd_xpc_dictionary_get_int32(result
, DNSSD_XPC_RESULT_KEY_ERROR
, out_valid
);
406 //======================================================================================================================
409 dnssd_xpc_result_set_error(xpc_object_t result
, DNSServiceErrorType error
)
411 xpc_dictionary_set_int64(result
, DNSSD_XPC_RESULT_KEY_ERROR
, error
);
414 //======================================================================================================================
417 dnssd_xpc_result_get_flags(xpc_object_t result
, bool *out_valid
)
419 return _dnssd_xpc_dictionary_get_uint32(result
, DNSSD_XPC_RESULT_KEY_FLAGS
, out_valid
);
422 //======================================================================================================================
425 dnssd_xpc_result_set_flags(xpc_object_t result
, DNSServiceFlags flags
)
427 xpc_dictionary_set_uint64(result
, DNSSD_XPC_RESULT_KEY_FLAGS
, flags
);
430 //======================================================================================================================
433 dnssd_xpc_result_get_interface_index(xpc_object_t result
, bool *out_valid
)
435 return _dnssd_xpc_dictionary_get_uint32(result
, DNSSD_XPC_RESULT_KEY_INTERFACE_INDEX
, out_valid
);
438 //======================================================================================================================
441 dnssd_xpc_result_set_interface_index(xpc_object_t result
, uint32_t interface_index
)
443 xpc_dictionary_set_uint64(result
, DNSSD_XPC_RESULT_KEY_INTERFACE_INDEX
, interface_index
);
446 //======================================================================================================================
449 dnssd_xpc_result_get_record_class(xpc_object_t result
, bool *out_valid
)
451 return _dnssd_xpc_dictionary_get_uint16(result
, DNSSD_XPC_RESULT_KEY_RECORD_CLASS
, out_valid
);
454 //======================================================================================================================
457 dnssd_xpc_result_set_record_class(xpc_object_t result
, uint16_t class)
459 xpc_dictionary_set_uint64(result
, DNSSD_XPC_RESULT_KEY_RECORD_CLASS
, class);
462 //======================================================================================================================
465 dnssd_xpc_result_get_record_data_object(xpc_object_t result
)
467 return _dnssd_xpc_dictionary_get_value(result
, DNSSD_XPC_RESULT_KEY_RECORD_DATA
, XPC_TYPE_DATA
);
470 //======================================================================================================================
473 dnssd_xpc_result_set_record_data(xpc_object_t result
, const void *data_ptr
, size_t data_len
)
475 xpc_dictionary_set_data(result
, DNSSD_XPC_RESULT_KEY_RECORD_DATA
, data_ptr
, data_len
);
478 //======================================================================================================================
481 dnssd_xpc_result_get_record_name_object(xpc_object_t result
)
483 return _dnssd_xpc_dictionary_get_value(result
, DNSSD_XPC_RESULT_KEY_RECORD_NAME
, XPC_TYPE_STRING
);
486 //======================================================================================================================
489 dnssd_xpc_result_set_record_name(xpc_object_t result
, const char *name
)
491 xpc_dictionary_set_string(result
, DNSSD_XPC_RESULT_KEY_RECORD_NAME
, name
);
494 //======================================================================================================================
497 dnssd_xpc_result_get_record_type(xpc_object_t result
, bool *out_valid
)
499 return _dnssd_xpc_dictionary_get_uint16(result
, DNSSD_XPC_RESULT_KEY_RECORD_TYPE
, out_valid
);
502 //======================================================================================================================
505 dnssd_xpc_result_set_record_type(xpc_object_t result
, uint16_t type
)
507 xpc_dictionary_set_uint64(result
, DNSSD_XPC_RESULT_KEY_RECORD_TYPE
, type
);
510 //======================================================================================================================
513 dnssd_xpc_result_get_record_protocol(xpc_object_t result
, bool * out_valid
)
515 return _dnssd_xpc_dictionary_get_uint16(result
, DNSSD_XPC_RESULT_KEY_RECORD_PROTOCOL
, out_valid
);
518 //======================================================================================================================
521 dnssd_xpc_result_set_record_protocol(xpc_object_t result
, uint16_t protocol
)
523 xpc_dictionary_set_uint64(result
, DNSSD_XPC_RESULT_KEY_RECORD_PROTOCOL
, protocol
);
526 //======================================================================================================================
529 dnssd_xpc_result_get_provider_name_object(xpc_object_t result
)
531 return _dnssd_xpc_dictionary_get_value(result
, DNSSD_XPC_RESULT_KEY_PROVIDER_NAME
, XPC_TYPE_STRING
);
534 //======================================================================================================================
537 dnssd_xpc_result_set_provider_name(xpc_object_t result
, const char *name
)
539 xpc_dictionary_set_string(result
, DNSSD_XPC_RESULT_KEY_PROVIDER_NAME
, name
);
542 //======================================================================================================================
545 dnssd_xpc_result_get_cname_update(xpc_object_t result
)
547 return xpc_dictionary_get_array(result
, DNSSD_XPC_RESULT_KEY_CNAME_UPDATE
);
550 //======================================================================================================================
553 dnssd_xpc_result_set_cname_update(xpc_object_t result
, xpc_object_t cname_update
)
555 xpc_dictionary_set_value(result
, DNSSD_XPC_RESULT_KEY_CNAME_UPDATE
, cname_update
);
558 //======================================================================================================================
559 // MARK: - XPC Dictionary Helpers
562 _dnssd_xpc_dictionary_get_int32(xpc_object_t dict
, const char *key
, bool *out_valid
)
564 return (int32_t)_dnssd_xpc_dictionary_get_int64_limited(dict
, key
, INT32_MIN
, INT32_MAX
, out_valid
);
567 //======================================================================================================================
570 _dnssd_xpc_dictionary_get_int64(xpc_object_t dict
, const char *key
, bool *out_valid
)
572 return _dnssd_xpc_dictionary_get_int64_limited(dict
, key
, INT64_MIN
, INT64_MAX
, out_valid
);
575 //======================================================================================================================
578 _dnssd_xpc_dictionary_get_int64_limited(xpc_object_t dict
, const char *key
, int64_t min
, int64_t max
, bool *out_valid
)
583 xpc_object_t
const value
= _dnssd_xpc_dictionary_get_value(dict
, key
, XPC_TYPE_INT64
);
585 i64
= xpc_int64_get_value(value
);
586 if ((i64
>= min
) && (i64
<= max
)) {
602 //======================================================================================================================
605 _dnssd_xpc_dictionary_get_uint16(xpc_object_t dict
, const char *key
, bool *out_valid
)
607 return (uint16_t)_dnssd_xpc_dictionary_get_uint64_limited(dict
, key
, 0, UINT16_MAX
, out_valid
);
610 //======================================================================================================================
613 _dnssd_xpc_dictionary_get_uint32(xpc_object_t dict
, const char *key
, bool *out_valid
)
615 return (uint32_t)_dnssd_xpc_dictionary_get_uint64_limited(dict
, key
, 0, UINT32_MAX
, out_valid
);
618 //======================================================================================================================
621 _dnssd_xpc_dictionary_get_uint64(xpc_object_t dict
, const char *key
, bool *out_valid
)
623 return _dnssd_xpc_dictionary_get_uint64_limited(dict
, key
, 0, UINT64_MAX
, out_valid
);
626 //======================================================================================================================
629 _dnssd_xpc_dictionary_get_uint64_limited(xpc_object_t dict
, const char *key
, uint64_t min
, uint64_t max
,
635 xpc_object_t
const value
= _dnssd_xpc_dictionary_get_value(dict
, key
, XPC_TYPE_UINT64
);
637 u64
= xpc_uint64_get_value(value
);
638 if ((u64
>= min
) && (u64
<= max
)) {
654 //======================================================================================================================
657 _dnssd_xpc_dictionary_get_value(xpc_object_t dict
, const char *key
, xpc_type_t type
)
659 xpc_object_t value
= xpc_dictionary_get_value(dict
, key
);
660 return (value
&& (xpc_get_type(value
) == type
)) ? value
: NULL
;