static RRset *conv_trick_rrset (RRset *rrs_a, uint16_t qtype, int pref) { const char *fn = "conv_trick_rrset()"; RR_List *rrl = NULL, *rrl_tmp; RRset *rrs_new = NULL; RR *rr_a = NULL, *rr_new = NULL; u_char *rd, *rd_new = NULL; syslog (LOG_DEBUG, "%s: start", fn); /* parse A resource record set */ rrl = rr_list_of_rrset (rrs_a); if (!rrl) return NULL; /* convert each RR_List data */ for (rrl_tmp = rrl; rrl_tmp->next; rrl_tmp = rrl_tmp->next) { int rdlen; u_char *rd_addr; rr_a = rrl_tmp->rrp; rrl_tmp->rrp = NULL; /* kept in rr_a */ rd = rr_rdata (rr_a); rdlen = sizeof(struct in6_addr); if (qtype == RT_A6) rdlen++; /* size of prefix length */ rd_new = malloc (rdlen); if (!rd_new) break; rd_addr = (qtype == RT_AAAA) ? rd_new : (rd_new + 1); memcpy (rd_addr, T.prefix[pref], 12); memcpy (rd_addr + 12, rd, 4); if (qtype == RT_A6) *rd_new = 0; /* plen is 0 */ rr_new = rr_alloc (rr_a->ttl, rdlen, rd_new); if (!rr_new) break; free (rd_new); rd_new = NULL; /* kept in rr_new */ rrl_tmp->rrp = rr_new; rr_new = NULL; /* kept in rrl_tmp->rrp */ free (rr_a); rr_a = NULL; } /* assemble A6/AAAA rrset */ rrs_new = rrset_create (qtype, rrs_a->key.info->r_class, rrs_a->key.info->owner_len, rrset_owner (rrs_a), rrl); /* cleanup */ if (rr_a) free (rr_a); if (rr_new) free (rr_new); if (rrl) rr_list_free (rrl); if (rd_new) free (rd_new); return rrs_new; }
/** * Add RR. * */ ods_status zone_add_rr(zone_type* zone, ldns_rr* rr, int do_stats) { domain_type* domain = NULL; rrset_type* rrset = NULL; rr_type* record = NULL; ods_status status = ODS_STATUS_OK; ods_log_assert(rr); ods_log_assert(zone); ods_log_assert(zone->name); ods_log_assert(zone->db); ods_log_assert(zone->signconf); /* If we already have this RR, return ODS_STATUS_UNCHANGED */ domain = namedb_lookup_domain(zone->db, ldns_rr_owner(rr)); if (!domain) { domain = namedb_add_domain(zone->db, ldns_rr_owner(rr)); if (!domain) { ods_log_error("[%s] unable to add RR to zone %s: " "failed to add domain", zone_str, zone->name); return ODS_STATUS_ERR; } if (ldns_dname_compare(domain->dname, zone->apex) == 0) { domain->is_apex = 1; } else { status = namedb_domain_entize(zone->db, domain, zone->apex); if (status != ODS_STATUS_OK) { ods_log_error("[%s] unable to add RR to zone %s: " "failed to entize domain", zone_str, zone->name); return ODS_STATUS_ERR; } } } rrset = domain_lookup_rrset(domain, ldns_rr_get_type(rr)); if (!rrset) { rrset = rrset_create(domain->zone, ldns_rr_get_type(rr)); if (!rrset) { ods_log_error("[%s] unable to add RR to zone %s: " "failed to add RRset", zone_str, zone->name); return ODS_STATUS_ERR; } domain_add_rrset(domain, rrset); } record = rrset_lookup_rr(rrset, rr); if (record) { record->is_added = 1; /* already exists, just mark added */ record->is_removed = 0; /* unset is_removed */ if (ldns_rr_ttl(rr) != ldns_rr_ttl(record->rr)) { ldns_rr_set_ttl(record->rr, ldns_rr_ttl(rr)); rrset->needs_signing = 1; } return ODS_STATUS_UNCHANGED; } else { record = rrset_add_rr(rrset, rr); ods_log_assert(record); ods_log_assert(record->rr); ods_log_assert(record->is_added); } /* update stats */ if (do_stats && zone->stats) { zone->stats->sort_count += 1; } return ODS_STATUS_OK; }