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;
}
예제 #2
0
/**
 * 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;
}