Example #1
0
void
schedule_purge(schedule_type* schedule)
{
    ldns_rbnode_t* node;
    
    if (!schedule || !schedule->tasks) return;

    pthread_mutex_lock(&schedule->schedule_lock);
        /* don't attempt to free payload, still referenced by other tree*/
        while ((node = ldns_rbtree_first(schedule->tasks)) !=
            LDNS_RBTREE_NULL)
        {
            node = ldns_rbtree_delete(schedule->tasks, node->data);
            if (node == 0) break;
            free(node);
        }
        /* also clean up name tree */
        while ((node = ldns_rbtree_first(schedule->tasks_by_name)) !=
            LDNS_RBTREE_NULL)
        {
            node = ldns_rbtree_delete(schedule->tasks_by_name, node->data);
            if (node == 0) break;
            task_cleanup((task_type*) node->data);
            free(node);
        }
    pthread_mutex_unlock(&schedule->schedule_lock);
}
Example #2
0
static ldns_rbnode_t *
ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone,
                                     ldns_rr *rr) {
	ldns_rbnode_t *current_node = ldns_rbtree_first(zone->names);
	ldns_dnssec_name *current_name;
	ldns_rdf *hashed_name;

	hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);

	while (current_node != LDNS_RBTREE_NULL) {
		current_name = (ldns_dnssec_name *) current_node->data;
		if (!current_name->hashed_name) {
			current_name->hashed_name =
				ldns_nsec3_hash_name_frm_nsec3(rr, current_name->name);
		}
		if (ldns_dname_compare(hashed_name,
						   current_name->hashed_name)
		    == 0) {
			ldns_rdf_deep_free(hashed_name);
			return current_node;
		}
		current_node = ldns_rbtree_next(current_node);
	}
	ldns_rdf_deep_free(hashed_name);
	return NULL;
}
Example #3
0
static void
ldns_dnssec_zone_hashed_names_from_nsec3(
		ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
{
	ldns_rbnode_t* current_node;
	ldns_dnssec_name* current_name;

	assert(zone != NULL);
	assert(nsec3rr != NULL);

	if (zone->hashed_names) {
		ldns_traverse_postorder(zone->hashed_names,
				ldns_hashed_names_node_free, NULL);
		LDNS_FREE(zone->hashed_names);
	}
	zone->_nsec3params = nsec3rr;

	/* So this is a NSEC3 zone.
	* Calculate hashes for all names already in the zone
	*/
	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
	if (zone->hashed_names == NULL) {
		return;
	}
	for ( current_node  = ldns_rbtree_first(zone->names)
	    ; current_node != LDNS_RBTREE_NULL
	    ; current_node  = ldns_rbtree_next(current_node)
	    ) {
		current_name = (ldns_dnssec_name *) current_node->data;
		ldns_dnssec_name_make_hashed_name(zone, current_name, nsec3rr);

	}
}
Example #4
0
/**
 * Get the first scheduled task. As long as return value is used
 * caller should hold schedule->schedule_lock.
 * 
 * \param[in] schedule schedule
 * \return task_type* first scheduled task, NULL on no task or error.
 */
static task_type*
get_first_task(schedule_type* schedule)
{
    ldns_rbnode_t* first_node;

    if (!schedule || !schedule->tasks) return NULL;
    first_node = ldns_rbtree_first(schedule->tasks);
    if (!first_node) return NULL;
    return (task_type*) first_node->data;
}
Example #5
0
static int
run(int sockfd, cmdhandler_ctx_type* context, const char *cmd)
{
	struct tm strtime_struct;
	char strtime[64]; /* at least 26 according to docs plus a long integer */
    char* taskdescription;
	size_t i = 0;
        int count;
	time_t now;
	time_t nextFireTime;
	ldns_rbnode_t* node = LDNS_RBTREE_NULL;
	task_type* task = NULL;
	int num_waiting;
        engine_type* engine = getglobalcontext(context);
	(void)cmd;

	ods_log_debug("[%s] list tasks command", module_str);

	ods_log_assert(engine);
	if (!engine->taskq || !engine->taskq->tasks) {
		client_printf(sockfd, "There are no tasks scheduled.\n");
		return 0;
	}

        schedule_info(engine->taskq, &nextFireTime, &num_waiting, &count);
	if (num_waiting == engine->config->num_worker_threads) {
		client_printf(sockfd, "All worker threads idle.\n");
	}

	/* how many tasks */
	client_printf(sockfd, "There %s %i %s scheduled.\n",
		(count==1)?"is":"are", (int) count, (count==1)?"task":"tasks");
	now = time_now();
	strftime(strtime, sizeof(strtime), "%c", localtime_r(&now, &strtime_struct));
	client_printf(sockfd, "It is now %s (%ld seconds since epoch)\n", (strtime[0]?strtime:"(null)"), (long)now);
	if (nextFireTime > now) {
			strftime(strtime, sizeof(strtime), "%c", localtime_r(&nextFireTime, &strtime_struct));
			client_printf(sockfd, "Next task scheduled %s (%ld seconds since epoch)\n", strtime, (long)nextFireTime);
	} else if (nextFireTime >= 0) {
			client_printf(sockfd, "Next task scheduled immediately\n");
	} /* else: no tasks scheduled at all. */
	
	/* list tasks */
	pthread_mutex_lock(&engine->taskq->schedule_lock);
		node = ldns_rbtree_first(engine->taskq->tasks);
		while (node && node != LDNS_RBTREE_NULL) {
			task = (task_type*) node->data;
			taskdescription = schedule_describetask(task);
			client_printf(sockfd, "%s", taskdescription);
                        free(taskdescription);
			node = ldns_rbtree_next(node);
		}
	pthread_mutex_unlock(&engine->taskq->schedule_lock);
	return 0;
}
Example #6
0
void MV_SHM_Dump_Node(ldns_rbtree_t *shm_root)
{
	ldns_rbnode_t *node;
	shm_address_t *tmp;
    dump_stack_android();
	node = ldns_rbtree_first(shm_root);
	while (node != LDNS_RBTREE_NULL) {
		tmp = (shm_address_t *)(node->key);
		node = ldns_rbtree_next(node);
        MV_SHM_Print("SHM:DUMP:N:0x%x,PA:0x%x,VA=0x%x,SZ=0x%x", \
            tmp, tmp->m_phyaddress, tmp->m_virtaddress, tmp->m_size);
    }
}
Example #7
0
void
ldns_dnssec_zone_names_print_fmt(FILE *out, const ldns_output_format *fmt,
		ldns_rbtree_t *tree, 
		bool print_soa)
{
	ldns_rbnode_t *node;
	ldns_dnssec_name *name;

	node = ldns_rbtree_first(tree);
	while (node != LDNS_RBTREE_NULL) {
		name = (ldns_dnssec_name *) node->data;
		ldns_dnssec_name_print_soa_fmt(out, fmt, name, print_soa);
		if ((fmt->flags & LDNS_COMMENT_LAYOUT))
			fprintf(out, ";\n");
		node = ldns_rbtree_next(node);
	}
}
Example #8
0
int
schedule_flush_type(schedule_type* schedule, task_id id)
{
    ldns_rbnode_t *node, *nextnode;
    int nflushed = 0;
    
    ods_log_debug("[%s] flush task", schedule_str);
    if (!schedule || !schedule->tasks) return 0;

    pthread_mutex_lock(&schedule->schedule_lock);
        node = ldns_rbtree_first(schedule->tasks);
        while (node && node != LDNS_RBTREE_NULL) {
            nextnode = ldns_rbtree_next(node);
            if (node->data && ((task_type*)node->data)->what == id) {
                /* Merely setting flush is not enough. We must set it
                 * to the front of the queue as well. */
                node = ldns_rbtree_delete(schedule->tasks, node->data);
                if (!node) break; /* stange, bail out */
                if (node->data) { /* task */
                    ((task_type*)node->data)->flush = 1;
                    /* This is important for our tests only. If a task is
                     * set to flush it should not affect the current time.
                     * Otherwise timeleap will advance time. */
                    ((task_type*)node->data)->when = time_now();
                    if (!ldns_rbtree_insert(schedule->tasks, node)) {
                        ods_log_crit("[%s] Could not reschedule task "
                            "after flush. A task has been lost!",
                            schedule_str);
                        free(node);
                        /* Do not free node->data it is still in use
                         * by the other rbtree. */
                        break;
                    }
                    nflushed++;
                }
            }
            node = nextnode;
        }
        /* wakeup! work to do! */
        pthread_cond_signal(&schedule->schedule_cond);
    pthread_mutex_unlock(&schedule->schedule_lock);
    return nflushed;
}
Example #9
0
bool
ldns_dnssec_zone_is_nsec3_optout(ldns_dnssec_zone* zone)
{
	ldns_rr* nsec3;
	ldns_rbnode_t* node;

	if (ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_NSEC3PARAM)) {
		node = ldns_rbtree_first(zone->names);
		while (node != LDNS_RBTREE_NULL) {
			nsec3 = ((ldns_dnssec_name*)node->data)->nsec;
			if (nsec3 &&ldns_rr_get_type(nsec3) 
					== LDNS_RR_TYPE_NSEC3 &&
					ldns_nsec3_optout(nsec3)) {
				return true;
			}
			node = ldns_rbtree_next(node);
		}
	}
	return false;
}
Example #10
0
/**
 * pop the first scheduled task. Caller must hold
 * schedule->schedule_lock. Result is safe to use outside lock.
 * 
 * \param[in] schedule schedule
 * \return task_type* first scheduled task, NULL on no task or error.
 */
static task_type*
pop_first_task(schedule_type* schedule)
{
    ldns_rbnode_t *node, *delnode;
    task_type *task;

    if (!schedule || !schedule->tasks) return NULL;
    node = ldns_rbtree_first(schedule->tasks);
    if (!node) return NULL;
    delnode = ldns_rbtree_delete(schedule->tasks, node->data);
    /* delnode == node, but we don't free it just yet, data is shared
     * with tasks_by_name tree */
    if (!delnode) return NULL;
    delnode = ldns_rbtree_delete(schedule->tasks_by_name, node->data);
    free(node);
    if (!delnode) return NULL;
    task = (task_type*) delnode->data;
    free(delnode); /* this delnode != node */
    set_alarm(schedule);
    return task;
}
/**
 * Queue zone for signing.
 *
 */
static void
worker_queue_zone(worker_type* worker, fifoq_type* q, zone_type* zone)
{
    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
    domain_type* domain = NULL;
    ods_log_assert(worker);
    ods_log_assert(q);
    ods_log_assert(zone);
    worker_clear_jobs(worker);
    if (!zone->db || !zone->db->domains) {
        return;
    }
    if (zone->db->domains->root != LDNS_RBTREE_NULL) {
        node = ldns_rbtree_first(zone->db->domains);
    }
    while (node && node != LDNS_RBTREE_NULL) {
        domain = (domain_type*) node->data;
        worker_queue_domain(worker, q, domain);
        node = ldns_rbtree_next(node);
    }
    return;
}
/**
 * Make sure that all zones have been worked on at least once.
 *
 */
static int
engine_all_zones_processed(engine_type* engine)
{
    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
    zone_type* zone = NULL;

    ods_log_assert(engine);
    ods_log_assert(engine->zonelist);
    ods_log_assert(engine->zonelist->zones);

    node = ldns_rbtree_first(engine->zonelist->zones);
    while (node && node != LDNS_RBTREE_NULL) {
        zone = (zone_type*) node->key;
        ods_log_assert(zone);
        ods_log_assert(zone->db);
        if (!zone->db->is_processed) {
            return 0;
        }
        node = ldns_rbtree_next(node);
    }
    return 1;
}
Example #13
0
ldns_status
ldns_dnssec_zone_mark_glue(ldns_dnssec_zone *zone)
{
	ldns_rbnode_t *cur_node;
	ldns_dnssec_name *cur_name;
	ldns_rdf *cur_owner, *cur_parent;

	cur_node = ldns_rbtree_first(zone->names);
	while (cur_node != LDNS_RBTREE_NULL) {
		cur_name = (ldns_dnssec_name *) cur_node->data;
		cur_node = ldns_rbtree_next(cur_node);
		if (ldns_dnssec_name_has_only_a(cur_name)) {
			/* assume glue XXX check for zone cur */
			cur_owner = ldns_rdf_clone(ldns_rr_owner(
					      cur_name->rrsets->rrs->rr));
			while (ldns_dname_label_count(cur_owner) >
				  ldns_dname_label_count(zone->soa->name)) {
				if (ldns_dnssec_zone_find_rrset(zone,
										  cur_owner,
										  LDNS_RR_TYPE_NS)) {
					/*
					fprintf(stderr, "[XX] Marking as glue: ");
					ldns_rdf_print(stderr, cur_name->name);
					fprintf(stderr, "\n");
					*/
					cur_name->is_glue = true;
				}
				cur_parent = ldns_dname_left_chop(cur_owner);
				ldns_rdf_deep_free(cur_owner);
				cur_owner = cur_parent;
			}
			ldns_rdf_deep_free(cur_owner);
		}
	}
	return LDNS_STATUS_OK;
}
Example #14
0
void
schedule_flush(schedule_type* schedule)
{
    ldns_rbnode_t* node;
    task_type* task;
    
    ods_log_debug("[%s] flush all tasks", schedule_str);
    if (!schedule || !schedule->tasks) return;

    pthread_mutex_lock(&schedule->schedule_lock);
        node = ldns_rbtree_first(schedule->tasks);
        while (node && node != LDNS_RBTREE_NULL) {
            task = (task_type*) node->data;
            /*
             * TODO BUG? schedule_flush_type() sets when to zero, this does not.
             * Whos right and whos wrong?
             */
            task->flush = 1;
            node = ldns_rbtree_next(node);
        }
        /* wakeup! work to do! */
        pthread_cond_signal(&schedule->schedule_cond);
    pthread_mutex_unlock(&schedule->schedule_lock);
}
Example #15
0
ldns_status
ldns_dnssec_zone_create_nsecs(ldns_dnssec_zone *zone,
                              ldns_rr_list *new_rrs)
{

	ldns_rbnode_t *first_node, *cur_node, *next_node;
	ldns_dnssec_name *cur_name, *next_name;
	ldns_rr *nsec_rr;
	uint32_t nsec_ttl;
	ldns_dnssec_rrsets *soa;
	
	/* the TTL of NSEC rrs should be set to the minimum TTL of
	 * the zone SOA (RFC4035 Section 2.3)
	 */
	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
	
	/* did the caller actually set it? if not,
	 * fall back to default ttl
	 */
	if (soa && soa->rrs && soa->rrs->rr) {
		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
		                                     soa->rrs->rr, 6));
	} else {
		nsec_ttl = LDNS_DEFAULT_TTL;
	}
	
	first_node = ldns_dnssec_name_node_next_nonglue(
			       ldns_rbtree_first(zone->names));
	cur_node = first_node;
	if (cur_node) {
		next_node = ldns_dnssec_name_node_next_nonglue(
			           ldns_rbtree_next(cur_node));
	} else {
		next_node = NULL;
	}

	while (cur_node && next_node) {
		cur_name = (ldns_dnssec_name *)cur_node->data;
		next_name = (ldns_dnssec_name *)next_node->data;
		nsec_rr = ldns_dnssec_create_nsec(cur_name,
		                                  next_name,
		                                  LDNS_RR_TYPE_NSEC);
		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
		ldns_dnssec_name_add_rr(cur_name, nsec_rr);
		ldns_rr_list_push_rr(new_rrs, nsec_rr);
		cur_node = next_node;
		if (cur_node) {
			next_node = ldns_dnssec_name_node_next_nonglue(
                               ldns_rbtree_next(cur_node));
		}
	}

	if (cur_node && !next_node) {
		cur_name = (ldns_dnssec_name *)cur_node->data;
		next_name = (ldns_dnssec_name *)first_node->data;
		nsec_rr = ldns_dnssec_create_nsec(cur_name,
		                                  next_name,
		                                  LDNS_RR_TYPE_NSEC);
		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
		ldns_dnssec_name_add_rr(cur_name, nsec_rr);
		ldns_rr_list_push_rr(new_rrs, nsec_rr);
	} else {
		printf("error\n");
	}

	return LDNS_STATUS_OK;
}
Example #16
0
/**
 * Marks the names in the zone that are occluded. Those names will be skipped
 * when walking the tree with the ldns_dnssec_name_node_next_nonglue()
 * function. But watch out! Names that are partially occluded (like glue with
 * the same name as the delegation) will not be marked and should specifically 
 * be taken into account separately.
 *
 * When glue_list is given (not NULL), in the process of marking the names, all
 * glue resource records will be pushed to that list, even glue at delegation names.
 *
 * \param[in] zone the zone in which to mark the names
 * \param[in] glue_list the list to which to push the glue rrs
 * \return LDNS_STATUS_OK on success, an error code otherwise
 */
ldns_status
ldns_dnssec_zone_mark_and_get_glue(ldns_dnssec_zone *zone, 
	ldns_rr_list *glue_list)
{
	ldns_rbnode_t    *node;
	ldns_dnssec_name *name;
	ldns_rdf         *owner;
	ldns_rdf         *cut = NULL; /* keeps track of zone cuts */
	/* When the cut is caused by a delegation, below_delegation will be 1.
	 * When caused by a DNAME, below_delegation will be 0.
	 */
	int below_delegation = -1; /* init suppresses comiler warning */
	ldns_status s;

	if (!zone || !zone->names) {
		return LDNS_STATUS_NULL;
	}
	for (node = ldns_rbtree_first(zone->names); 
			node != LDNS_RBTREE_NULL; 
			node = ldns_rbtree_next(node)) {
		name = (ldns_dnssec_name *) node->data;
		owner = ldns_dnssec_name_name(name);

		if (cut) { 
			/* The previous node was a zone cut, or a subdomain
			 * below a zone cut. Is this node (still) a subdomain
			 * below the cut? Then the name is occluded. Unless
			 * the name contains a SOA, after which we are 
			 * authoritative again.
			 *
			 * FIXME! If there are labels in between the SOA and
			 * the cut, going from the authoritative space (below
			 * the SOA) up into occluded space again, will not be
			 * detected with the contruct below!
			 */
			if (ldns_dname_is_subdomain(owner, cut) &&
					!ldns_dnssec_rrsets_contains_type(
					name->rrsets, LDNS_RR_TYPE_SOA)) {

				if (below_delegation && glue_list) {
					s = ldns_dnssec_addresses_on_glue_list(
						name->rrsets, glue_list);
					if (s != LDNS_STATUS_OK) {
						return s;
					}
				}
				name->is_glue = true; /* Mark occluded name! */
				continue;
			} else {
				cut = NULL;
			}
		}

		/* The node is not below a zone cut. Is it a zone cut itself?
		 * Everything below a SOA is authoritative of course; Except
		 * when the name also contains a DNAME :).
		 */
		if (ldns_dnssec_rrsets_contains_type(
				name->rrsets, LDNS_RR_TYPE_NS)
			    && !ldns_dnssec_rrsets_contains_type(
				name->rrsets, LDNS_RR_TYPE_SOA)) {
			cut = owner;
			below_delegation = 1;
			if (glue_list) { /* record glue on the zone cut */
				s = ldns_dnssec_addresses_on_glue_list(
					name->rrsets, glue_list);
				if (s != LDNS_STATUS_OK) {
					return s;
				}
			}
		} else if (ldns_dnssec_rrsets_contains_type(
				name->rrsets, LDNS_RR_TYPE_DNAME)) {
			cut = owner;
			below_delegation = 0;
		}
	}
	return LDNS_STATUS_OK;
}
Example #17
0
static ldns_status
ldns_dnssec_zone_create_nsec3s_mkmap(ldns_dnssec_zone *zone,
		ldns_rr_list *new_rrs,
		uint8_t algorithm,
		uint8_t flags,
		uint16_t iterations,
		uint8_t salt_length,
		uint8_t *salt,
		ldns_rbtree_t **map)
{
	ldns_rbnode_t *first_name_node;
	ldns_rbnode_t *current_name_node;
	ldns_dnssec_name *current_name;
	ldns_status result = LDNS_STATUS_OK;
	ldns_rr *nsec_rr;
	ldns_rr_list *nsec3_list;
	uint32_t nsec_ttl;
	ldns_dnssec_rrsets *soa;
	ldns_rbnode_t *hashmap_node;

	if (!zone || !new_rrs || !zone->names) {
		return LDNS_STATUS_ERR;
	}

	/* the TTL of NSEC rrs should be set to the minimum TTL of
	 * the zone SOA (RFC4035 Section 2.3)
	 */
	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);

	/* did the caller actually set it? if not,
	 * fall back to default ttl
	 */
	if (soa && soa->rrs && soa->rrs->rr
			&& ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
	} else {
		nsec_ttl = LDNS_DEFAULT_TTL;
	}

	if (zone->hashed_names) {
		ldns_traverse_postorder(zone->hashed_names,
				ldns_hashed_names_node_free, NULL);
		LDNS_FREE(zone->hashed_names);
	}
	zone->hashed_names = ldns_rbtree_create(ldns_dname_compare_v);
	if (zone->hashed_names && map) {
		*map = zone->hashed_names;
	}

	first_name_node = ldns_dnssec_name_node_next_nonglue(
					  ldns_rbtree_first(zone->names));

	current_name_node = first_name_node;

	while (current_name_node && current_name_node != LDNS_RBTREE_NULL &&
			result == LDNS_STATUS_OK) {

		current_name = (ldns_dnssec_name *) current_name_node->data;
		nsec_rr = ldns_dnssec_create_nsec3(current_name,
		                                   NULL,
		                                   zone->soa->name,
		                                   algorithm,
		                                   flags,
		                                   iterations,
		                                   salt_length,
		                                   salt);
		/* by default, our nsec based generator adds rrsigs
		 * remove the bitmap for empty nonterminals */
		if (!current_name->rrsets) {
			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
		}
		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
		result = ldns_dnssec_name_add_rr(current_name, nsec_rr);
		ldns_rr_list_push_rr(new_rrs, nsec_rr);
		if (ldns_rr_owner(nsec_rr)) {
			hashmap_node = LDNS_MALLOC(ldns_rbnode_t);
			if (hashmap_node == NULL) {
				return LDNS_STATUS_MEM_ERR;
			}
			current_name->hashed_name = 
				ldns_dname_label(ldns_rr_owner(nsec_rr), 0);

			if (current_name->hashed_name == NULL) {
				LDNS_FREE(hashmap_node);
				return LDNS_STATUS_MEM_ERR;
			}
			hashmap_node->key  = current_name->hashed_name;
			hashmap_node->data = current_name;

			if (! ldns_rbtree_insert(zone->hashed_names
						, hashmap_node)) {
				LDNS_FREE(hashmap_node);
			}
		}
		current_name_node = ldns_dnssec_name_node_next_nonglue(
		                   ldns_rbtree_next(current_name_node));
	}
	if (result != LDNS_STATUS_OK) {
		return result;
	}

	/* Make sorted list of nsec3s (via zone->hashed_names)
	 */
	nsec3_list = ldns_rr_list_new();
	if (nsec3_list == NULL) {
		return LDNS_STATUS_MEM_ERR;
	}
	for ( hashmap_node  = ldns_rbtree_first(zone->hashed_names)
	    ; hashmap_node != LDNS_RBTREE_NULL
	    ; hashmap_node  = ldns_rbtree_next(hashmap_node)
	    ) {
		current_name = (ldns_dnssec_name *) hashmap_node->data;
		nsec_rr = ((ldns_dnssec_name *) hashmap_node->data)->nsec;
		if (nsec_rr) {
			ldns_rr_list_push_rr(nsec3_list, nsec_rr);
		}
	}
	result = ldns_dnssec_chain_nsec3_list(nsec3_list);
	ldns_rr_list_free(nsec3_list);

	return result;
}
Example #18
0
static int MV_SHM_free_all_node(shm_free_t *shm)
{
	int i = 0;
	int frist = 0;
	ldns_rbnode_t *node;
	shm_address_t *tmp;
	uint middle1, middle2, middle_size;

	shm->flag = 0;
	shm->node = NULL;

    MV_SHM_Print("SHM:FREE:START:%d\n", __LINE__);
    MV_SHM_Dump_Node(&shm->shm_root->m_phyaddr_root);
    MV_SHM_Dump_Node(&shm->shm_root->m_virtaddr_root);
	node = ldns_rbtree_first(&shm->shm_root->m_phyaddr_root);
	while (node != LDNS_RBTREE_NULL) {
		tmp = (shm_address_t *)(node->key);
		node = ldns_rbtree_next(node);

		middle1 = tmp->m_phyaddress + tmp->m_size/2;
		middle2 = shm->address + shm->size/2;
		middle_size = (tmp->m_size + shm->size)/2;
		if (middle1 > middle2)
			middle1 = middle1 - middle2;
		else
			middle1 = middle2 - middle1;

		if (middle1 < middle_size) {
			MV_SHM_Print("MV_SHM_free_all_node No.[%d], root[%p]"
				" Node_phys[%08x] Node_virt[%08x] Node_size[%08x]"
				" address[%08x] size[%08x]\n",
				i, tmp, tmp->m_phyaddress, tmp->m_virtaddress,
				tmp->m_size, shm->address, shm->size);
			i++;
			if ((tmp->m_phyaddress == shm->address)
				&& (tmp->m_size == shm->size)
				&& (shm->flag == 0)) {
				shm->flag = 1;
				if ((shm->node != NULL) && (frist == 1))
					free(shm->node);
				shm->node = tmp;
			} else {
				if (MV_SHM_Munmap_Base(tmp->m_virtaddress,
					tmp->m_size, shm->mem_type) == 0) {
					MV_SHM_delete_phyaddress_node(
                                            &shm->shm_root->m_phyaddr_root, tmp);
					MV_SHM_delete_virtaddress_node(
                                            &shm->shm_root->m_virtaddr_root, tmp);

					if ((frist == 0) && (shm->flag == 0)) {
						frist = 1;
						shm->node = tmp;
					} else {
						free(tmp);
					}
				}
			}
		}
	}
    MV_SHM_Print("SHM:FREE:END:%d\n", __LINE__);
    MV_SHM_Dump_Node(&shm->shm_root->m_phyaddr_root);
    MV_SHM_Dump_Node(&shm->shm_root->m_virtaddr_root);
	return 0;
}
Example #19
0
ldns_status
ldns_dnssec_zone_add_empty_nonterminals(ldns_dnssec_zone *zone)
{
	ldns_dnssec_name *new_name;
	ldns_rdf *cur_name;
	ldns_rdf *next_name;
	ldns_rbnode_t *cur_node, *next_node, *new_node;

	/* for the detection */
	uint16_t i, cur_label_count, next_label_count;
	uint16_t soa_label_count = 0;
	ldns_rdf *l1, *l2;
	int lpos;

	if (!zone) {
		return LDNS_STATUS_ERR;
	}
	if (zone->soa && zone->soa->name) {
		soa_label_count = ldns_dname_label_count(zone->soa->name);
	}
	
	cur_node = ldns_rbtree_first(zone->names);
	while (cur_node != LDNS_RBTREE_NULL) {
		next_node = ldns_rbtree_next(cur_node);
		
		/* skip glue */
		while (next_node != LDNS_RBTREE_NULL && 
		       next_node->data &&
		       ((ldns_dnssec_name *)next_node->data)->is_glue
		) {
			next_node = ldns_rbtree_next(next_node);
		}

		if (next_node == LDNS_RBTREE_NULL) {
			next_node = ldns_rbtree_first(zone->names);
		}
		if (! cur_node->data || ! next_node->data) {
			return LDNS_STATUS_ERR;
		}
		cur_name = ((ldns_dnssec_name *)cur_node->data)->name;
		next_name = ((ldns_dnssec_name *)next_node->data)->name;
		cur_label_count = ldns_dname_label_count(cur_name);
		next_label_count = ldns_dname_label_count(next_name);

		/* Since the names are in canonical order, we can
		 * recognize empty non-terminals by their labels;
		 * every label after the first one on the next owner
		 * name is a non-terminal if it either does not exist
		 * in the current name or is different from the same
		 * label in the current name (counting from the end)
		 */
		for (i = 1; i < next_label_count - soa_label_count; i++) {
			lpos = (int)cur_label_count - (int)next_label_count + (int)i;
			if (lpos >= 0) {
				l1 = ldns_dname_clone_from(cur_name, (uint8_t)lpos);
			} else {
				l1 = NULL;
			}
			l2 = ldns_dname_clone_from(next_name, i);

			if (!l1 || ldns_dname_compare(l1, l2) != 0) {
				/* We have an empty nonterminal, add it to the
				 * tree
				 */
				new_name = ldns_dnssec_name_new();
				if (!new_name) {
					return LDNS_STATUS_MEM_ERR;
				}
				new_name->name = ldns_dname_clone_from(next_name,
				                                       i);
				if (!new_name->name) {
					ldns_dnssec_name_free(new_name);
					return LDNS_STATUS_MEM_ERR;
				}
				new_name->name_alloced = true;
				new_node = LDNS_MALLOC(ldns_rbnode_t);
				if (!new_node) {
					ldns_dnssec_name_free(new_name);
					return LDNS_STATUS_MEM_ERR;
				}
				new_node->key = new_name->name;
				new_node->data = new_name;
				(void)ldns_rbtree_insert(zone->names, new_node);
				ldns_dnssec_name_make_hashed_name(
						zone, new_name, NULL);
			}
			ldns_rdf_deep_free(l1);
			ldns_rdf_deep_free(l2);
		}
		
		/* we might have inserted a new node after
		 * the current one so we can't just use next()
		 */
		if (next_node != ldns_rbtree_first(zone->names)) {
			cur_node = next_node;
		} else {
			cur_node = LDNS_RBTREE_NULL;
		}
	}
	return LDNS_STATUS_OK;
}
Example #20
0
ldns_status
ldns_dnssec_zone_create_rrsigs_flg( ldns_dnssec_zone *zone
				  , ldns_rr_list *new_rrs
				  , ldns_key_list *key_list
				  , int (*func)(ldns_rr *, void*)
				  , void *arg
				  , int flags
				  )
{
	ldns_status result = LDNS_STATUS_OK;

	ldns_rbnode_t *cur_node;
	ldns_rr_list *rr_list;

	ldns_dnssec_name *cur_name;
	ldns_dnssec_rrsets *cur_rrset;
	ldns_dnssec_rrs *cur_rr;

	ldns_rr_list *siglist;

	size_t i;

	int on_delegation_point = 0; /* handle partially occluded names */

	ldns_rr_list *pubkey_list = ldns_rr_list_new();
	for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
		ldns_rr_list_push_rr( pubkey_list
				    , ldns_key2rr(ldns_key_list_key(
							key_list, i))
				    );
	}
	/* TODO: callback to see is list should be signed */
	/* TODO: remove 'old' signatures from signature list */
	cur_node = ldns_rbtree_first(zone->names);
	while (cur_node != LDNS_RBTREE_NULL) {
		cur_name = (ldns_dnssec_name *) cur_node->data;

		if (!cur_name->is_glue) {
			on_delegation_point = ldns_dnssec_rrsets_contains_type(
					cur_name->rrsets, LDNS_RR_TYPE_NS)
				&& !ldns_dnssec_rrsets_contains_type(
					cur_name->rrsets, LDNS_RR_TYPE_SOA);
			cur_rrset = cur_name->rrsets;
			while (cur_rrset) {
				/* reset keys to use */
				ldns_key_list_set_use(key_list, true);

				/* walk through old sigs, remove the old,
				   and mark which keys (not) to use) */
				cur_rrset->signatures =
					ldns_dnssec_remove_signatures(cur_rrset->signatures,
											key_list,
											func,
											arg);
				if(!(flags&LDNS_SIGN_DNSKEY_WITH_ZSK) &&
					cur_rrset->type == LDNS_RR_TYPE_DNSKEY)
					ldns_key_list_filter_for_dnskey(key_list);

				if(cur_rrset->type != LDNS_RR_TYPE_DNSKEY)
					ldns_key_list_filter_for_non_dnskey(key_list);

				/* TODO: just set count to zero? */
				rr_list = ldns_rr_list_new();

				cur_rr = cur_rrset->rrs;
				while (cur_rr) {
					ldns_rr_list_push_rr(rr_list, cur_rr->rr);
					cur_rr = cur_rr->next;
				}

				/* only sign non-delegation RRsets */
				/* (glue should have been marked earlier, 
				 *  except on the delegation points itself) */
				if (!on_delegation_point ||
						ldns_rr_list_type(rr_list) 
							== LDNS_RR_TYPE_DS ||
						ldns_rr_list_type(rr_list) 
							== LDNS_RR_TYPE_NSEC ||
						ldns_rr_list_type(rr_list) 
							== LDNS_RR_TYPE_NSEC3) {
					siglist = ldns_sign_public(rr_list, key_list);
					for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
						if (cur_rrset->signatures) {
							result = ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
											   ldns_rr_list_rr(siglist,
														    i));
						} else {
							cur_rrset->signatures = ldns_dnssec_rrs_new();
							cur_rrset->signatures->rr =
								ldns_rr_list_rr(siglist, i);
						}
						if (new_rrs) {
							ldns_rr_list_push_rr(new_rrs,
												 ldns_rr_list_rr(siglist,
															  i));
						}
					}
					ldns_rr_list_free(siglist);
				}

				ldns_rr_list_free(rr_list);

				cur_rrset = cur_rrset->next;
			}

			/* sign the nsec */
			ldns_key_list_set_use(key_list, true);
			cur_name->nsec_signatures =
				ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
										key_list,
										func,
										arg);
			ldns_key_list_filter_for_non_dnskey(key_list);

			rr_list = ldns_rr_list_new();
			ldns_rr_list_push_rr(rr_list, cur_name->nsec);
			siglist = ldns_sign_public(rr_list, key_list);

			for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
				if (cur_name->nsec_signatures) {
					result = ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
									   ldns_rr_list_rr(siglist, i));
				} else {
					cur_name->nsec_signatures = ldns_dnssec_rrs_new();
					cur_name->nsec_signatures->rr =
						ldns_rr_list_rr(siglist, i);
				}
				if (new_rrs) {
					ldns_rr_list_push_rr(new_rrs,
								 ldns_rr_list_rr(siglist, i));
				}
			}

			ldns_rr_list_free(siglist);
			ldns_rr_list_free(rr_list);
		}
		cur_node = ldns_rbtree_next(cur_node);
	}

	ldns_rr_list_deep_free(pubkey_list);
	return result;
}
Example #21
0
ldns_status
ldns_dnssec_zone_create_nsec3s(ldns_dnssec_zone *zone,
						 ldns_rr_list *new_rrs,
						 uint8_t algorithm,
						 uint8_t flags,
						 uint16_t iterations,
						 uint8_t salt_length,
						 uint8_t *salt)
{
	ldns_rbnode_t *first_name_node;
	ldns_rbnode_t *current_name_node;
	ldns_dnssec_name *current_name;
	ldns_status result = LDNS_STATUS_OK;
	ldns_rr *nsec_rr;
	ldns_rr_list *nsec3_list;
	uint32_t nsec_ttl;
	ldns_dnssec_rrsets *soa;
	
	if (!zone || !new_rrs || !zone->names) {
		return LDNS_STATUS_ERR;
	}
	
	/* the TTL of NSEC rrs should be set to the minimum TTL of
	 * the zone SOA (RFC4035 Section 2.3)
	 */
	soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
	
	/* did the caller actually set it? if not,
	 * fall back to default ttl
	 */
	if (soa && soa->rrs && soa->rrs->rr) {
		nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(
		                                     soa->rrs->rr, 6));
	} else {
		nsec_ttl = LDNS_DEFAULT_TTL;
	}

	nsec3_list = ldns_rr_list_new();

	first_name_node = ldns_dnssec_name_node_next_nonglue(
					  ldns_rbtree_first(zone->names));
	
	current_name_node = first_name_node;

	while (current_name_node &&
	       current_name_node != LDNS_RBTREE_NULL) {
		current_name = (ldns_dnssec_name *) current_name_node->data;
		nsec_rr = ldns_dnssec_create_nsec3(current_name,
		                                   NULL,
		                                   zone->soa->name,
		                                   algorithm,
		                                   flags,
		                                   iterations,
		                                   salt_length,
		                                   salt);
		/* by default, our nsec based generator adds rrsigs
		 * remove the bitmap for empty nonterminals */
		if (!current_name->rrsets) {
			ldns_rdf_deep_free(ldns_rr_pop_rdf(nsec_rr));
		}
		ldns_rr_set_ttl(nsec_rr, nsec_ttl);
		ldns_dnssec_name_add_rr(current_name, nsec_rr);
		ldns_rr_list_push_rr(new_rrs, nsec_rr);
		ldns_rr_list_push_rr(nsec3_list, nsec_rr);
		current_name_node = ldns_dnssec_name_node_next_nonglue(
		                   ldns_rbtree_next(current_name_node));
	}

	ldns_rr_list_sort_nsec3(nsec3_list);
	ldns_dnssec_chain_nsec3_list(nsec3_list);
	if (result != LDNS_STATUS_OK) {
		return result;
	}
	
	ldns_rr_list_free(nsec3_list);
	return result;
}
/**
 * Try to recover from the backup files.
 *
 */
static ods_status
engine_recover(engine_type* engine)
{
    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
    zone_type* zone = NULL;
    ods_status status = ODS_STATUS_OK;
    ods_status result = ODS_STATUS_UNCHANGED;

    if (!engine || !engine->zonelist || !engine->zonelist->zones) {
        ods_log_error("[%s] cannot recover zones: no engine or zonelist",
            engine_str);
        return ODS_STATUS_ERR; /* no need to update zones */
    }
    ods_log_assert(engine);
    ods_log_assert(engine->zonelist);
    ods_log_assert(engine->zonelist->zones);

    lock_basic_lock(&engine->zonelist->zl_lock);
    /* [LOCK] zonelist */
    node = ldns_rbtree_first(engine->zonelist->zones);
    while (node && node != LDNS_RBTREE_NULL) {
        zone = (zone_type*) node->data;

        ods_log_assert(zone->zl_status == ZONE_ZL_ADDED);
        status = zone_recover2(zone);
        if (status == ODS_STATUS_OK) {
            ods_log_assert(zone->task);
            ods_log_assert(zone->db);
            ods_log_assert(zone->signconf);
            /* notify nameserver */
            if (engine->config->notify_command && !zone->notify_ns) {
                set_notify_ns(zone, engine->config->notify_command);
            }
            /* schedule task */
            lock_basic_lock(&engine->taskq->schedule_lock);
            /* [LOCK] schedule */
            status = schedule_task(engine->taskq, (task_type*) zone->task, 0);
            /* [UNLOCK] schedule */
            lock_basic_unlock(&engine->taskq->schedule_lock);

            if (status != ODS_STATUS_OK) {
                ods_log_crit("[%s] unable to schedule task for zone %s: %s",
                    engine_str, zone->name, ods_status2str(status));
                task_cleanup((task_type*) zone->task);
                zone->task = NULL;
                result = ODS_STATUS_OK; /* will trigger update zones */
            } else {
                ods_log_debug("[%s] recovered zone %s", engine_str,
                    zone->name);
                /* recovery done */
                zone->zl_status = ZONE_ZL_OK;
            }
        } else {
            if (status != ODS_STATUS_UNCHANGED) {
                ods_log_warning("[%s] unable to recover zone %s from backup,"
                " performing full sign", engine_str, zone->name);
            }
            result = ODS_STATUS_OK; /* will trigger update zones */
        }
        node = ldns_rbtree_next(node);
    }
    /* [UNLOCK] zonelist */
    lock_basic_unlock(&engine->zonelist->zl_lock);
    return result;
}
/**
 * Update zones.
 *
 */
void
engine_update_zones(engine_type* engine, ods_status zl_changed)
{
    ldns_rbnode_t* node = LDNS_RBTREE_NULL;
    zone_type* zone = NULL;
    zone_type* delzone = NULL;
    task_type* task = NULL;
    ods_status status = ODS_STATUS_OK;
    unsigned wake_up = 0;
    int warnings = 0;
    time_t now = 0;

    if (!engine || !engine->zonelist || !engine->zonelist->zones) {
        return;
    }
    now = time_now();

    ods_log_debug("[%s] commit zone list changes", engine_str);
    lock_basic_lock(&engine->zonelist->zl_lock);
    node = ldns_rbtree_first(engine->zonelist->zones);
    while (node && node != LDNS_RBTREE_NULL) {
        zone = (zone_type*) node->data;
        task = NULL; /* reset task */

        if (zone->zl_status == ZONE_ZL_REMOVED) {
            node = ldns_rbtree_next(node);
            lock_basic_lock(&zone->zone_lock);
            delzone = zonelist_del_zone(engine->zonelist, zone);
            if (delzone) {
                lock_basic_lock(&engine->taskq->schedule_lock);
                task = unschedule_task(engine->taskq,
                    (task_type*) zone->task);
                lock_basic_unlock(&engine->taskq->schedule_lock);
            }
            task_cleanup(task);
            task = NULL;
            lock_basic_unlock(&zone->zone_lock);
            netio_remove_handler(engine->xfrhandler->netio,
                &zone->xfrd->handler);
            zone_cleanup(zone);
            zone = NULL;
            continue;
        } else if (zone->zl_status == ZONE_ZL_ADDED) {
            lock_basic_lock(&zone->zone_lock);
            ods_log_assert(!zone->task);
            /* set notify nameserver command */
            if (engine->config->notify_command && !zone->notify_ns) {
                set_notify_ns(zone, engine->config->notify_command);
            }
            /* create task */
            task = task_create(TASK_SIGNCONF, now, zone);
            lock_basic_unlock(&zone->zone_lock);
            if (!task) {
                ods_log_crit("[%s] unable to create task for zone %s: "
                    "task_create() failed", engine_str, zone->name);
                node = ldns_rbtree_next(node);
                continue;
            }
        }
        /* load adapter config */
        status = adapter_load_config(zone->adinbound);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] unable to load config for inbound adapter "
                "for zone %s: %s", engine_str, zone->name,
                ods_status2str(status));
        }
        status = adapter_load_config(zone->adoutbound);
        if (status != ODS_STATUS_OK) {
            ods_log_error("[%s] unable to load config for outbound adapter "
                "for zone %s: %s", engine_str, zone->name,
                ods_status2str(status));
        }
        /* for dns adapters */
        warnings += dnsconfig_zone(engine, zone);

        if (zone->zl_status == ZONE_ZL_ADDED) {
            ods_log_assert(task);
            lock_basic_lock(&zone->zone_lock);
            zone->task = task;
            lock_basic_unlock(&zone->zone_lock);
            lock_basic_lock(&engine->taskq->schedule_lock);
            status = schedule_task(engine->taskq, task, 0);
            lock_basic_unlock(&engine->taskq->schedule_lock);
        } else if (zl_changed == ODS_STATUS_OK) {
            /* always try to update signconf */
            lock_basic_lock(&zone->zone_lock);
            status = zone_reschedule_task(zone, engine->taskq, TASK_SIGNCONF);
            lock_basic_unlock(&zone->zone_lock);
        }
        if (status != ODS_STATUS_OK) {
            ods_log_crit("[%s] unable to schedule task for zone %s: %s",
                engine_str, zone->name, ods_status2str(status));
        } else {
            wake_up = 1;
            zone->zl_status = ZONE_ZL_OK;
        }
        node = ldns_rbtree_next(node);
    }
    lock_basic_unlock(&engine->zonelist->zl_lock);
    if (engine->dnshandler) {
        dnshandler_fwd_notify(engine->dnshandler,
            (uint8_t*) ODS_SE_NOTIFY_CMD, strlen(ODS_SE_NOTIFY_CMD));
    } else if (warnings) {
        ods_log_warning("[%s] no dnshandler/listener configured, but zones "
         "are configured with dns adapters: notify and zone transfer "
         "requests will not work properly", engine_str);
    }
    if (wake_up) {
        engine_wakeup_workers(engine);
    }
    return;
}
Example #24
0
ldns_status
ldns_dnssec_zone_create_rrsigs(ldns_dnssec_zone *zone,
                               ldns_rr_list *new_rrs,
                               ldns_key_list *key_list,
                               int (*func)(ldns_rr *, void*),
                               void *arg)
{
	ldns_status result = LDNS_STATUS_OK;

	ldns_rbnode_t *cur_node;
	ldns_rr_list *rr_list;

	ldns_dnssec_name *cur_name;
	ldns_dnssec_rrsets *cur_rrset;
	ldns_dnssec_rrs *cur_rr;

	ldns_rr_list *siglist;
	
	size_t i;

	ldns_rr_list *pubkey_list = ldns_rr_list_new();
	zone = zone;
	new_rrs = new_rrs;
	key_list = key_list;
	for (i = 0; i<ldns_key_list_key_count(key_list); i++) {
		ldns_rr_list_push_rr(pubkey_list,
						 ldns_key2rr(ldns_key_list_key(key_list, i)));
	}
	/* TODO: callback to see is list should be signed */
	/* TODO: remove 'old' signatures from signature list */
	cur_node = ldns_rbtree_first(zone->names);
	while (cur_node != LDNS_RBTREE_NULL) {
		cur_name = (ldns_dnssec_name *) cur_node->data;

		if (!cur_name->is_glue) {
			cur_rrset = cur_name->rrsets;
			while (cur_rrset) {
				/* reset keys to use */
				ldns_key_list_set_use(key_list, true);
				
				/* walk through old sigs, remove the old,
				   and mark which keys (not) to use) */
				cur_rrset->signatures =
					ldns_dnssec_remove_signatures(cur_rrset->signatures,
											key_list,
											func,
											arg);
				
				/* TODO: just set count to zero? */
				rr_list = ldns_rr_list_new();
				
				cur_rr = cur_rrset->rrs;
				while (cur_rr) {
					ldns_rr_list_push_rr(rr_list, cur_rr->rr);
					cur_rr = cur_rr->next;
				}
				
				/* only sign non-delegation RRsets */
				/* (glue should have been marked earlier) */
				if ((ldns_rr_list_type(rr_list) != LDNS_RR_TYPE_NS ||
					ldns_dname_compare(ldns_rr_list_owner(rr_list),
					zone->soa->name) == 0) &&
					/* OK, there is also the possibility that the record
					 * is glue, but at the same owner name as other records that
					 * are not NS nor A/AAAA. Bleh, our current data structure
					 * doesn't really support that... */
					!((ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_A ||
					 ldns_rr_list_type(rr_list) == LDNS_RR_TYPE_AAAA) &&
					 !ldns_dname_compare(ldns_rr_list_owner(rr_list), zone->soa->name) == 0 &&
					 ldns_dnssec_zone_find_rrset(zone, ldns_rr_list_owner(rr_list), LDNS_RR_TYPE_NS)
					 )) {

					siglist = ldns_sign_public(rr_list, key_list);
					for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
						if (cur_rrset->signatures) {
							ldns_dnssec_rrs_add_rr(cur_rrset->signatures,
											   ldns_rr_list_rr(siglist,
														    i));
						} else {
							cur_rrset->signatures = ldns_dnssec_rrs_new();
							cur_rrset->signatures->rr =
								ldns_rr_list_rr(siglist, i);
							ldns_rr_list_push_rr(new_rrs,
											 ldns_rr_list_rr(siglist,
														  i));
						}
					}
					ldns_rr_list_free(siglist);
				}
				
				ldns_rr_list_free(rr_list);
				
				cur_rrset = cur_rrset->next;
			}
			
			/* sign the nsec */
			cur_name->nsec_signatures =
				ldns_dnssec_remove_signatures(cur_name->nsec_signatures,
										key_list,
										func,
										arg);
			
			rr_list = ldns_rr_list_new();
			ldns_rr_list_push_rr(rr_list, cur_name->nsec);
			siglist = ldns_sign_public(rr_list, key_list);
			
			for (i = 0; i < ldns_rr_list_rr_count(siglist); i++) {
				if (cur_name->nsec_signatures) {
					ldns_dnssec_rrs_add_rr(cur_name->nsec_signatures,
									   ldns_rr_list_rr(siglist, i));
				} else {
					cur_name->nsec_signatures = ldns_dnssec_rrs_new();
					cur_name->nsec_signatures->rr =
						ldns_rr_list_rr(siglist, i);
					ldns_rr_list_push_rr(new_rrs,
									 ldns_rr_list_rr(siglist, i));
				}
			}
			
			ldns_rr_list_free(siglist);
			ldns_rr_list_free(rr_list);
		}
		cur_node = ldns_rbtree_next(cur_node);
	}

	ldns_rr_list_deep_free(pubkey_list);
	return result;
}
Example #25
0
/**
 * Merge zone lists.
 *
 */
static void
zonelist_merge(zonelist_type* zl1, zonelist_type* zl2)
{
    zone_type* z1 = NULL;
    zone_type* z2 = NULL;
    ldns_rbnode_t* n1 = LDNS_RBTREE_NULL;
    ldns_rbnode_t* n2 = LDNS_RBTREE_NULL;
    int ret = 0;

    ods_log_assert(zl1);
    ods_log_assert(zl2);
    ods_log_assert(zl1->zones);
    ods_log_assert(zl2->zones);
    ods_log_debug("[%s] merge two zone lists", zl_str);

    n1 = ldns_rbtree_first(zl1->zones);
    n2 = ldns_rbtree_first(zl2->zones);
    while (n2 && n2 != LDNS_RBTREE_NULL) {
        z2 = (zone_type*) n2->data;
        if (n1 && n1 != LDNS_RBTREE_NULL) {
            z1 = (zone_type*) n1->data;
        } else {
            z1 = NULL;
        }
        if (!z2) {
            /* no more zones to merge into zl1 */
            return;
        } else if (!z1) {
            /* just add remaining zones from zl2 */
            z2 = zonelist_add_zone(zl1, z2);
            if (!z2) {
                ods_log_crit("[%s] merge failed: z2 not added", zl_str);
                return;
            }
            n2 = ldns_rbtree_next(n2);
        } else {
            /* compare the zones z1 and z2 */
            ret = zone_compare(z1, z2);
            if (ret < 0) {
                /* remove zone z1, it is not present in the new list zl2 */
                z1->zl_status = ZONE_ZL_REMOVED;
                zl1->just_removed++;
                n1 = ldns_rbtree_next(n1);
            } else if (ret > 0) {
                /* add the new zone z2 */
                z2 = zonelist_add_zone(zl1, z2);
                if (!z2) {
                    ods_log_crit("[%s] merge failed: z2 not added", zl_str);
                    return;
                }
                n2 = ldns_rbtree_next(n2);
            } else {
                /* just update zone z1 */
                n1 = ldns_rbtree_next(n1);
                n2 = ldns_rbtree_next(n2);
                zone_merge(z1, z2);
                zone_cleanup(z2);
                if (z1->zl_status == ZONE_ZL_UPDATED) {
                    zl1->just_updated++;
                }
                z1->zl_status = ZONE_ZL_UPDATED;
            }
        }
    }
    /* remove remaining zones from z1 */
    while (n1 && n1 != LDNS_RBTREE_NULL) {
        z1 = (zone_type*) n1->data;
        z1->zl_status = ZONE_ZL_REMOVED;
        zl1->just_removed++;
        n1 = ldns_rbtree_next(n1);
    }
    zl1->last_modified = zl2->last_modified;
    return;
}