示例#1
0
/** load an RR into rrset */
static int
load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region,
	struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
	unsigned int i, int is_rrsig, int* go_on, time_t now)
{
	uint8_t rr[LDNS_RR_BUF_SIZE];
	size_t rr_len = sizeof(rr), dname_len = 0;
	int status;

	/* read the line */
	if(!ssl_read_buf(ssl, buf))
		return 0;
	if(strncmp((char*)sldns_buffer_begin(buf), "BADRR\n", 6) == 0) {
		*go_on = 0;
		return 1;
	}
	status = sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf), rr,
		&rr_len, &dname_len, 3600, NULL, 0, NULL, 0);
	if(status != 0) {
		log_warn("error cannot parse rr: %s: %s",
			sldns_get_errorstr_parse(status),
			(char*)sldns_buffer_begin(buf));
		return 0;
	}
	if(is_rrsig && sldns_wirerr_get_type(rr, rr_len, dname_len)
		!= LDNS_RR_TYPE_RRSIG) {
		log_warn("error expected rrsig but got %s",
			(char*)sldns_buffer_begin(buf));
		return 0;
	}

	/* convert ldns rr into packed_rr */
	d->rr_ttl[i] = (time_t)sldns_wirerr_get_ttl(rr, rr_len, dname_len) + now;
	sldns_buffer_clear(buf);
	d->rr_len[i] = sldns_wirerr_get_rdatalen(rr, rr_len, dname_len)+2;
	d->rr_data[i] = (uint8_t*)regional_alloc_init(region, 
		sldns_wirerr_get_rdatawl(rr, rr_len, dname_len), d->rr_len[i]);
	if(!d->rr_data[i]) {
		log_warn("error out of memory");
		return 0;
	}

	/* if first entry, fill the key structure */
	if(i==0) {
		rk->rk.type = htons(sldns_wirerr_get_type(rr, rr_len, dname_len));
		rk->rk.rrset_class = htons(sldns_wirerr_get_class(rr, rr_len, dname_len));
		rk->rk.dname_len = dname_len;
		rk->rk.dname = regional_alloc_init(region, rr, dname_len);
		if(!rk->rk.dname) {
			log_warn("error out of memory");
			return 0;
		}
	}

	return 1;
}
示例#2
0
/** load msg cache */
static int
load_msg_cache(SSL* ssl, struct worker* worker)
{
	sldns_buffer* buf = worker->env.scratch_buffer;
	if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
	while(ssl_read_buf(ssl, buf) && 
		strcmp((char*)sldns_buffer_begin(buf), "END_MSG_CACHE")!=0) {
		if(!load_msg(ssl, buf, worker))
			return 0;
	}
	return 1;
}
示例#3
0
/** load a msg rrset reference */
static int
load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker, 
	struct regional *region, struct ub_packed_rrset_key** rrset, 
	int* go_on)
{
	char* s = (char*)sldns_buffer_begin(buf);
	struct query_info qinfo;
	unsigned int flags;
	struct ub_packed_rrset_key* k;

	/* read line */
	if(!ssl_read_buf(ssl, buf))
		return 0;
	if(strncmp(s, "BADREF", 6) == 0) {
		*go_on = 0; /* its bad, skip it and skip message */
		return 1;
	}

	s = load_qinfo(s, &qinfo, region);
	if(!s) {
		return 0;
	}
	if(sscanf(s, " %u", &flags) != 1) {
		log_warn("error cannot parse flags: %s", s);
		return 0;
	}

	/* lookup in cache */
	k = rrset_cache_lookup(worker->env.rrset_cache, qinfo.qname,
		qinfo.qname_len, qinfo.qtype, qinfo.qclass,
		(uint32_t)flags, *worker->env.now, 0);
	if(!k) {
		/* not found or expired */
		*go_on = 0;
		return 1;
	}

	/* store in result */
	*rrset = packed_rrset_copy_region(k, region, *worker->env.now);
	lock_rw_unlock(&k->entry.lock);

	return (*rrset != NULL);
}
示例#4
0
/** check fixed text on line */
static int
read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
{
	if(!ssl_read_buf(ssl, buf)) return 0;
	return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
}
示例#5
0
/** load an RR into rrset */
static int
load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
	struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
	unsigned int i, int is_rrsig, int* go_on, uint32_t now)
{
	ldns_rr* rr;
	ldns_status status;

	/* read the line */
	if(!ssl_read_buf(ssl, buf))
		return 0;
	if(strncmp((char*)ldns_buffer_begin(buf), "BADRR\n", 6) == 0) {
		*go_on = 0;
		return 1;
	}
	status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf),
		LDNS_DEFAULT_TTL, NULL, NULL);
	if(status != LDNS_STATUS_OK) {
		log_warn("error cannot parse rr: %s: %s",
			ldns_get_errorstr_by_id(status),
			(char*)ldns_buffer_begin(buf));
		return 0;
	}
	if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
		log_warn("error expected rrsig but got %s",
			(char*)ldns_buffer_begin(buf));
		return 0;
	}

	/* convert ldns rr into packed_rr */
	d->rr_ttl[i] = ldns_rr_ttl(rr) + now;
	ldns_buffer_clear(buf);
	ldns_buffer_skip(buf, 2);
	status = ldns_rr_rdata2buffer_wire(buf, rr);
	if(status != LDNS_STATUS_OK) {
		log_warn("error cannot rr2wire: %s",
			ldns_get_errorstr_by_id(status));
		ldns_rr_free(rr);
		return 0;
	}
	ldns_buffer_flip(buf);
	ldns_buffer_write_u16_at(buf, 0, ldns_buffer_limit(buf) - 2);

	d->rr_len[i] = ldns_buffer_limit(buf);
	d->rr_data[i] = (uint8_t*)regional_alloc_init(region, 
		ldns_buffer_begin(buf), ldns_buffer_limit(buf));
	if(!d->rr_data[i]) {
		ldns_rr_free(rr);
		log_warn("error out of memory");
		return 0;
	}

	/* if first entry, fill the key structure */
	if(i==0) {
		rk->rk.type = htons(ldns_rr_get_type(rr));
		rk->rk.rrset_class = htons(ldns_rr_get_class(rr));
		ldns_buffer_clear(buf);
		status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
		if(status != LDNS_STATUS_OK) {
			log_warn("error cannot dname2buffer: %s",
				ldns_get_errorstr_by_id(status));
			ldns_rr_free(rr);
			return 0;
		}
		ldns_buffer_flip(buf);
		rk->rk.dname_len = ldns_buffer_limit(buf);
		rk->rk.dname = regional_alloc_init(region, 
			ldns_buffer_begin(buf), ldns_buffer_limit(buf));
		if(!rk->rk.dname) {
			log_warn("error out of memory");
			ldns_rr_free(rr);
			return 0;
		}
	}
	ldns_rr_free(rr);

	return 1;
}