Ejemplo n.º 1
0
static int rrl_clsname(char *dst, size_t maxlen, uint8_t cls,
                       rrl_req_t *req, const zone_t *zone)
{
    /* Fallback zone (for errors etc.) */
    const knot_dname_t *dn = (const knot_dname_t*)"\x00";

    /* Found associated zone. */
    if (zone != NULL) {
        dn = zone->name;
    }

    switch (cls) {
    case CLS_ERROR:    /* Could be a non-existent zone or garbage. */
    case CLS_NXDOMAIN: /* Queries to non-existent names in zone. */
    case CLS_WILDCARD: /* Queries to names covered by a wildcard. */
        dbg_rrl_verb("%s: using zone/fallback name\n", __func__);
        break;
    default:
        /* Use QNAME */
        if (req->query)
            dn = knot_pkt_qname(req->query);
        break;
    }

    /* Write to wire */
    return knot_dname_to_wire((uint8_t *)dst, dn, maxlen);
}
Ejemplo n.º 2
0
/**
 * Name error response check (RFC4035 3.1.3.2; RFC4035 5.4, bullet 2).
 * @note Returned flags must be checked in order to prove denial.
 * @param flags Flags to be set according to check outcome.
 * @param nsec  NSEC RR.
 * @param name  Name to be checked.
 * @param pool
 * @return      0 or error code.
 */
static int name_error_response_check_rr(int *flags, const knot_rrset_t *nsec,
                                        const knot_dname_t *name)
{
	assert(flags && nsec && name);

	if (nsec_nonamematch(nsec, name) == 0) {
		*flags |= FLG_NOEXIST_RRSET;
	}

	/* Try to find parent wildcard that is proved by this NSEC. */ 
	uint8_t namebuf[KNOT_DNAME_MAXLEN];
	int ret = knot_dname_to_wire(namebuf, name, sizeof(namebuf));
	if (ret < 0)
		return ret;
	knot_dname_t *ptr = namebuf;
	while (ptr[0]) {
		/* Remove leftmost label and replace it with '\1*'. */
		ptr = (uint8_t *) knot_wire_next_label(ptr, NULL);
		*(--ptr) = '*';
		*(--ptr) = 1;
		/* True if this wildcard provably doesn't exist. */
		if (nsec_nonamematch(nsec, ptr) == 0) {
			*flags |= FLG_NOEXIST_WILDCARD;
			break;
		}
		/* Remove added leftmost asterisk. */
		ptr += 2;
	}

	return kr_ok();
}
Ejemplo n.º 3
0
/*----------------------------------------------------------------------------*/
_public_
knot_dname_t *knot_dname_copy_part(const knot_dname_t *name, unsigned len,
                                   mm_ctx_t *mm)
{
	if (name == NULL || len == 0)
		return NULL;

	knot_dname_t *dst = mm_alloc(mm, len);
	if (knot_dname_to_wire(dst, name, len) < 1) {
		free(dst);
		return NULL;
	}

	return dst;
}
Ejemplo n.º 4
0
_public_
int knot_pkt_put_question(knot_pkt_t *pkt, const knot_dname_t *qname, uint16_t qclass, uint16_t qtype)
{
	if (pkt == NULL || qname == NULL) {
		return KNOT_EINVAL;
	}

	assert(pkt->size == KNOT_WIRE_HEADER_SIZE);
	assert(pkt->rrset_count == 0);

	/* Copy name wireformat. */
	uint8_t *dst = pkt->wire + KNOT_WIRE_HEADER_SIZE;
	int qname_len = knot_dname_to_wire(dst, qname, pkt->max_size - pkt->size);
	if (qname_len < 0) {
		return qname_len;
	}

	/* Check size limits. */
	size_t question_len = 2 * sizeof(uint16_t) + qname_len;
	if (qname_len < 0 || pkt->size + question_len > pkt->max_size) {
		return KNOT_ESPACE;
	}

	/* Copy QTYPE & QCLASS */
	dst += qname_len;
	wire_write_u16(dst, qtype);
	dst += sizeof(uint16_t);
	wire_write_u16(dst, qclass);

	/* Update question count and sizes. */
	knot_wire_set_qdcount(pkt->wire, 1);
	pkt->size += question_len;
	pkt->qname_size = qname_len;

	/* Start writing ANSWER. */
	return knot_pkt_begin(pkt, KNOT_ANSWER);
}
Ejemplo n.º 5
0
static int knot_tsig_write_tsig_variables(uint8_t *wire,
                                          const knot_rrset_t *tsig_rr)
{
	if (wire == NULL || tsig_rr == NULL) {
		dbg_tsig("TSIG: write tsig variables: NULL arguments.\n");
		return KNOT_EINVAL;
	}

	/* Copy TSIG variables - starting with key name. */
	const knot_dname_t *tsig_owner = tsig_rr->owner;
	if (!tsig_owner) {
		dbg_tsig("TSIG: write variables: no owner.\n");
		return KNOT_EINVAL;
	}

	int offset = 0;

	offset += knot_dname_to_wire(wire + offset, tsig_owner, KNOT_DNAME_MAXLEN);

	/*!< \todo which order? */

	/* Copy class. */
	knot_wire_write_u16(wire + offset, tsig_rr->rclass);
	dbg_tsig_verb("TSIG: write variables: written CLASS: %u - \n",
	               tsig_rr->rclass);
	dbg_tsig_hex_detail((char *)(wire + offset), sizeof(uint16_t));
	offset += sizeof(uint16_t);

	/* Copy TTL - always 0. */
	knot_wire_write_u32(wire + offset, knot_rrset_rr_ttl(tsig_rr, 0));
	dbg_tsig_verb("TSIG: write variables: written TTL: %u - \n",
	              knot_rrset_rr_ttl(tsig_rr, 0));
	dbg_tsig_hex_detail((char *)(wire + offset), sizeof(uint32_t));
	offset += sizeof(uint32_t);

	/* Copy alg name. */
	const knot_dname_t *alg_name = tsig_rdata_alg_name(tsig_rr);
	if (!alg_name) {
		dbg_tsig("TSIG: write variables: no algorithm name.\n");
		return KNOT_EINVAL;
	}

	/* Te algorithm name must be in canonical form, i.e. in lowercase. */
	uint8_t *alg_name_wire = wire + offset;
	offset += knot_dname_to_wire(alg_name_wire, alg_name, KNOT_DNAME_MAXLEN);
	if (knot_dname_to_lower(alg_name_wire) != KNOT_EOK) {
		dbg_tsig("TSIG: write variables: cannot convert algorithm "
		         "to lowercase.\n");
		return KNOT_EINVAL;
	}

	/* Following data are written in network order. */
	/* Time signed. */
	knot_wire_write_u48(wire + offset, tsig_rdata_time_signed(tsig_rr));
	offset += 6;
	dbg_tsig_verb("TSIG: write variables: time signed: %"PRIu64" \n",
	              tsig_rdata_time_signed(tsig_rr));
	dbg_tsig_hex_detail((char *)(wire + offset - 6), 6);
	/* Fudge. */
	knot_wire_write_u16(wire + offset, tsig_rdata_fudge(tsig_rr));
	offset += sizeof(uint16_t);
	dbg_tsig_verb("TSIG: write variables: fudge: %hu\n",
	              tsig_rdata_fudge(tsig_rr));
	/* TSIG error. */
	knot_wire_write_u16(wire + offset, tsig_rdata_error(tsig_rr));
	offset += sizeof(uint16_t);
	/* Get other data length. */
	uint16_t other_data_length = tsig_rdata_other_data_length(tsig_rr);
	/* Get other data. */
	const uint8_t *other_data = tsig_rdata_other_data(tsig_rr);
	if (!other_data) {
		dbg_tsig("TSIG: write variables: no other data.\n");
		return KNOT_EINVAL;
	}

	/*
	 * We cannot write the whole other_data, as it contains its length in
	 * machine order.
	 */
	knot_wire_write_u16(wire + offset, other_data_length);
	offset += sizeof(uint16_t);

	/* Skip the length. */
	dbg_tsig_verb("Copying other data.\n");
	memcpy(wire + offset, other_data, other_data_length);

	return KNOT_EOK;
}