int delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name, int lame) { struct delegpt_ns* ns; size_t len; (void)dname_count_size_labels(name, &len); /* slow check for duplicates to avoid counting failures when * adding the same server as a dependency twice */ if(delegpt_find_ns(dp, name, len)) return 1; ns = (struct delegpt_ns*)regional_alloc(region, sizeof(struct delegpt_ns)); if(!ns) return 0; ns->next = dp->nslist; ns->namelen = len; dp->nslist = ns; ns->name = regional_alloc_init(region, name, ns->namelen); ns->resolved = 0; ns->got4 = 0; ns->got6 = 0; ns->lame = (uint8_t)lame; ns->done_pside4 = 0; ns->done_pside6 = 0; return 1; }
int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame) { struct delegpt_ns* ns; size_t len; (void)dname_count_size_labels(name, &len); log_assert(dp->dp_type_mlc); /* slow check for duplicates to avoid counting failures when * adding the same server as a dependency twice */ if(delegpt_find_ns(dp, name, len)) return 1; ns = (struct delegpt_ns*)malloc(sizeof(struct delegpt_ns)); if(!ns) return 0; ns->namelen = len; ns->name = memdup(name, ns->namelen); if(!ns->name) { free(ns); return 0; } ns->next = dp->nslist; dp->nslist = ns; ns->resolved = 0; ns->got4 = 0; ns->got6 = 0; ns->lame = (uint8_t)lame; ns->done_pside4 = 0; ns->done_pside6 = 0; return 1; }
void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg) { struct reply_info* rep = (struct reply_info*)msg->entry.data; if(!rep) return; /* if error or no answers */ if(FLAGS_GET_RCODE(rep->flags) != 0 || rep->an_numrrsets == 0) { struct delegpt_ns* ns = delegpt_find_ns(dp, msg->key.qname, msg->key.qname_len); if(ns) { if(msg->key.qtype == LDNS_RR_TYPE_A) ns->got4 = 1; else if(msg->key.qtype == LDNS_RR_TYPE_AAAA) ns->got6 = 1; if(ns->got4 && ns->got6) ns->resolved = 1; } } }
int delegpt_add_target(struct delegpt* dp, struct regional* region, uint8_t* name, size_t namelen, struct sockaddr_storage* addr, socklen_t addrlen, int bogus, int lame, int nodup) { struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); if(!ns) { /* ignore it */ return 1; } if(!lame) { if(addr_is_ip6(addr, addrlen)) ns->got6 = 1; else ns->got4 = 1; if(ns->got4 && ns->got6) ns->resolved = 1; } return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, nodup); }
int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, uint8_t lame) { struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); log_assert(dp->dp_type_mlc); if(!ns) { /* ignore it */ return 1; } if(!lame) { if(addr_is_ip6(addr, addrlen)) ns->got6 = 1; else ns->got4 = 1; if(ns->got4 && ns->got6) ns->resolved = 1; } return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame); }
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags, struct delegpt* dp) { struct delegpt_ns* ns; /* check: * o RD qflag is on. * o no addresses are provided. * o all NS items are required glue. * OR * o RD qflag is on. * o no addresses are provided. * o the query is for one of the nameservers in dp, * and that nameserver is a glue-name for this dp. */ if(!(qflags&BIT_RD)) return 0; /* either available or unused targets */ if(dp->usable_list || dp->result_list) return 0; /* see if query is for one of the nameservers, which is glue */ if( (qinfo->qtype == LDNS_RR_TYPE_A || qinfo->qtype == LDNS_RR_TYPE_AAAA) && dname_subdomain_c(qinfo->qname, dp->name) && delegpt_find_ns(dp, qinfo->qname, qinfo->qname_len)) return 1; for(ns = dp->nslist; ns; ns = ns->next) { if(ns->resolved) /* skip failed targets */ continue; if(!dname_subdomain_c(ns->name, dp->name)) return 0; /* one address is not required glue */ } return 1; }