1 /* 2 * Copyright (c) 2022 Apple Inc. All rights reserved. 3 * 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 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 //====================================================================================================================== 18 // MARK: - Headers 19 20 #include "dns_obj_log.h" 21 #include "dns_obj_rr_srv.h" 22 #include "dns_obj_rr_private.h" 23 #include "dns_obj.h" 24 #include "dns_common.h" 25 #include "rdata_parser.h" 26 27 #include "dns_assert_macros.h" 28 #include "mdns_strict.h" 29 30 //====================================================================================================================== 31 // MARK: - DNS SRV Resource Record Kind Definition 32 33 struct dns_obj_rr_srv_s { 34 struct dns_obj_rr_s base; // The reference count and kind support base. 35 dns_obj_domain_name_t target; 36 }; 37 38 // dns_obj_rr_srv_t is a subkind of dns_obj_rr_t, and it always have DNS type: kDNSRecordType_SRV. 39 DNS_OBJECT_SUBKIND_DEFINE_FULL(rr, srv, 40 .rr_type = kDNSRecordType_SRV, 41 .copy_rdata_rfc_description_method = NULL 42 ); 43 44 //====================================================================================================================== 45 // MARK: - DNS SRV Resource Record Public Methods 46 47 dns_obj_rr_srv_t 48 dns_obj_rr_srv_create(const uint8_t * const name, const uint8_t * const rdata, const uint16_t rdata_len, 49 const bool allocate, dns_obj_error_t * const out_error) 50 { 51 dns_obj_error_t err; 52 dns_obj_rr_srv_t srv = NULL; 53 dns_obj_rr_srv_t obj = NULL; 54 55 const bool valid = rdata_parser_srv_check_validity(rdata, rdata_len); 56 require_action(valid, exit, err = DNS_OBJ_ERROR_MALFORMED_ERR); 57 58 obj = _dns_obj_rr_srv_new(); 59 require_action(obj != NULL, exit, err = DNS_OBJ_ERROR_NO_MEMORY); 60 61 _dns_obj_rr_srv_kind.dns_obj_rr_init_fields(&obj->base, name, _dns_obj_rr_srv_kind.rr_type, 62 kDNSClassType_IN, rdata, rdata_len, allocate, _dns_obj_rr_srv_kind.copy_rdata_rfc_description_method, &err); 63 require_noerr(err, exit); 64 65 const uint8_t * const target_in_labels = rdata_parser_srv_get_target(rdata); 66 obj->target = dns_obj_domain_name_create_with_labels(target_in_labels, true, &err); 67 require_noerr(err, exit); 68 69 dns_obj_replace(&srv, obj); 70 err = DNS_OBJ_ERROR_NO_ERROR; 71 72 exit: 73 if (out_error != NULL) { 74 *out_error = err; 75 } 76 MDNS_DISPOSE_DNS_OBJ(obj); 77 return srv; 78 } 79 80 //====================================================================================================================== 81 82 uint16_t 83 dns_obj_rr_srv_get_priority(const dns_obj_rr_srv_t me) 84 { 85 const uint8_t * const rdata = dns_obj_rr_get_rdata(me); 86 return rdata_parser_srv_get_priority(rdata); 87 } 88 89 //====================================================================================================================== 90 91 uint16_t 92 dns_obj_rr_srv_get_weight(const dns_obj_rr_srv_t me) 93 { 94 const uint8_t * const rdata = dns_obj_rr_get_rdata(me); 95 return rdata_parser_srv_get_weight(rdata); 96 } 97 98 //====================================================================================================================== 99 100 uint16_t 101 dns_obj_rr_srv_get_port(const dns_obj_rr_srv_t me) 102 { 103 const uint8_t * const rdata = dns_obj_rr_get_rdata(me); 104 return rdata_parser_srv_get_port(rdata); 105 } 106 107 //====================================================================================================================== 108 109 dns_obj_domain_name_t 110 dns_obj_rr_srv_get_target(const dns_obj_rr_srv_t me) 111 { 112 return me->target; 113 } 114 115 //====================================================================================================================== 116 // MARK: - DNS Resource Record Private Methods 117 118 static compare_result_t 119 _dns_obj_rr_srv_compare(const dns_obj_rr_srv_t me, const dns_obj_rr_srv_t other, 120 const bool check_equality_only) 121 { 122 if (check_equality_only) { 123 // Let the comparator of the super kind to do comparison if there is one. 124 return compare_result_unknown; 125 } 126 127 const dns_obj_domain_name_t my_name = dns_obj_rr_get_name(me); 128 const dns_obj_domain_name_t others_name = dns_obj_rr_get_name(other); 129 if (!dns_obj_equal(my_name, others_name)) { 130 return compare_result_notequal; 131 } 132 133 const uint16_t my_priority = dns_obj_rr_srv_get_priority(me); 134 const uint16_t others_priority = dns_obj_rr_srv_get_priority(other); 135 if (my_priority < others_priority) { 136 return compare_result_greater; 137 } else if (my_priority > others_priority) { 138 return compare_result_less; 139 } else { 140 return compare_result_equal; 141 } 142 } 143 144 //====================================================================================================================== 145 146 static void 147 _dns_obj_rr_srv_finalize(const dns_obj_rr_srv_t me) 148 { 149 MDNS_DISPOSE_DNS_OBJ(me->target); 150 } 151