Esempio n. 1
0
File: edns.c Progetto: dnstap/knot
int knot_edns_add_option(knot_opt_rr_t *opt_rr, uint16_t code,
                           uint16_t length, const uint8_t *data)
{
	if (opt_rr == NULL) {
		return KNOT_EINVAL;
	}

	if (opt_rr->option_count == opt_rr->options_max) {
		knot_opt_option_t *options_new =
			(knot_opt_option_t *)calloc(
				(opt_rr->options_max + KNOT_EDNS_OPTION_STEP),
				sizeof(knot_opt_option_t));
		CHECK_ALLOC_LOG(options_new, KNOT_ENOMEM);
		memcpy(options_new, opt_rr->options,
		       opt_rr->option_count * sizeof(knot_opt_option_t));

		knot_opt_option_t *old_options = opt_rr->options;
		opt_rr->options = options_new;
		opt_rr->options_max += KNOT_EDNS_OPTION_STEP;
		free(old_options);
	}

	dbg_edns_verb("Adding option.\n");
	dbg_edns_verb("Code: %u.\n", code);
	dbg_edns_verb("Length: %u.\n", length);
	dbg_edns_verb("Data: %p.\n", data);

	opt_rr->options[opt_rr->option_count].data = (uint8_t *)malloc(length);
	CHECK_ALLOC_LOG(opt_rr->options[opt_rr->option_count].data, KNOT_ENOMEM);
	memcpy(opt_rr->options[opt_rr->option_count].data, data, length);

	opt_rr->options[opt_rr->option_count].code = code;
	opt_rr->options[opt_rr->option_count].length = length;

	++opt_rr->option_count;
	opt_rr->size += 4 + length;

	return KNOT_EOK;
}
Esempio n. 2
0
File: edns.c Progetto: dnstap/knot
knot_opt_rr_t *knot_edns_new()
{
	knot_opt_rr_t *opt_rr = (knot_opt_rr_t *)malloc(sizeof(knot_opt_rr_t));
	CHECK_ALLOC_LOG(opt_rr, NULL);
	memset(opt_rr, 0, sizeof(knot_opt_rr_t));
	opt_rr->size = EDNS_MIN_SIZE;
	opt_rr->option_count = 0;
	opt_rr->options_max = 0;

	opt_rr->ext_rcode = 0;
	opt_rr->flags = 0;
	opt_rr->version = 0;

	return opt_rr;
}
Esempio n. 3
0
int notify_create_response(knot_packet_t *request, uint8_t *buffer,
                           size_t *size)
{
	knot_packet_t *response =
		knot_packet_new(KNOT_PACKET_PREALLOC_QUERY);
	CHECK_ALLOC_LOG(response, KNOT_ENOMEM);

	/* Set maximum packet size. */
	int rc = knot_packet_set_max_size(response, *size);
	if (rc == KNOT_EOK) {
		rc = knot_response_init_from_query(response, request, 1);
	}

	/* Aggregated result check. */
	if (rc != KNOT_EOK) {
		dbg_notify("%s: failed to init response packet: %s",
			   "notify_create_response", knot_strerror(rc));
		knot_packet_free(&response);
		return KNOT_EINVAL;
	}

	// TODO: copy the SOA in Answer section
	uint8_t *wire = NULL;
	size_t wire_size = 0;
	rc = knot_packet_to_wire(response, &wire, &wire_size);
	if (rc != KNOT_EOK) {
		knot_packet_free(&response);
		return rc;
	}

	if (wire_size > *size) {
		knot_packet_free(&response);
		return KNOT_ESPACE;
	}

	memcpy(buffer, wire, wire_size);
	*size = wire_size;

	knot_packet_dump(response);
	knot_packet_free(&response);

	return KNOT_EOK;
}
Esempio n. 4
0
static int notify_request(const knot_rrset_t *rrset,
                          uint8_t *buffer, size_t *size)
{
	knot_packet_t *pkt = knot_packet_new(KNOT_PACKET_PREALLOC_QUERY);
	CHECK_ALLOC_LOG(pkt, KNOT_ENOMEM);

	/*! \todo Get rid of the numeric constant. */
	int rc = knot_packet_set_max_size(pkt, 512);
	if (rc != KNOT_EOK) {
		knot_packet_free(&pkt);
		return KNOT_ERROR;
	}

	rc = knot_query_init(pkt);
	if (rc != KNOT_EOK) {
		knot_packet_free(&pkt);
		return KNOT_ERROR;
	}

	knot_question_t question;

	// this is ugly!!
	question.qname = rrset->owner;
	question.qtype = rrset->type;
	question.qclass = rrset->rclass;

	rc = knot_query_set_question(pkt, &question);
	if (rc != KNOT_EOK) {
		knot_packet_free(&pkt);
		return KNOT_ERROR;
	}

	/* Set random query ID. */
	knot_packet_set_random_id(pkt);
	knot_wire_set_id(pkt->wireformat, pkt->header.id);

	/*! \todo add the SOA RR to the Answer section as a hint */
	/*! \todo this should not use response API!! */
//	rc = knot_response_add_rrset_answer(pkt, rrset, 0, 0, 0);
//	if (rc != KNOT_EOK) {
//		knot_packet_free(&pkt);
//		return rc;
//	}

	/*! \todo this should not use response API!! */
	knot_response_set_aa(pkt);

	knot_query_set_opcode(pkt, KNOT_OPCODE_NOTIFY);

	/*! \todo OPT RR ?? */

	uint8_t *wire = NULL;
	size_t wire_size = 0;
	rc = knot_packet_to_wire(pkt, &wire, &wire_size);
	if (rc != KNOT_EOK) {
		knot_packet_free(&pkt);
		return KNOT_ERROR;
	}

	if (wire_size > *size) {
		knot_packet_free(&pkt);
		return KNOT_ESPACE;
	}

	memcpy(buffer, wire, wire_size);
	*size = wire_size;

	knot_packet_dump(pkt);

	knot_packet_free(&pkt);

	return KNOT_EOK;
}