From: jessevz Date: Thu, 13 Jun 2024 08:04:37 +0000 (+0200) Subject: Made a first rough working version for _deleg X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=42b7ce9c41707f7d7c35f93b0bdbe6b1e6da9611;p=thirdparty%2Funbound.git Made a first rough working version for _deleg --- diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c index c8b9a3ffe..ceff0cc3c 100644 --- a/iterator/iter_delegpt.c +++ b/iterator/iter_delegpt.c @@ -408,6 +408,32 @@ find_NS(struct reply_info* rep, size_t from, size_t to) return NULL; } +struct delegpt* delegpt_from_deleg(struct dns_msg*, struct regional* region, uint8_t* ipv4, uint8_t* ipv6, uint8_t* ns_name, size_t ns_name_len) { + struct delegpt* dp; + dp = delegpt_create(region); + delegpt_set_name(dp, region, ns_name); + delegpt_add_ns(dp, region, ns_name, 0, NULL, 53); + // delegpt_rrset_add_ns(dp, region, ns_rrset, 0); + struct sockaddr_in sa4; + socklen_t lenv4 = (socklen_t)sizeof(sa4); + memset(&sa4, 0, lenv4); + sa4.sin_family = AF_INET; + memmove(&sa4.sin_addr, ipv4, INET_SIZE); + + struct sockaddr_in6 sa6; + socklen_t lenv6 = (socklen_t)sizeof(sa6); + memset(&sa6, 0, lenv6); + sa6.sin6_family = AF_INET6; + memmove(&sa6.sin6_addr, ipv6, INET6_SIZE); + + delegpt_add_target(dp, region, ns_name, ns_name_len, (struct sockaddr_storage*)&sa4, lenv4, 0, 0, NULL); + delegpt_add_target(dp, region, ns_name, ns_name_len, (struct sockaddr_storage*)&sa6, lenv6, 0, 0, NULL); + return dp; +// delegpt_add_addr(struct delegpt* dp, struct regional* region, +// struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, +// uint8_t lame, char* tls_auth_name, int port, int* additions) +} + struct delegpt* delegpt_from_message(struct dns_msg* msg, struct regional* region) { diff --git a/iterator/iter_delegpt.h b/iterator/iter_delegpt.h index 49f6f6b81..d79cb438d 100644 --- a/iterator/iter_delegpt.h +++ b/iterator/iter_delegpt.h @@ -361,6 +361,7 @@ size_t delegpt_count_targets(struct delegpt* dp); struct delegpt* delegpt_from_message(struct dns_msg* msg, struct regional* regional); +struct delegpt* delegpt_from_deleg(struct dns_msg*, struct regional* region, uint8_t* ipv4, uint8_t* pv6, uint8_t* ns_name, size_t ns_name_len); /** * Mark negative return in delegation point for specific nameserver. * sets the got4 or got6 to negative, updates the ns->resolved. diff --git a/iterator/iterator.c b/iterator/iterator.c index ca945a472..40f7943a5 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -198,6 +198,8 @@ iter_new(struct module_qstate* qstate, int id) // the initial query (qstate->qinfo) that started all this. iq->qchase = qstate->qinfo; iq->deleg_state = 0; + iq->deleg_original_qname_len = 0; + iq->deleg_original_qname = NULL; outbound_list_init(&iq->outlist); iq->minimise_count = 0; iq->timeout_count = 0; @@ -2602,7 +2604,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, memcpy(delname + first_label_len + sizeof(deleg_wireformat) + 1, qname_minus_first_label, leftover_len); //memcpy other labels in delname log_err("Old delegation point: %s", iq->qchase.qname); log_err("cname without first label: %s", qname_minus_first_label); - + iq->deleg_original_qname = iq->qchase.qname; + iq->deleg_original_qname_len = iq->qchase.qname_len; // log_err("delegation name in bytes:"); // for (size_t i = 0; i < delnamelen; ++i) { // log_err("%u ", delname[i]); @@ -2610,10 +2613,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, log_err("The _deleg delegation point: %s", delname); - //uncomment if not onlys used in stub zone iq->deleg_state = 1; + iq->deleg_original_qname = qstate->qinfo.qname; - //left here iq->dp->namelen = delnamelen; // iq->dp->namelabs++; iq->qchase.qtype = 64; @@ -2623,7 +2625,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, iq->qinfo_out.qtype = 64; iq->qinfo_out.qname = delname; iq->qinfo_out.qname_len = delnamelen; - // iq->deleg_original_qname = qstate->qinfo.qname; // qstate->qinfo.qname = delname; // generate_target_query(qstate, iq, id, uint8_t* name, size_t namelen, uint16_t qtype, uint16_t qclass) } @@ -3309,13 +3310,14 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, } index = index + 1;//add 1 for the root label //Reference https://datatracker.ietf.org/doc/rfc9460/ section 2.2 - uint8_t *ipv4; - uint8_t *ipv6; + uint8_t *ipv4 = NULL; + uint8_t *ipv6 = NULL; while(index < data_len && (ipv4 == NULL || ipv6 == NULL)) { uint16_t svcParamkey = (svcb_data[index] << 8) | svcb_data[index+1]; uint16_t svcParamValLen = (svcb_data[index+2] << 8) | svcb_data[index+3]; + log_err("scvparamkey: %d", svcParamkey); + log_err("scvparamlength: %d", svcParamValLen); index = index + 4; - //logic fault, will never enter the paramkey checks TODOOOOOOOO if (svcParamkey == 4) { //parse IPv4 ipv4 = (uint8_t *)malloc(4 * sizeof(uint8_t)); memcpy(ipv4, svcb_data + index, 4); @@ -3327,12 +3329,46 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, ipv6 = (uint8_t *)malloc(16 * sizeof(uint8_t)); memcpy(ipv6, svcb_data + index, 16); log_err("Parsed IPv6 Hint:"); - for (size_t i = 0; i < 4; ++i) { + for (size_t i = 0; i < 16; ++i) { log_err("%u ", ipv6[i]); } } index = index + svcParamValLen; + } + // old_dp = iq->dp; + iq->dp = delegpt_from_deleg(iq->response, qstate->region, ipv4, ipv6, iq->deleg_original_qname, iq->deleg_original_qname_len); + iq->referral_count++; + iq->sent_count = 0; + iq->dp_target_count = 0; + if(qstate->env->cfg->harden_referral_path) + generate_ns_check(qstate, iq, id); + + /* stop current outstanding queries. + * FIXME: should the outstanding queries be waited for and + * handled? Say by a subquery that inherits the outbound_entry. + */ + outbound_list_clear(&iq->outlist); + iq->num_current_queries = 0; + fptr_ok(fptr_whitelist_modenv_detach_subs( + qstate->env->detach_subs)); + (*qstate->env->detach_subs)(qstate); + iq->num_target_queries = 0; + iq->response = NULL; + iq->fail_addr_type = 0; + verbose(VERB_ALGO, "cleared outbound list for next round"); + + + //turns all values back to normal, normally you would do this after first query found nothing. TODO? + iq->qchase.qname = iq->deleg_original_qname; + iq->qchase.qtype = 1; + iq->qchase.qname_len = iq->deleg_original_qname_len; + + iq->qinfo_out.qtype = 1; + iq->qinfo_out.qname = iq->deleg_original_qname; + iq->qinfo_out.qname_len = iq->deleg_original_qname_len; + + return next_state(iq, QUERYTARGETS_STATE); } else { log_err("TESTTTTTTT2"); //this means no _deleg record found diff --git a/iterator/iterator.h b/iterator/iterator.h index e253f3f7e..1b36d8676 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -431,6 +431,11 @@ struct iter_qstate { /** State for capsfail: QNAME minimisation state for comparisons. */ enum minimisation_state caps_minimisation_state; + //DELEG added code + int deleg_state; + uint8_t* deleg_original_qname; + size_t deleg_original_qname_len; + /** * The query info that is sent upstream. Will be a subset of qchase * when qname minimisation is enabled.