Home | History | Annotate | Line # | Download | only in objs
      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