Beispiel #1
0
/** dump message entry */
static int
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d, 
	time_t now)
{
	size_t i;
	char* nm, *tp, *cl;
	if(!k || !d) return 1;
	if(d->ttl < now) return 1; /* expired */
	
	nm = sldns_wire2str_dname(k->qname, k->qname_len);
	tp = sldns_wire2str_type(k->qtype);
	cl = sldns_wire2str_class(k->qclass);
	if(!nm || !tp || !cl) {
		free(nm);
		free(tp);
		free(cl);
		return 1; /* skip this entry */
	}
	if(!rrset_array_lock(d->ref, d->rrset_count, now)) {
		/* rrsets have timed out or do not exist */
		free(nm);
		free(tp);
		free(cl);
		return 1; /* skip this entry */
	}
	
	/* meta line */
	if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u\n",
			nm, cl, tp,
			(int)d->flags, (int)d->qdcount, 
			(long long)(d->ttl-now), (int)d->security,
			(unsigned)d->an_numrrsets, 
			(unsigned)d->ns_numrrsets,
			(unsigned)d->ar_numrrsets)) {
		free(nm);
		free(tp);
		free(cl);
		rrset_array_unlock(d->ref, d->rrset_count);
		return 0;
	}
	free(nm);
	free(tp);
	free(cl);
	
	for(i=0; i<d->rrset_count; i++) {
		if(!dump_msg_ref(ssl, d->rrsets[i])) {
			rrset_array_unlock(d->ref, d->rrset_count);
			return 0;
		}
	}
	rrset_array_unlock(d->ref, d->rrset_count);

	return 1;
}
Beispiel #2
0
struct dns_msg*
tomsg(struct module_env* env, struct query_info* q, struct reply_info* r, 
	struct regional* region, time_t now, struct regional* scratch)
{
	struct dns_msg* msg;
	size_t i;
	if(now > r->ttl)
		return NULL;
	msg = gen_dns_msg(region, q, r->rrset_count);
	if(!msg)
		return NULL;
	msg->rep->flags = r->flags;
	msg->rep->qdcount = r->qdcount;
	msg->rep->ttl = r->ttl - now;
	if(r->prefetch_ttl > now)
		msg->rep->prefetch_ttl = r->prefetch_ttl - now;
	else	msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
	msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
	msg->rep->security = r->security;
	msg->rep->an_numrrsets = r->an_numrrsets;
	msg->rep->ns_numrrsets = r->ns_numrrsets;
	msg->rep->ar_numrrsets = r->ar_numrrsets;
	msg->rep->rrset_count = r->rrset_count;
        msg->rep->authoritative = r->authoritative;
	if(!rrset_array_lock(r->ref, r->rrset_count, now))
		return NULL;
	if(r->an_numrrsets > 0 && (r->rrsets[0]->rk.type == htons(
		LDNS_RR_TYPE_CNAME) || r->rrsets[0]->rk.type == htons(
		LDNS_RR_TYPE_DNAME)) && !reply_check_cname_chain(q, r)) {
		/* cname chain is now invalid, reconstruct msg */
		rrset_array_unlock(r->ref, r->rrset_count);
		return NULL;
	}
	if(r->security == sec_status_secure && !reply_all_rrsets_secure(r)) {
		/* message rrsets have changed status, revalidate */
		rrset_array_unlock(r->ref, r->rrset_count);
		return NULL;
	}
	for(i=0; i<msg->rep->rrset_count; i++) {
		msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i], 
			region, now);
		if(!msg->rep->rrsets[i]) {
			rrset_array_unlock(r->ref, r->rrset_count);
			return NULL;
		}
	}
	if(env)
		rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref, 
		r->rrset_count);
	else
		rrset_array_unlock(r->ref, r->rrset_count);
	return msg;
}
Beispiel #3
0
/*  Invalidate the message associated with query_info stored in message cache */
void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo)
{ 
    hashvalue_t h;
    struct lruhash_entry* e;
    struct reply_info *r;
    size_t i, j;

    h = query_info_hash(qinfo, qstate->query_flags);
    if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0))) 
    {
	r = (struct reply_info*)(e->data);
	if (r) 
	{
	   r->ttl = 0;
	   if(rrset_array_lock(r->ref, r->rrset_count, *qstate->env->now)) {
		   for(i=0; i< r->rrset_count; i++) 
		   {
		       struct packed_rrset_data* data = 
		       	(struct packed_rrset_data*) r->ref[i].key->entry.data;
		       if(i>0 && r->ref[i].key == r->ref[i-1].key)
			   continue;
	      
		       data->ttl = r->ttl;
		       for(j=0; j<data->count + data->rrsig_count; j++)
			   data->rr_ttl[j] = r->ttl;
		   }
		   rrset_array_unlock(r->ref, r->rrset_count);
	   }
	}
	lock_rw_unlock(&e->lock);
    } else {
	log_info("invalidateQueryInCache: qinfo is not in cache");
    }
}
Beispiel #4
0
/** dump message entry */
static int
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d, 
	uint32_t now)
{
	size_t i;
	char* nm, *tp, *cl;
	ldns_rdf* rdf;
	ldns_status status;
	size_t pos;
	if(!k || !d) return 1;
	if(d->ttl < now) return 1; /* expired */
	
	pos = 0;
	status = ldns_wire2dname(&rdf, k->qname, k->qname_len, &pos);
	if(status != LDNS_STATUS_OK) {
		return 1; /* skip this entry */
	}
	nm = ldns_rdf2str(rdf);
	ldns_rdf_deep_free(rdf);
	tp = ldns_rr_type2str(k->qtype);
	cl = ldns_rr_class2str(k->qclass);
	if(!nm || !tp || !cl) {
		free(nm);
		free(tp);
		free(cl);
		return 1; /* skip this entry */
	}
	if(!rrset_array_lock(d->ref, d->rrset_count, now)) {
		/* rrsets have timed out or do not exist */
		free(nm);
		free(tp);
		free(cl);
		return 1; /* skip this entry */
	}
	
	/* meta line */
	if(!ssl_printf(ssl, "msg %s %s %s %d %d %u %d %u %u %u\n",
			nm, cl, tp,
			(int)d->flags, (int)d->qdcount, 
			(unsigned)(d->ttl-now), (int)d->security,
			(unsigned)d->an_numrrsets, 
			(unsigned)d->ns_numrrsets,
			(unsigned)d->ar_numrrsets)) {
		free(nm);
		free(tp);
		free(cl);
		rrset_array_unlock(d->ref, d->rrset_count);
		return 0;
	}
	free(nm);
	free(tp);
	free(cl);
	
	for(i=0; i<d->rrset_count; i++) {
		if(!dump_msg_ref(ssl, d->rrsets[i])) {
			rrset_array_unlock(d->ref, d->rrset_count);
			return 0;
		}
	}
	rrset_array_unlock(d->ref, d->rrset_count);

	return 1;
}