Example #1
0
void dnscache_reset (dnscache_t *dnscache)
{
	size_t i;

	if (dnscache->records) {
		for (i = 0; i < dnscache->used; i++) {
			buffer_free (&(dnscache->records[i].name));

			rr_list_free (dnscache->records[i].rr_list, MAX_HOSTS);
			dnscache->records[i].nhosts = 0;
		}
	}

	dnscache->used = 0;
}
Example #2
0
void dnscache_free (dnscache_t *dnscache)
{
	size_t i;

	if (dnscache->records) {
		for (i = 0; i < dnscache->used; i++) {
			buffer_free (&(dnscache->records[i].name));
			rr_list_free (dnscache->records[i].rr_list, MAX_HOSTS);
		}

		free (dnscache->records);
		dnscache->records = NULL;
	}

	if (dnscache->index) {
		free (dnscache->index);
		dnscache->index = NULL;
	}

	dnscache->size = 0;
	dnscache->used = 0;
}
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;
}
Example #4
0
eDnsStatus dnscache_lookup (dnscache_t *dnscache, const char *dname, int type, size_t max_hosts, off_t *index, time_t current_time)
{
	dnscache_entry_t *record;
	rr_t *rr_list;
	buffer_t name;
	unsigned int position;
	int min_ttl;
	int lookup;
	size_t len;
	size_t i;

	if (max_hosts > MAX_HOSTS) {
		return DNS_ERROR;
	}

	if (search (dnscache, dname, type, &position) < 0) {
		/* DNS cache miss. */
		buffer_init (&name, 64);
		len = strlen (dname);
		if (buffer_allocate (&name, len + 1) < 0) {
			buffer_free (&name);
			return DNS_ERROR;
		}

		memcpy (name.data, dname, len + 1);
		name.used = len + 1;

		if (allocate (dnscache) < 0) {
			buffer_free (&name);
			return DNS_ERROR;
		}

		/* We might have emptied the cache. */
		if (dnscache->used == 0) {
			position = 0;
		}

		record = &(dnscache->records[dnscache->used]);

		memcpy (&record->name, &name, sizeof (buffer_t));
		record->type = type;
		record->timestamp = current_time;
		rr_list_init (record->rr_list, MAX_HOSTS);
		record->nhosts = 0;

		record->status = dns_lookup (dname, type, max_hosts, record->rr_list, &record->nhosts);

		*index = dnscache->used;

		if (position < dnscache->used) {
			memmove (&(dnscache->index[position + 1]), &(dnscache->index[position]), (dnscache->used - position) * sizeof (off_t));
		}

		dnscache->index[position] = dnscache->used++;

		return record->status;
	}

	*index = dnscache->index[position];
	record = &(dnscache->records[*index]);
	rr_list = record->rr_list;

	if ((record->status == DNS_HOST_NOT_FOUND) || (record->status == DNS_NO_DATA)) {
		if (record->timestamp + QUERY_MIN_INTERVAL >= current_time) {
			return record->status;
		}

		lookup = 1;
	} else if (record->status != DNS_SUCCESS) {
		lookup = 1;
	} else {
		/* Compute the minimum TTL. */
		min_ttl = rr_list[0].ttl;
		for (i = 1; i < record->nhosts; i++) {
			if (rr_list[i].ttl < min_ttl) {
				min_ttl = rr_list[i].ttl;
			}
		}

		/* If the TTL has already expired... */
		if (record->timestamp + min_ttl < current_time) {
			lookup = 1;
		} else {
			lookup = 0;
		}
	}

	if (lookup) {
		rr_list_free (rr_list, MAX_HOSTS);

		record->status = dns_lookup (dname, type, max_hosts, rr_list, &record->nhosts);
		record->timestamp = current_time;
	}

	return record->status;
}