From: Vladimír Čunát Date: Wed, 1 Aug 2018 16:06:17 +0000 (+0200) Subject: knot_dname_in_bailiwick(): new API X-Git-Tag: v2.7.0~5^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d55f160a96bbcfe36ee4e10a2211bee669e9f0df;p=thirdparty%2Fknot-dns.git knot_dname_in_bailiwick(): new API And reimplement knot_dname_is_sub() and knot_dname_in() via the new API. --- diff --git a/src/libknot/dname.c b/src/libknot/dname.c index d97bcd4efe..1a2790ea63 100644 --- a/src/libknot/dname.c +++ b/src/libknot/dname.c @@ -516,44 +516,6 @@ size_t knot_dname_realsize(const knot_dname_t *name, const uint8_t *pkt) return len + 1; } -_public_ -bool knot_dname_is_sub(const knot_dname_t *sub, const knot_dname_t *domain) -{ - if (sub == NULL || domain == NULL || sub == domain) { - return false; - } - - /* Subdomain must have more labels than parent. */ - size_t sub_l = knot_dname_labels(sub, NULL); - size_t domain_l = knot_dname_labels(domain, NULL); - if (sub_l <= domain_l) { - return false; - } - - /* Align end-to-end to common suffix. */ - int common = dname_align(&sub, sub_l, &domain, domain_l); - - /* Compare common suffix. */ - while (common > 0) { - /* Compare label. */ - if (!label_is_equal(sub, domain)) { - return false; - } - /* Next label. */ - sub = knot_wire_next_label(sub, NULL); - domain = knot_wire_next_label(domain, NULL); - --common; - } - - return true; -} - -_public_ -bool knot_dname_in(const knot_dname_t *domain, const knot_dname_t *sub) -{ - return knot_dname_is_equal(domain, sub) || knot_dname_is_sub(sub, domain); -} - _public_ size_t knot_dname_matched_labels(const knot_dname_t *d1, const knot_dname_t *d2) { @@ -772,3 +734,22 @@ uint8_t *knot_dname_lf(const knot_dname_t *src, knot_dname_storage_t storage) return &storage[idx]; } + +_public_ +int knot_dname_in_bailiwick(const knot_dname_t *name, const knot_dname_t *bailiwick) +{ + if (name == NULL || bailiwick == NULL) { + return KNOT_EINVAL; + } + + int label_diff = knot_dname_labels(name, NULL) - knot_dname_labels(bailiwick, NULL); + if (label_diff < 0) { + return KNOT_EOUTOFZONE; + } + + for (int i = 0; i < label_diff; ++i) { + name = knot_wire_next_label(name, NULL); + } + + return knot_dname_is_equal(name, bailiwick) ? label_diff : KNOT_EOUTOFZONE; +} diff --git a/src/libknot/dname.h b/src/libknot/dname.h index b96e9095b7..e6e11afe49 100644 --- a/src/libknot/dname.h +++ b/src/libknot/dname.h @@ -189,30 +189,6 @@ size_t knot_dname_size(const knot_dname_t *name); _pure_ size_t knot_dname_realsize(const knot_dname_t *name, const uint8_t *pkt); -/*! - * \brief Checks if one domain name is a (strict) subdomain of other. - * - * \param sub Domain name to be the possible subdomain. - * \param domain Domain name to be the possible parent domain. - * - * \retval true \a sub is a (strict) subdomain of \a domain. - * \retval false otherwise. - */ -_pure_ -bool knot_dname_is_sub(const knot_dname_t *sub, const knot_dname_t *domain); - -/*! - * \brief Check if the domain name is a subdomain of or equal to other. - * - * \param domain Domain name to be the possible parent domain. - * \param sub Domain name to be the possible subdomain. - * - * \retval true \a sub us a subdomain or equal to \a domain. - * \retval false otherwise. - */ -_pure_ -bool knot_dname_in(const knot_dname_t *domain, const knot_dname_t *sub); - /*! * \brief Checks if the domain name is a wildcard. * @@ -338,4 +314,46 @@ size_t knot_dname_labels(const uint8_t *name, const uint8_t *pkt); */ uint8_t *knot_dname_lf(const knot_dname_t *src, knot_dname_storage_t storage); +/*! + * \brief Check whether a domain name is under another one and how deep. + * + * \param name The longer name to check. + * \param bailiwick The shorter name to check. + * + * \retval >=0 a subdomain nested this many labels. + * \retval <0 not a subdomain (KNOT_EOUTOFZONE) or another error (KNOT_EINVAL). + */ +int knot_dname_in_bailiwick(const knot_dname_t *name, const knot_dname_t *bailiwick); + +/*! + * \brief Checks if one domain name is a (strict) subdomain of other. + * + * \param sub Domain name to be the possible subdomain. + * \param domain Domain name to be the possible parent domain. + * + * \retval true \a sub is a (strict) subdomain of \a domain. + * \retval false otherwise. + */ +static inline +bool knot_dname_is_sub(const knot_dname_t *sub, const knot_dname_t *domain) +{ + return knot_dname_in_bailiwick(sub, domain) > 0; +} + +/*! + * \brief Check if the domain name is a subdomain of or equal to other. + * + * \param domain Domain name to be the possible parent domain. + * \param sub Domain name to be the possible subdomain. + * + * \retval true \a sub us a subdomain or equal to \a domain. + * \retval false otherwise. + */ +static inline +bool knot_dname_in(const knot_dname_t *domain, const knot_dname_t *sub) +{ + return knot_dname_in_bailiwick(sub, domain) >= 0; +} + + /*! @} */