/** match edns sections */
static int
match_edns(ldns_pkt* q, ldns_pkt* p)
{
	if(ldns_pkt_edns_udp_size(q) != ldns_pkt_edns_udp_size(p))
		return 0;
	if(ldns_pkt_edns_extended_rcode(q) != ldns_pkt_edns_extended_rcode(p))
		return 0;
	if(ldns_pkt_edns_version(q) != ldns_pkt_edns_version(p))
		return 0;
	if(ldns_pkt_edns_do(q) != ldns_pkt_edns_do(p))
		return 0;
	if(ldns_pkt_edns_z(q) != ldns_pkt_edns_z(p))
		return 0;
	if(ldns_rdf_compare(ldns_pkt_edns_data(q), ldns_pkt_edns_data(p)) != 0)
		return 0;
	return 1;
}
示例#2
0
void truncation_check(evldns_server_request *srq)
{
	ldns_pkt *req = srq->request;
	ldns_pkt *resp = srq->response;
	unsigned int bufsize = 512;

	/* if it's TCP, business as usual */
	if (srq->is_tcp) {
		return;
	}

	/* otherwise, convert to wire format, if necessary */
	if (!srq->wire_response) {
		(void) ldns_pkt2wire(&srq->wire_response, resp, &srq->wire_resplen);
	}

	/* if it's under the RFC 1035 limit, we're OK */
	if (srq->wire_resplen <= bufsize) {
		return;
	}

	/* if the client used EDNS, use that new bufsize */
	if (ldns_pkt_edns(req)) {
		unsigned int ednssize = ldns_pkt_edns_udp_size(req);
		if (ednssize > bufsize) {
			bufsize = ednssize;
		}

		/* it fits - we're OK */
		if (srq->wire_resplen <= bufsize) {
			return;
		}
	}

	/*
	 * if we got here, it didn't fit - throw away the
	 * existing wire buffer and the non-question sections
	 */
	free(srq->wire_response);
	LDNS_rr_list_empty_rr_list(ldns_pkt_additional(resp));
	LDNS_rr_list_empty_rr_list(ldns_pkt_authority(resp));
	LDNS_rr_list_empty_rr_list(ldns_pkt_answer(resp));

	/* set the TC bit and reset section counts */
	ldns_pkt_set_tc(resp, true);
	ldns_pkt_set_ancount(resp, 0);
	ldns_pkt_set_nscount(resp, 0);
	ldns_pkt_set_arcount(resp, 0);

	/* and convert to wire format again */
	(void) ldns_pkt2wire(&srq->wire_response, resp, &srq->wire_resplen);
}
示例#3
0
ldns_status
ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, 
				   ldns_pkt *query_pkt)
{
	ldns_pkt *answer_pkt = NULL;
	ldns_status stat = LDNS_STATUS_OK;

	stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
	if (stat != LDNS_STATUS_OK) {
		if(answer_pkt) {
			ldns_pkt_free(answer_pkt);
			answer_pkt = NULL;
		}
	} else {
	
		/* if tc=1 fall back to EDNS and/or TCP */
		/* check for tcp first (otherwise we don't care about tc=1) */
		if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
			if (ldns_pkt_tc(answer_pkt)) {
				/* was EDNS0 set? */
				if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
					ldns_pkt_set_edns_udp_size(query_pkt, 4096);
					ldns_pkt_free(answer_pkt);
					stat = ldns_send(&answer_pkt, r, query_pkt);
				}
				/* either way, if it is still truncated, use TCP */
				if (stat != LDNS_STATUS_OK ||
				    ldns_pkt_tc(answer_pkt)) {
					ldns_resolver_set_usevc(r, true);
					ldns_pkt_free(answer_pkt);
					stat = ldns_send(&answer_pkt, r, query_pkt);
					ldns_resolver_set_usevc(r, false);
				}
			}
		}
	}


	if (answer) {
		*answer = answer_pkt;
	}

	return stat;
}
示例#4
0
文件: host2wire.c 项目: LANJr4D/iEnum
ldns_status
ldns_pkt2buffer_wire(ldns_buffer *buffer, const ldns_pkt *packet)
{
	ldns_rr_list *rr_list;
	uint16_t i;
	
	/* edns tmp vars */
	ldns_rr *edns_rr;
	uint8_t edata[4];
	
	(void) ldns_hdr2buffer_wire(buffer, packet);

	rr_list = ldns_pkt_question(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_QUESTION);
		}
	}
	rr_list = ldns_pkt_answer(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ANSWER);
		}
	}
	rr_list = ldns_pkt_authority(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_AUTHORITY);
		}
	}
	rr_list = ldns_pkt_additional(packet);
	if (rr_list) {
		for (i = 0; i < ldns_rr_list_rr_count(rr_list); i++) {
			(void) ldns_rr2buffer_wire(buffer, 
			             ldns_rr_list_rr(rr_list, i), LDNS_SECTION_ADDITIONAL);
		}
	}
	
	/* add EDNS to additional if it is needed */
	if (ldns_pkt_edns(packet)) {
		edns_rr = ldns_rr_new();
		ldns_rr_set_owner(edns_rr,
				ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, "."));
		ldns_rr_set_type(edns_rr, LDNS_RR_TYPE_OPT);
		ldns_rr_set_class(edns_rr, ldns_pkt_edns_udp_size(packet));
		edata[0] = ldns_pkt_edns_extended_rcode(packet);
		edata[1] = ldns_pkt_edns_version(packet);
		ldns_write_uint16(&edata[2], ldns_pkt_edns_z(packet));
		ldns_rr_set_ttl(edns_rr, ldns_read_uint32(edata));
		(void)ldns_rr2buffer_wire(buffer, edns_rr, LDNS_SECTION_ADDITIONAL);
		ldns_rr_free(edns_rr);
	}
	
	/* add TSIG to additional if it is there */
	if (ldns_pkt_tsig(packet)) {
		(void) ldns_rr2buffer_wire(buffer,
		                           ldns_pkt_tsig(packet), LDNS_SECTION_ADDITIONAL);
	}
	
	return LDNS_STATUS_OK;
}